golang.org/x/build@v0.0.0-20240506185731-218518f32b70/maintner/maintq/maintq.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // The maintq command queries a maintnerd gRPC server.
     6  // This tool is mostly for debugging.
     7  package main
     8  
     9  import (
    10  	"context"
    11  	"crypto/tls"
    12  	"errors"
    13  	"flag"
    14  	"fmt"
    15  	"log"
    16  	"os"
    17  	"sort"
    18  	"strings"
    19  	"time"
    20  
    21  	"github.com/golang/protobuf/proto"
    22  	"golang.org/x/build/maintner/maintnerd/apipb"
    23  	"google.golang.org/grpc"
    24  	"google.golang.org/grpc/credentials"
    25  )
    26  
    27  var (
    28  	server = flag.String("server", "maintner.golang.org:443", "maintnerd server")
    29  )
    30  
    31  var (
    32  	mc  apipb.MaintnerServiceClient
    33  	ctx = context.Background()
    34  )
    35  
    36  func main() {
    37  	flag.Parse()
    38  
    39  	c := credentials.NewTLS(&tls.Config{
    40  		NextProtos:         []string{"h2"},
    41  		InsecureSkipVerify: strings.HasPrefix(*server, "localhost:"),
    42  	})
    43  	opts := []grpc.DialOption{
    44  		grpc.WithDisableRetry(),
    45  		grpc.WithBlock(),
    46  		grpc.WithTimeout(5 * time.Second),
    47  		grpc.WithTransportCredentials(c),
    48  	}
    49  
    50  	cc, err := grpc.Dial(*server, opts...)
    51  	if err != nil {
    52  		log.Fatalf("unable to grpc.Dial(%q) = %s", *server, err)
    53  	}
    54  	mc = apipb.NewMaintnerServiceClient(cc)
    55  
    56  	cmdFunc := map[string]func(args []string) error{
    57  		"has-ancestor":  callHasAncestor,
    58  		"get-ref":       callGetRef,
    59  		"try-work":      callTryWork,
    60  		"list-releases": callListReleases,
    61  		"get-dashboard": callGetDashboard,
    62  	}
    63  	log.SetFlags(0)
    64  	if flag.NArg() == 0 || cmdFunc[flag.Arg(0)] == nil {
    65  		var cmds []string
    66  		for cmd := range cmdFunc {
    67  			cmds = append(cmds, cmd)
    68  		}
    69  		sort.Strings(cmds)
    70  		log.Fatalf(`Usage: maintq %v ...`, cmds)
    71  	}
    72  	if err := cmdFunc[flag.Arg(0)](flag.Args()[1:]); err != nil {
    73  		log.Fatal(err)
    74  	}
    75  }
    76  
    77  func callHasAncestor(args []string) error {
    78  	if len(args) != 2 {
    79  		return errors.New("Usage: maintq has-ancestor <commit> <ancestor>")
    80  	}
    81  	res, err := mc.HasAncestor(ctx, &apipb.HasAncestorRequest{
    82  		Commit:   args[0],
    83  		Ancestor: args[1],
    84  	})
    85  	if err != nil {
    86  		return err
    87  	}
    88  	fmt.Println(res)
    89  	return nil
    90  }
    91  
    92  func callGetRef(args []string) error {
    93  	if len(args) != 2 {
    94  		return errors.New("Usage: maintq get-ref <project> <ref>")
    95  	}
    96  	res, err := mc.GetRef(ctx, &apipb.GetRefRequest{
    97  		GerritServer:  "go.googlesource.com",
    98  		GerritProject: args[0],
    99  		Ref:           args[1],
   100  	})
   101  	if err != nil {
   102  		return err
   103  	}
   104  	if res.Value == "" {
   105  		return errors.New("ref not found")
   106  	}
   107  	fmt.Println(res.Value)
   108  	return nil
   109  }
   110  
   111  func callTryWork(args []string) error {
   112  	staging := len(args) == 1 && args[0] == "staging"
   113  	if !staging && len(args) > 0 {
   114  		return errors.New(`Usage: maintq try-work ["staging"]  # prod is default`)
   115  	}
   116  	res, err := mc.GoFindTryWork(ctx, &apipb.GoFindTryWorkRequest{ForStaging: staging})
   117  	if err != nil {
   118  		return err
   119  	}
   120  	return printTextProto(res)
   121  }
   122  
   123  func callListReleases(args []string) error {
   124  	if len(args) != 0 {
   125  		return errors.New("Usage: maintq list-releases")
   126  	}
   127  	res, err := mc.ListGoReleases(ctx, &apipb.ListGoReleasesRequest{})
   128  	if err != nil {
   129  		return err
   130  	}
   131  	return printTextProto(res)
   132  }
   133  
   134  func callGetDashboard(args []string) error {
   135  	req := &apipb.DashboardRequest{}
   136  
   137  	fs := flag.NewFlagSet("get-dash-commits", flag.ExitOnError)
   138  	var page int
   139  	fs.IntVar(&page, "page", 0, "0-based page number")
   140  	fs.StringVar(&req.Branch, "branch", "", "branch name; empty means master")
   141  	fs.StringVar(&req.Repo, "repo", "", "repo name; empty means the main repo, otherwise \"golang.org/*\"")
   142  	fs.Parse(args)
   143  	if fs.NArg() != 0 {
   144  		fs.Usage()
   145  		os.Exit(2)
   146  	}
   147  
   148  	req.Page = int32(page)
   149  
   150  	res, err := mc.GetDashboard(ctx, req)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	return printTextProto(res)
   155  }
   156  
   157  func printTextProto(m proto.Message) error {
   158  	tm := proto.TextMarshaler{Compact: false}
   159  	return tm.Marshal(os.Stdout, m)
   160  }