go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/buildbucket/cmd/bbagent/util/dump_bbagent_arg/main.go (about)

     1  // Copyright 2020 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"os"
    21  	"os/signal"
    22  	"text/template"
    23  	"time"
    24  
    25  	"github.com/golang/protobuf/jsonpb"
    26  
    27  	"go.chromium.org/luci/buildbucket/cmd/bbagent/bbinput"
    28  )
    29  
    30  // the disappointed emoji `{{- "" -}}` removes whitespace before "usage:"
    31  var helpTemplate = template.Must(template.New("").Parse(`{{- "" -}}
    32  usage:
    33  	{{.Prog}} <<<"raw argument to bbagent"
    34  	{{.Prog}} "raw argument to bbagent"
    35  	{{.Prog}} help
    36  
    37  Decodes and prints the BBAgentArgs message from the raw input to bbagent.
    38  
    39  Useful for debugging swarming tasks which use bbagent in order to see what
    40  buildbucket passed as the input message.
    41  `))
    42  
    43  func help() {
    44  	helpTemplate.Execute(os.Stdout, map[string]string{
    45  		"Prog": os.Args[0],
    46  	})
    47  	os.Exit(0)
    48  }
    49  
    50  func main() {
    51  	var raw string
    52  
    53  	interrupt := make(chan os.Signal, 1)
    54  	go func() {
    55  		<-interrupt
    56  		help()
    57  	}()
    58  	signal.Notify(interrupt, os.Interrupt)
    59  
    60  	switch {
    61  	case len(os.Args) == 1:
    62  		done := make(chan struct{})
    63  		var data []byte
    64  		go func() {
    65  			defer close(done)
    66  			var err error
    67  			data, err = io.ReadAll(os.Stdin)
    68  			if err != nil {
    69  				panic(err)
    70  			}
    71  		}()
    72  		select {
    73  		case <-done:
    74  		case <-time.After(time.Second):
    75  			fmt.Fprintf(os.Stderr, "waiting for bbagent string on stdin...\n")
    76  			<-done
    77  		}
    78  		raw = string(data)
    79  		if len(raw) == 0 {
    80  			help()
    81  		}
    82  
    83  	case len(os.Args) == 2:
    84  		arg := os.Args[1]
    85  		switch arg {
    86  		case "-h", "--help", "help":
    87  			help()
    88  		default:
    89  			raw = arg
    90  		}
    91  
    92  	default:
    93  		help()
    94  	}
    95  
    96  	bbargs, err := bbinput.Parse(raw)
    97  	if err != nil {
    98  		fmt.Fprintf(os.Stderr, "failed to parse: %s", err)
    99  		os.Exit(1)
   100  	}
   101  	err = (&jsonpb.Marshaler{OrigName: true, Indent: "  "}).Marshal(os.Stdout, bbargs)
   102  	if err != nil {
   103  		fmt.Fprintf(os.Stderr, "failed to emit: %s", err)
   104  		os.Exit(1)
   105  	}
   106  }