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  }