| // Copyright 2022 The Fuchsia Authors. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package sizes |
| |
| import ( |
| "fmt" |
| "strings" |
| ) |
| |
| // BinarySizes maps component names to ComponentMetadata. |
| type BinarySizes map[string]*ComponentMetadata |
| |
| // ComponentMetadata contains size and size budget metadata for a single |
| // component. |
| type ComponentMetadata struct { |
| // Size of the component in bytes. |
| Size int64 |
| |
| // Budget of the component in bytes. |
| Budget int64 |
| |
| // Creep budget of the component in bytes. |
| CreepBudget int64 |
| } |
| |
| // Parse parses a raw binary_sizes map from JSON to a structured BinarySizes |
| // object. Byte values are casted from float64 to int64, and ".owner" keys are |
| // removed as they are not meaningful to our tools. |
| // |
| // The binary_sizes schema is defined in |
| // https://chromium.googlesource.com/infra/gerrit-plugins/binary-size/+/HEAD/README.md. |
| func Parse(raw map[string]any) (BinarySizes, error) { |
| casted := make(map[string]int64) |
| for k, v := range raw { |
| if strings.HasSuffix(k, ".owner") { |
| continue |
| } |
| val, ok := v.(float64) |
| if !ok { |
| return nil, fmt.Errorf("got value of type %T but expected float64", v) |
| } |
| casted[k] = int64(val) |
| } |
| |
| parsed := make(BinarySizes) |
| outerLoop: |
| for k, v := range casted { |
| // The binary_sizes component metadata is denoted by well-known |
| // suffixes. We want to group by components only, not metadata, so |
| // filter out any entries with the well-known suffixes. |
| for _, suffix := range []string{".budget", ".creepBudget"} { |
| if strings.HasSuffix(k, suffix) { |
| continue outerLoop |
| } |
| } |
| component := k |
| size := v |
| |
| // Resolve budget and creep budget metadata. |
| budget, ok := casted[component+".budget"] |
| if !ok { |
| return nil, fmt.Errorf("%s: missing budget metadata", component) |
| } |
| creepBudget, ok := casted[component+".creepBudget"] |
| if !ok { |
| return nil, fmt.Errorf("%s: missing creep budget metadata", component) |
| } |
| parsed[component] = &ComponentMetadata{ |
| Size: size, |
| Budget: budget, |
| CreepBudget: creepBudget, |
| } |
| } |
| |
| return parsed, nil |
| } |