go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/lkg/cmd_revision.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 main 6 7 import ( 8 "context" 9 "errors" 10 "fmt" 11 12 "github.com/maruel/subcommands" 13 "go.chromium.org/luci/auth" 14 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 15 "google.golang.org/genproto/protobuf/field_mask" 16 ) 17 18 func cmdRevision(authOpts auth.Options) *subcommands.Command { 19 return &subcommands.Command{ 20 UsageLine: "revision -builder project1/bucket1/builder1, ... [common options]", 21 ShortDesc: "Get the last known good revision across a set of builders.", 22 LongDesc: "Get the last known good revision across a set of builders.", 23 CommandRun: func() subcommands.CommandRun { 24 c := &revisionRun{} 25 c.Init(authOpts) 26 return c 27 }, 28 } 29 } 30 31 type revisionRun struct { 32 commonFlags 33 builders builders 34 } 35 36 func (c *revisionRun) Init(defaultAuthOpts auth.Options) { 37 c.commonFlags.Init(defaultAuthOpts) 38 c.Flags.Var(&c.builders, "builder", "Builder ID as project/bucket/builder. Repeatable") 39 } 40 41 func (c *revisionRun) checkFlags() error { 42 if err := c.commonFlags.checkFlags(); err != nil { 43 return err 44 } 45 if len(c.builders) == 0 { 46 return errors.New("at least one -builder is required") 47 } 48 return nil 49 } 50 51 func (c *revisionRun) main(a subcommands.Application) error { 52 ctx := context.Background() 53 client, err := newBuildbucketClient(ctx, c.parsedAuthOpts, c.buildbucketHost) 54 if err != nil { 55 return fmt.Errorf("failed to initialize client: %w", err) 56 } 57 // Do not retrieve any fields additional to default input, as we only need revision. 58 mask := &field_mask.FieldMask{ 59 Paths: []string{}, 60 } 61 builds, err := client.GetBuilds(ctx, c.builders, mask, c.searchRange) 62 if err != nil { 63 return fmt.Errorf("failed to query builds: %w", err) 64 } 65 // Pass an accessorFunc which returns a build's revision. 66 revision, err := getLastKnownGood(builds, c.gitilesRef, func(build *buildbucketpb.Build) any { 67 // Skip manually triggered builds, which do not have a gitiles commit. 68 if build.Input.GitilesCommit == nil { 69 return nil 70 } 71 return build.Input.GitilesCommit.Id 72 }) 73 if err != nil { 74 return fmt.Errorf("failed to get last known good revision: %w", err) 75 } 76 fmt.Println(revision) 77 return nil 78 } 79 80 func (c *revisionRun) Run(a subcommands.Application, args []string, env subcommands.Env) int { 81 if err := c.checkFlags(); err != nil { 82 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) 83 return 1 84 } 85 86 if err := c.main(a); err != nil { 87 fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err) 88 return 1 89 } 90 return 0 91 }