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  }