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

     1  // Copyright 2020 The Fuchsia Authors. All rights reserved.
     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 props
     6  
     7  import (
     8  	"fmt"
     9  
    10  	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
    11  	"go.chromium.org/luci/luciexe/exe"
    12  	"google.golang.org/protobuf/encoding/protojson"
    13  	"google.golang.org/protobuf/proto"
    14  )
    15  
    16  // Set input property on Build.Input.Properties.
    17  func SetBuildInputProperty(build *buildbucketpb.Build, key string, value any) error {
    18  	return exe.WriteProperties(build.Input.Properties, map[string]any{
    19  		key: value,
    20  	})
    21  }
    22  
    23  // Gets string input property from Build.Input.Properties.
    24  // If property was not set, returns empty string and a nil error.
    25  func String(build *buildbucketpb.Build, key string) (string, error) {
    26  	var val string
    27  	if err := exe.ParseProperties(build.Input.Properties, map[string]any{
    28  		key: &val,
    29  	}); err != nil {
    30  		return "", fmt.Errorf("failed to read %s property: %w", key, err)
    31  	}
    32  	return val, nil
    33  }
    34  
    35  // Bool reads a boolean input property from
    36  // Build.Input.Properties. If the property is not set, returns false and a nil
    37  // error.
    38  func Bool(build *buildbucketpb.Build, key string) (bool, error) {
    39  	var val bool
    40  	if err := exe.ParseProperties(build.Input.Properties, map[string]any{
    41  		key: &val,
    42  	}); err != nil {
    43  		return false, fmt.Errorf("failed to read %s property: %w", key, err)
    44  	}
    45  	return val, nil
    46  }
    47  
    48  // Proto parses an input property whose value is encoded as
    49  // jsonpb. If the property is not set, it will return a nil error and leave the
    50  // proto message as-is.
    51  func Proto(build *buildbucketpb.Build, key string, m proto.Message) error {
    52  	// We can't use `exe.ParseProperties` because it doesn't support parsing a
    53  	// nested property into a protobuf, so we have to instead retrieve the raw
    54  	// value ourselves and deserialize it to a proto object.
    55  	val := build.Input.Properties.Fields[key]
    56  	if val == nil {
    57  		return nil
    58  	}
    59  	jsonBuf, err := protojson.Marshal(val)
    60  	if err != nil {
    61  		return err
    62  	}
    63  	if err := protojson.Unmarshal(jsonBuf, m); err != nil {
    64  		return fmt.Errorf("failed to deserialize %q property: %w", key, err)
    65  	}
    66  	return nil
    67  }