| 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(host string) (*url.URL, error) { |
| 86 host = strings.TrimSuffix(host, "/") |
| 87 |
| 88 switch { |
| 89 case host == "": |
| 90 return nil, fmt.Errorf("unspecified") |
| 91 |
| 92 case strings.Contains(host, "://"): |
| 93 return nil, fmt.Errorf("must not have scheme") |
| 94 |
| 95 case strings.ContainsAny(host, "?/#"): |
| 96 return nil, fmt.Errorf("must not have query, path or fragment") |
| 97 |
| 98 case strings.HasPrefix(host, ":"): |
| 99 host = "localhost" + host |
| 100 } |
| 101 |
| 102 u := &url.URL{ |
| 103 Scheme: "https", |
| 104 Host: host, |
| 105 } |
| 106 if isLocalHost(host) { |
| 107 u.Scheme = "http" |
| 108 } |
| 109 return u, nil |
| 110 } |
| 111 |
| 112 func isLocalHost(host string) bool { |
| 113 return host == "localhost" || strings.HasPrefix(host, "localhost:") || |
| 114 host == "127.0.0.1" || strings.HasPrefix(host, "127.0.0.1:") |
| 115 } |
| OLD | NEW |