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 }