Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from native flags to posix flags #111

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ source or protoset files.
grpcurl localhost:8787 list

# Using compiled protoset files
grpcurl -protoset my-protos.bin list
grpcurl --protoset my-protos.bin list

# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto list
grpcurl --import-path ../protos --proto my-stuff.proto list
```

The "list" verb also lets you see all methods in a particular service:
Expand All @@ -149,10 +149,10 @@ original source that defined the element, but it will be equivalent.
grpcurl localhost:8787 describe my.custom.server.Service.MethodOne

# Using compiled protoset files
grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne
grpcurl --protoset my-protos.bin describe my.custom.server.Service.MethodOne

# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne
grpcurl --import-path ../protos --proto my-stuff.proto describe my.custom.server.Service.MethodOne
```

## Descriptor Sources
Expand All @@ -176,8 +176,8 @@ and ask it for its descriptors.
To use `grpcurl` on servers that do not support reflection, you can use `.proto` source
files.

In addition to using `-proto` flags to point `grpcurl` at the relevant proto source file(s),
you may also need to supply `-import-path` flags to tell `grpcurl` the folders from which
In addition to using `--proto` flags to point `grpcurl` at the relevant proto source file(s),
you may also need to supply `--import-path` flags to tell `grpcurl` the folders from which
dependencies can be imported.

Just like when compiling with `protoc`, you do *not* need to provide an import path for the
Expand Down
77 changes: 41 additions & 36 deletions cmd/grpcurl/grpcurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
package main

import (
"flag"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"

flag "github.com/spf13/pflag"

"github.com/fullstorydev/grpcurl"
descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/jhump/protoreflect/desc"
Expand All @@ -34,24 +35,24 @@ var (

flags = flag.NewFlagSet(os.Args[0], flag.ExitOnError)

help = flags.Bool("help", false, prettify(`
help = flags.BoolP("help", "h", false, prettify(`
Print usage instructions and exit.`))
printVersion = flags.Bool("version", false, prettify(`
Print version.`))
plaintext = flags.Bool("plaintext", false, prettify(`
Use plain-text HTTP/2 when connecting to server (no TLS).`))
insecure = flags.Bool("insecure", false, prettify(`
insecure = flags.BoolP("insecure", "k", false, prettify(`
Skip server certificate and domain verification. (NOT SECURE!) Not
valid with -plaintext option.`))
valid with --plaintext option.`))
cacert = flags.String("cacert", "", prettify(`
File containing trusted root certificates for verifying the server.
Ignored if -insecure is specified.`))
cert = flags.String("cert", "", prettify(`
Ignored if --insecure is specified.`))
cert = flags.StringP("cert", "E", "", prettify(`
File containing client certificate (public key), to present to the
server. Not valid with -plaintext option. Must also provide -key option.`))
server. Not valid with --plaintext option. Must also provide --key option.`))
key = flags.String("key", "", prettify(`
File containing client private key, to present to the server. Not valid
with -plaintext option. Must also provide -cert option.`))
with --plaintext option. Must also provide --cert option.`))
protoset multiString
protoFiles multiString
importPaths multiString
Expand All @@ -61,11 +62,11 @@ var (
authority = flags.String("authority", "", prettify(`
Value of :authority pseudo-header to be use with underlying HTTP/2
requests. It defaults to the given address.`))
data = flags.String("d", "", prettify(`
data = flags.StringP("data", "d", "", prettify(`
Data for request contents. If the value is '@' then the request contents
are read from stdin. For calls that accept a stream of requests, the
contents should include all such request messages concatenated together
(possibly delimited; see -format).`))
(possibly delimited; see --format).`))
format = flags.String("format", "json", prettify(`
The format of request data. The allowed values are 'json' or 'text'. For
'json', the input data must be in JSON format. Multiple request values
Expand Down Expand Up @@ -95,14 +96,14 @@ var (
Emit default values for JSON-encoded responses.`))
msgTemplate = flags.Bool("msg-template", false, prettify(`
When describing messages, show a template of input data.`))
verbose = flags.Bool("v", false, prettify(`
verbose = flags.BoolP("verbose", "v", false, prettify(`
Enable verbose output.`))
serverName = flags.String("servername", "", prettify(`
Override server name when validating TLS certificate.`))
)

func init() {
flags.Var(&addlHeaders, "H", prettify(`
flags.VarP(&addlHeaders, "headers", "H", prettify(`
Additional headers in 'name: value' format. May specify more than one
via multiple flags. These headers will also be included in reflection
requests requests to a server.`))
Expand All @@ -122,24 +123,24 @@ func init() {
'list' action lists the services found in the given descriptors (vs.
those exposed by the remote server), and the 'describe' action describes
symbols found in the given descriptors. May specify more than one via
multiple -protoset flags. It is an error to use both -protoset and
-proto flags.`))
multiple --protoset flags. It is an error to use both --protoset and
--proto flags.`))
flags.Var(&protoFiles, "proto", prettify(`
The name of a proto source file. Source files given will be used to
determine the RPC schema instead of querying for it from the remote
server via the gRPC reflection API. When set: the 'list' action lists
the services found in the given files and their imports (vs. those
exposed by the remote server), and the 'describe' action describes
symbols found in the given files. May specify more than one via multiple
-proto flags. Imports will be resolved using the given -import-path
--proto flags. Imports will be resolved using the given --import-path
flags. Multiple proto files can be specified by specifying multiple
-proto flags. It is an error to use both -protoset and -proto flags.`))
--proto flags. It is an error to use both --protoset and --proto flags.`))
flags.Var(&importPaths, "import-path", prettify(`
The path to a directory from which proto sources can be imported, for
use with -proto flags. Multiple import paths can be configured by
specifying multiple -import-path flags. Paths will be searched in the
use with --proto flags. Multiple import paths can be configured by
specifying multiple --import-path flags. Paths will be searched in the
order given. If no import paths are given, all files (including all
imports) must be provided as -proto flags, and grpcurl will attempt to
imports) must be provided as --proto flags, and grpcurl will attempt to
resolve all import statements from the set of file names given.`))
}

