github.com/rgonomic/rgo@v0.2.2-0.20220708095818-4747f0905d6e/internal/rgo/cmd.go (about) 1 // Copyright ©2019 The rgonomic 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 // Copyright 2018 The Go Authors. All rights reserved. 6 // Use of this source code is governed by a BSD-style 7 // license that can be found in the LICENSE file. 8 9 // Package rgo handles the rgo command line. 10 // It contains a handler for each of the modes, along with all the flag handling 11 // and the command line output format. 12 package rgo 13 14 import ( 15 "context" 16 "flag" 17 "fmt" 18 "os" 19 20 "github.com/rgonomic/rgo/internal/tool" 21 ) 22 23 // Application is the main application as passed to tool.Main 24 // It handles the main command line parsing and dispatch to the sub commands. 25 type Application struct { 26 // Core application flags 27 28 // Embed the basic profiling flags supported by the tool package 29 tool.Profile 30 31 // The name of the binary, used in help and telemetry. 32 name string 33 34 // The working directory to run commands in. 35 wd string 36 37 // The environment variables to use. 38 env []string 39 40 // Enable verbose logging 41 Verbose bool `flag:"v" help:"verbose output"` 42 } 43 44 // Returns a new Application ready to run. 45 func New(name, wd string, env []string) *Application { 46 if wd == "" { 47 wd, _ = os.Getwd() 48 } 49 return &Application{ 50 name: name, 51 wd: wd, 52 env: env, 53 } 54 } 55 56 // Name implements tool.Application returning the binary name. 57 func (app *Application) Name() string { return app.name } 58 59 // Usage implements tool.Application returning empty extra argument usage. 60 func (app *Application) Usage() string { return "<command> [command-flags] [command-args]" } 61 62 // ShortHelp implements tool.Application returning the main binary help. 63 func (app *Application) ShortHelp() string { 64 return "The rgo source building tools." 65 } 66 67 // DetailedHelp implements tool.Application returning the main binary help. 68 // This includes the short help for all the sub commands. 69 func (app *Application) DetailedHelp(f *flag.FlagSet) { 70 fmt.Fprint(f.Output(), ` 71 Available commands are: 72 `) 73 for _, c := range app.commands() { 74 fmt.Fprintf(f.Output(), " %s: %v\n", c.Name(), c.ShortHelp()) 75 } 76 fmt.Fprint(f.Output(), ` 77 rgo flags are: 78 `) 79 f.PrintDefaults() 80 } 81 82 // Run takes the args after top level flag processing, and invokes the correct 83 // sub command as specified by the first argument. 84 // If no arguments are passed it will invoke the server sub command, as a 85 // temporary measure for compatibility. 86 func (app *Application) Run(ctx context.Context, args ...string) error { 87 if len(args) == 0 { 88 return tool.Run(ctx, &help{}, args) 89 } 90 command, args := args[0], args[1:] 91 for _, c := range app.commands() { 92 if c.Name() == command { 93 return tool.Run(ctx, c, args) 94 } 95 } 96 return tool.CommandLineErrorf("Unknown command %v", command) 97 } 98 99 // commands returns the set of commands supported by the rgo tool on the 100 // command line. 101 // The command is specified by the first non flag argument. 102 func (app *Application) commands() []tool.Application { 103 return []tool.Application{ 104 &setup{app: app, DryRun: false}, 105 &build{app: app, DryRun: false}, 106 &version{app: app}, 107 &help{}, 108 } 109 }