github.com/knieriem/gointernal@v0.2.0-pre2/cmd/cli/main.go (about)

     1  // Copyright 2011 The Go 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  package cli
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"os"
    11  	"strings"
    12  
    13  	"github.com/knieriem/gointernal/cmd/cli/internal/help"
    14  	"github.com/knieriem/gointernal/cmd/go/base"
    15  )
    16  
    17  type Command = base.Command
    18  
    19  func EvalArgs(args []string) {
    20  	if len(args) < 1 {
    21  		base.Usage()
    22  	}
    23  
    24  	cmdName := args[0] // for error messages
    25  	if args[0] == "help" {
    26  		help.Help(os.Stdout, args[1:])
    27  		return
    28  	}
    29  
    30  BigCmdLoop:
    31  	for bigCmd := base.Prog; ; {
    32  		for _, cmd := range bigCmd.Commands {
    33  			if cmd.Name() != args[0] {
    34  				continue
    35  			}
    36  			if len(cmd.Commands) > 0 {
    37  				bigCmd = cmd
    38  				args = args[1:]
    39  				if len(args) == 0 {
    40  					help.PrintUsage(os.Stderr, bigCmd)
    41  					base.SetExitStatus(2)
    42  					base.Exit()
    43  				}
    44  				if args[0] == "help" {
    45  					// Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
    46  					help.Help(os.Stdout, append(strings.Split(cmdName, " "), args[1:]...))
    47  					return
    48  				}
    49  				cmdName += " " + args[0]
    50  				continue BigCmdLoop
    51  			}
    52  			if !cmd.Runnable() {
    53  				continue
    54  			}
    55  			invoke(cmd, args)
    56  			base.Exit()
    57  			return
    58  		}
    59  		helpArg := ""
    60  		if i := strings.LastIndex(cmdName, " "); i >= 0 {
    61  			helpArg = " " + cmdName[:i]
    62  		}
    63  		progName := base.Prog.UsageLine
    64  		fmt.Fprintf(os.Stderr, "%s %s: unknown command\nRun '%s help%s' for usage.\n", progName, cmdName, progName, helpArg)
    65  		base.SetExitStatus(2)
    66  		base.Exit()
    67  	}
    68  }
    69  
    70  func invoke(cmd *base.Command, args []string) {
    71  	cmd.Flag.Usage = func() { cmd.Usage() }
    72  	if cmd.CustomFlags {
    73  		args = args[1:]
    74  	} else {
    75  		cmd.Flag.Parse(args[1:])
    76  		args = cmd.Flag.Args()
    77  	}
    78  	ctx := context.Background()
    79  	cmd.Run(ctx, cmd, args)
    80  }
    81  
    82  func init() {
    83  	base.Usage = mainUsage
    84  }
    85  
    86  func mainUsage() {
    87  	help.PrintUsage(os.Stderr, base.Prog)
    88  	os.Exit(2)
    89  }