| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium 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 "fmt" |
| 9 "net/url" |
| 10 "os" |
| 11 "strings" |
| 12 |
| 13 "github.com/maruel/subcommands" |
| 14 gol "github.com/op/go-logging" |
| 15 "golang.org/x/net/context" |
| 16 |
| 17 "github.com/luci/luci-go/common/logging/gologger" |
| 18 ) |
| 19 |
| 20 const ( |
| 21 userAgent = "luci-rpc" |
| 22 ) |
| 23 |
| 24 // cmdRun is a base of all rpc subcommands. |
| 25 // It defines some common flags, such as logging, and useful methods. |
| 26 type cmdRun struct { |
| 27 subcommands.CommandRunBase |
| 28 verbose bool |
| 29 } |
| 30 |
| 31 // registerBaseFlags registers common flags used by all subcommands. |
| 32 func (r *cmdRun) registerBaseFlags() { |
| 33 r.Flags.BoolVar(&r.verbose, "verbose", false, "Enable more logging.") |
| 34 } |
| 35 |
| 36 // initContext creates a context with installed logger. |
| 37 func (r *cmdRun) initContext() context.Context { |
| 38 // Setup logger. |
| 39 loggerConfig := gologger.LoggerConfig{ |
| 40 Format: `%{message}`, |
| 41 Out: os.Stderr, |
| 42 Level: gol.WARNING, |
| 43 } |
| 44 if r.verbose { |
| 45 loggerConfig.Level = gol.DEBUG |
| 46 } |
| 47 return loggerConfig.Use(context.Background()) |
| 48 } |
| 49 |
| 50 // argErr prints an err and usage to stderr and returns an exit code. |
| 51 func (r *cmdRun) argErr(format string, a ...interface{}) int { |
| 52 if format != "" { |
| 53 fmt.Fprintf(os.Stderr, format+"\n", a...) |
| 54 } |
| 55 fmt.Fprintln(os.Stderr, cmdCall.ShortDesc) |
| 56 fmt.Fprintln(os.Stderr, cmdCall.UsageLine) |
| 57 fmt.Fprintln(os.Stderr, "\nFlags:") |
| 58 r.Flags.PrintDefaults() |
| 59 return 1 |
| 60 } |
| 61 |
| 62 // done prints err to stderr if it is not nil and returns an exit code. |
| 63 func (r *cmdRun) done(err error) int { |
| 64 if err != nil { |
| 65 fmt.Fprintln(os.Stderr, err) |
| 66 return 2 |
| 67 } |
| 68 return 0 |
| 69 } |
| 70 |
| 71 var application = &subcommands.DefaultApplication{ |
| 72 Name: "rpc", |
| 73 Title: "Remote Procedure Call CLI", |
| 74 Commands: []*subcommands.Command{ |
| 75 cmdCall, |
| 76 cmdShow, |
| 77 }, |
| 78 } |
| 79 |
| 80 func main() { |
| 81 os.Exit(subcommands.Run(application, os.Args[1:])) |
| 82 } |
| 83 |
| 84 // parseServer validates and parses a server URL. |
| 85 func parseServer(server string) (*url.URL, error) { |
| 86 switch { |
| 87 case strings.HasPrefix(server, ":"): |
| 88 server = "http://localhost" + server |
| 89 case !strings.HasPrefix(server, "http://") && !strings.HasPrefix(server,
"https://"): |
| 90 return nil, fmt.Errorf("server must start with http:// or https:
//, unless it is :port") |
| 91 } |
| 92 |
| 93 u, err := url.Parse(server) |
| 94 u.Path = strings.TrimSuffix(u.Path, "/") |
| 95 switch { |
| 96 case err != nil: |
| 97 return nil, err |
| 98 // Double-check scheme. |
| 99 case u.Scheme != "http" && u.Scheme != "https": |
| 100 return nil, fmt.Errorf("invalid scheme %q. Must be http or https
", u.Scheme) |
| 101 case u.Path != "": |
| 102 return nil, fmt.Errorf("must not have path") |
| 103 case u.RawQuery != "": |
| 104 return nil, fmt.Errorf("must not have query") |
| 105 case u.Fragment != "": |
| 106 return nil, fmt.Errorf("must not have fragment") |
| 107 default: |
| 108 return u, nil |
| 109 } |
| 110 } |
| OLD | NEW |