go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/grpc/cmd/prpc/show.go (about) 1 // Copyright 2016 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 "context" 19 "fmt" 20 "os" 21 "strings" 22 23 "github.com/maruel/subcommands" 24 "google.golang.org/protobuf/types/descriptorpb" 25 26 "go.chromium.org/luci/auth" 27 "go.chromium.org/luci/common/cli" 28 "go.chromium.org/luci/common/proto/google/descutil" 29 "go.chromium.org/luci/common/proto/google/descutil/printer" 30 "go.chromium.org/luci/grpc/prpc" 31 ) 32 33 const ( 34 cmdShowUsage = `show [flags] <server> [name] 35 36 server: host ("example.com") or port for localhost (":8080"). 37 name: a full name of service, method or type. If not specified prints names 38 of all available services. 39 ` 40 41 cmdShowDesc = "lists services and prints a definition of a referenced object." 42 ) 43 44 func cmdShow(defaultAuthOpts auth.Options) *subcommands.Command { 45 return &subcommands.Command{ 46 UsageLine: cmdShowUsage, 47 ShortDesc: cmdShowDesc, 48 LongDesc: "Lists services and prints a definition of a referenced object.", 49 CommandRun: func() subcommands.CommandRun { 50 c := &showRun{} 51 c.registerBaseFlags(defaultAuthOpts) 52 return c 53 }, 54 } 55 } 56 57 type showRun struct { 58 cmdRun 59 } 60 61 func (r *showRun) Run(a subcommands.Application, args []string, env subcommands.Env) int { 62 var host, name string 63 switch len(args) { 64 case 2: 65 name = args[1] 66 fallthrough 67 case 1: 68 host = args[0] 69 70 default: 71 return r.argErr(cmdShowDesc, cmdShowUsage, "") 72 } 73 74 ctx := cli.GetContext(a, r, env) 75 client, err := r.authenticatedClient(ctx, host) 76 if err != nil { 77 return ecAuthenticatedClientError 78 } 79 return r.done(show(ctx, client, name)) 80 } 81 82 // show prints a definition of an object referenced by name in proto3 style. 83 func show(ctx context.Context, client *prpc.Client, name string) error { 84 desc, err := loadDescription(ctx, client) 85 if err != nil { 86 return fmt.Errorf("could not load server description: %s", err) 87 } 88 89 if name == "" { 90 for _, s := range desc.Services { 91 fmt.Println(s) 92 } 93 return nil 94 } 95 96 file, obj, path := descutil.Resolve(desc.Description, name) 97 if obj == nil { 98 return fmt.Errorf("name %q could not resolved", name) 99 } 100 101 printer := printer.NewPrinter(os.Stdout) 102 if err := printer.SetFile(file); err != nil { 103 return err 104 } 105 106 switch obj := obj.(type) { 107 108 case *descriptorpb.ServiceDescriptorProto: 109 printer.Service(obj, -1) 110 111 case *descriptorpb.MethodDescriptorProto: 112 serviceIndex, methodIndex := path[1], path[3] 113 printer.Service(file.Service[serviceIndex], methodIndex) 114 115 printMsg := func(name string) error { 116 name = strings.TrimPrefix(name, ".") 117 file, msg, _ := descutil.Resolve(desc.Description, name) 118 if msg == nil { 119 printer.Printf("// Message %q is not found\n", name) 120 return nil 121 } 122 if err := printer.SetFile(file); err != nil { 123 return err 124 } 125 printer.Message(msg.(*descriptorpb.DescriptorProto)) 126 return nil 127 } 128 129 printer.Printf("\n") 130 if err := printMsg(obj.GetInputType()); err != nil { 131 return err 132 } 133 printer.Printf("\n") 134 if err := printMsg(obj.GetOutputType()); err != nil { 135 return err 136 } 137 138 case *descriptorpb.DescriptorProto: 139 printer.Message(obj) 140 141 case *descriptorpb.FieldDescriptorProto: 142 printer.Field(obj) 143 144 case *descriptorpb.EnumDescriptorProto: 145 printer.Enum(obj) 146 147 case *descriptorpb.EnumValueDescriptorProto: 148 printer.EnumValue(obj) 149 150 default: 151 return fmt.Errorf("object of type %T is not supported", obj) 152 } 153 154 return printer.Err 155 }