go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/size_check/sizes/sizes.go (about)

     1  // Copyright 2022 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 sizes
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  // BinarySizes maps component names to ComponentMetadata.
    13  type BinarySizes map[string]*ComponentMetadata
    14  
    15  // ComponentMetadata contains size and size budget metadata for a single
    16  // component.
    17  type ComponentMetadata struct {
    18  	// Size of the component in bytes.
    19  	Size int64
    20  
    21  	// Budget of the component in bytes.
    22  	Budget int64
    23  
    24  	// Creep budget of the component in bytes.
    25  	CreepBudget int64
    26  }
    27  
    28  // Parse parses a raw binary_sizes map from JSON to a structured BinarySizes
    29  // object. Byte values are casted from float64 to int64, and ".owner" keys are
    30  // removed as they are not meaningful to our tools.
    31  //
    32  // The binary_sizes schema is defined in
    33  // https://chromium.googlesource.com/infra/gerrit-plugins/binary-size/+/HEAD/README.md.
    34  func Parse(raw map[string]any) (BinarySizes, error) {
    35  	casted := make(map[string]int64)
    36  	for k, v := range raw {
    37  		if strings.HasSuffix(k, ".owner") {
    38  			continue
    39  		}
    40  		val, ok := v.(float64)
    41  		if !ok {
    42  			return nil, fmt.Errorf("got value of type %T but expected float64", v)
    43  		}
    44  		casted[k] = int64(val)
    45  	}
    46  
    47  	parsed := make(BinarySizes)
    48  outerLoop:
    49  	for k, v := range casted {
    50  		// The binary_sizes component metadata is denoted by well-known
    51  		// suffixes. We want to group by components only, not metadata, so
    52  		// filter out any entries with the well-known suffixes.
    53  		for _, suffix := range []string{".budget", ".creepBudget"} {
    54  			if strings.HasSuffix(k, suffix) {
    55  				continue outerLoop
    56  			}
    57  		}
    58  		component := k
    59  		size := v
    60  
    61  		// Resolve budget and creep budget metadata.
    62  		budget, ok := casted[component+".budget"]
    63  		if !ok {
    64  			return nil, fmt.Errorf("%s: missing budget metadata", component)
    65  		}
    66  		creepBudget, ok := casted[component+".creepBudget"]
    67  		if !ok {
    68  			return nil, fmt.Errorf("%s: missing creep budget metadata", component)
    69  		}
    70  		parsed[component] = &ComponentMetadata{
    71  			Size:        size,
    72  			Budget:      budget,
    73  			CreepBudget: creepBudget,
    74  		}
    75  	}
    76  
    77  	return parsed, nil
    78  }