go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/size_diff/diff/diff.go (about) 1 // Copyright 2021 The Fuchsia Authors. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package diff 6 7 import ( 8 "sort" 9 10 "go.fuchsia.dev/infra/cmd/size_check/sizes" 11 ) 12 13 // DiffBinarySizes diffs two BinarySizes objects. 14 func DiffBinarySizes(binarySizes, baselineBinarySizes sizes.BinarySizes) *Diff { 15 var cDiffs []*ComponentDiff 16 for component, metadata := range binarySizes { 17 baselineMetadata, ok := baselineBinarySizes[component] 18 if ok { 19 cDiffs = append(cDiffs, NewComponentDiff(component, baselineMetadata.Size, metadata.Size, metadata.Budget, metadata.CreepBudget, true)) 20 } else { 21 // Any components which don't have a matching baseline component are 22 // assumed to have a baseline size of 0. Also, don't enforce creep 23 // budget here: size upon initialization is likely to exceed creep, 24 // and this scenario is not considered to be an error. 25 cDiffs = append(cDiffs, NewComponentDiff(component, 0, metadata.Size, metadata.Budget, metadata.CreepBudget, false)) 26 } 27 } 28 sort.SliceStable(cDiffs, func(i, j int) bool { return cDiffs[i].Name < cDiffs[j].Name }) 29 return NewDiff(cDiffs) 30 } 31 32 // Diff is a combined diff of per-component diffs. 33 type Diff struct { 34 // The per-component diffs. 35 ComponentDiffs []*ComponentDiff `json:"component_diffs"` 36 37 // Whether one or more budgets are exceeded. 38 BudgetExceeded bool `json:"budget_exceeded"` 39 40 // Whether one or more creep budgets are exceeded. 41 CreepBudgetExceeded bool `json:"creep_budget_exceeded"` 42 43 // The baseline build ID that was used, if applicable. 44 BaselineBuildID int64 `json:"baseline_build_id,omitempty"` 45 } 46 47 // NewDiff constructs a Diff from a slice of ComponentDiffs. 48 func NewDiff(componentDiffs []*ComponentDiff) *Diff { 49 var budgetExceeded bool 50 for _, c := range componentDiffs { 51 if c.BudgetExceeded { 52 budgetExceeded = true 53 break 54 } 55 } 56 57 var creepBudgetExceeded bool 58 for _, c := range componentDiffs { 59 if c.CreepBudgetExceeded { 60 creepBudgetExceeded = true 61 break 62 } 63 } 64 65 return &Diff{ 66 ComponentDiffs: componentDiffs, 67 BudgetExceeded: budgetExceeded, 68 CreepBudgetExceeded: creepBudgetExceeded, 69 } 70 } 71 72 // ComponentDiff contains metadata of a per-component diff. 73 type ComponentDiff struct { 74 // Name of the component. 75 Name string `json:"name"` 76 77 // Baseline size of the component in bytes. 78 BaselineSize int64 `json:"baseline_size"` 79 80 // Size of the component in bytes. 81 Size int64 `json:"size"` 82 83 // Size diff in bytes. 84 SizeDiff int64 `json:"size_diff"` 85 86 // Budget of the component in bytes. 87 Budget int64 `json:"budget"` 88 89 // Creep budget of the component in bytes. 90 CreepBudget int64 `json:"creep_budget"` 91 92 // Whether the budget is exceeded. 93 BudgetExceeded bool `json:"budget_exceeded"` 94 95 // Whether the creep budget is exceeded. 96 CreepBudgetExceeded bool `json:"creep_budget_exceeded"` 97 } 98 99 // NewComponentDiff constructs a ComponentDiff. 100 func NewComponentDiff(name string, baselineSize, size, budget, creepBudget int64, enforceCreepBudget bool) *ComponentDiff { 101 creepBudgetExceeded := false 102 if enforceCreepBudget { 103 creepBudgetExceeded = size-baselineSize > creepBudget 104 } 105 return &ComponentDiff{ 106 Name: name, 107 BaselineSize: baselineSize, 108 Size: size, 109 SizeDiff: size - baselineSize, 110 Budget: budget, 111 CreepBudget: creepBudget, 112 BudgetExceeded: size > budget, 113 CreepBudgetExceeded: creepBudgetExceeded, 114 } 115 }