Expand All @@ -154,6 +155,10 @@ func (s *multiString) Set(value string) error {
return nil
}

func (s *multiString) Type() string {
return "stringSlice"
}

func main() {
flags.Usage = usage
flags.Parse(os.Args[1:])
Expand All @@ -168,34 +173,34 @@ func main() {

// Do extra validation on arguments and figure out what user asked us to do.
if *connectTimeout < 0 {
fail(nil, "The -connect-timeout argument must not be negative.")
fail(nil, "The --connect-timeout argument must not be negative.")
}
if *keepaliveTime < 0 {
fail(nil, "The -keepalive-time argument must not be negative.")
fail(nil, "The --keepalive-time argument must not be negative.")
}
if *maxTime < 0 {
fail(nil, "The -max-time argument must not be negative.")
fail(nil, "The --max-time argument must not be negative.")
}
if *maxMsgSz < 0 {
fail(nil, "The -max-msg-sz argument must not be negative.")
fail(nil, "The --max-msg-sz argument must not be negative.")
}
if *plaintext && *insecure {
fail(nil, "The -plaintext and -insecure arguments are mutually exclusive.")
fail(nil, "The --plaintext and --insecure arguments are mutually exclusive.")
}
if *plaintext && *cert != "" {
fail(nil, "The -plaintext and -cert arguments are mutually exclusive.")
fail(nil, "The --plaintext and --cert arguments are mutually exclusive.")
}
if *plaintext && *key != "" {
fail(nil, "The -plaintext and -key arguments are mutually exclusive.")
fail(nil, "The --plaintext and --key arguments are mutually exclusive.")
}
if (*key == "") != (*cert == "") {
fail(nil, "The -cert and -key arguments must be used together and both be present.")
fail(nil, "The --cert and --key arguments must be used together and both be present.")
}
if *format != "json" && *format != "text" {
fail(nil, "The -format option must be 'json' or 'text.")
fail(nil, "The --format option must be 'json' or 'text.")
}
if *emitDefaults && *format != "json" {
warn("The -emit-defaults is only used when using json format.")
warn("The --emit-defaults is only used when using json format.")
}

args := flags.Args()
Expand Down Expand Up @@ -232,10 +237,10 @@ func main() {
args = args[1:]
} else {
if *data != "" {
warn("The -d argument is not used with 'list' or 'describe' verb.")
warn("The --data argument is not used with 'list' or 'describe' verb.")
}
if len(rpcHeaders) > 0 {
warn("The -rpc-header argument is not used with 'list' or 'describe' verb.")
warn("The --rpc-header argument is not used with 'list' or 'describe' verb.")
}
if len(args) > 0 {
symbol = args[0]
Expand All @@ -253,13 +258,13 @@ func main() {
fail(nil, "No host:port specified, no protoset specified, and no proto sources specified.")
}
if len(protoset) > 0 && len(reflHeaders) > 0 {
warn("The -reflect-header argument is not used when -protoset files are used.")
warn("The --reflect-header argument is not used when --protoset files are used.")
}
if len(protoset) > 0 && len(protoFiles) > 0 {
fail(nil, "Use either -protoset files or -proto files, but not both.")
fail(nil, "Use either --protoset files or --proto files, but not both.")
}
if len(importPaths) > 0 && len(protoFiles) == 0 {
warn("The -import-path argument is not used unless -proto files are used.")
warn("The --import-path argument is not used unless --proto files are used.")
}

ctx := context.Background()
Expand Down Expand Up @@ -549,7 +554,7 @@ method's request type will be sent.
The address will typically be in the form "host:port" where host can be an IP
address or a hostname and port is a numeric port or service name. If an IPv6
address is given, it must be surrounded by brackets, like "[2001:db8::1]". For
Unix variants, if a -unix=true flag is present, then the address must be the
Unix variants, if a --unix=true flag is present, then the address must be the
path to the domain socket.

Available flags:
Expand Down Expand Up @@ -591,7 +596,7 @@ func fail(err error, msg string, args ...interface{}) {
exit(1)
} else {
// nil error means it was CLI usage issue
fmt.Fprintf(os.Stderr, "Try '%s -help' for more details.\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Try '%s --help' for more details.\n", os.Args[0])
exit(2)
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/fullstorydev/grpcurl
require (
github.com/golang/protobuf v1.3.1
github.com/jhump/protoreflect v1.5.0
github.com/spf13/pflag v1.0.3
golang.org/x/net v0.0.0-20190311183353-d8887717615a
google.golang.org/grpc v1.21.0
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/jhump/protoreflect v1.4.4 h1:kySdALZUh7xRtW6UoZjjHtlR8k7rLzx5EXJFRvsO5UY=
github.com/jhump/protoreflect v1.4.4/go.mod h1:gZ3i/BeD62fjlaIL0VW4UDMT70CTX+3m4pOnAlJ0BX8=
github.com/jhump/protoreflect v1.5.0 h1:NgpVT+dX71c8hZnxHof2M7QDK7QtohIJ7DYycjnkyfc=
github.com/jhump/protoreflect v1.5.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down