Esempio n. 1
0
// printHelp dispatches into individual defined commands to find their help, as
// needed
func printHelp(stream *os.File) {
	if _, help, err := cli.NewCmd("help"); err == nil {
		help.RunCli()
	} else {
		fmt.Fprintln(os.Stderr, "help command not defined")
	}
}
Esempio n. 2
0
func main() {
	var exitcode int
	// defer os.Exit first since it would cancel any previous defers.
	defer func() {
		os.Exit(exitcode)
	}()

	// Handle any panic not caught at command-level.
	defer func() {
		if r := recover(); r != nil {
			// Dump the stack with information about what command was being run.
			cli.PanicStack = make([]byte, 1<<20) // 1 MB
			runtime.Stack(cli.PanicStack, true)
			header := "Panic within CLI\n\n"

			// Extend to make room for header.
			cli.PanicStack = append(cli.PanicStack, make([]byte, len(header))...)
			copy(cli.PanicStack[len(header):], cli.PanicStack)
			copy(cli.PanicStack[:len(header)], header)

			reportPanic()
		}
	}()

	handleSignals()

	// Special handling of flags to avoid calling flag.Parse() here. Commands
	// use flag.Flagsets and we don't want to interfere.
	if len(os.Args) == 1 {
		printHelp(os.Stderr)
		exitcode = 1
		return
	} else if len(os.Args) == 2 {
		switch os.Args[1] {
		case "-v", "--v", "-version", "--version":
			if _, ver, err := cli.NewCmd("version"); err == nil {
				ver.RunCli()
			} else {
				fmt.Fprintln(os.Stderr, "version command not defined")
			}
			return
		case "-h", "--h", "-help", "--help":
			printHelp(os.Stdout)
			exitcode = 0
			return
		}
	}

	// Find the command
	cmdDef, cmd, err := cli.NewCmd(os.Args[1:]...)
	if err != nil {
		exitcode = 1
		// Print help and error if command was found but args were incorrect.
		// e.g. any validation errors returned are surfaced here.
		if cmdDef != nil {
			cmdDef.PrintHelp(os.Stderr)
			// Hide any 'help requested' errors from bubbling up, but still show
			// usage errors.
			if err.Error() == "flag: help requested" {
				return
			}
		}
		fmt.Fprintf(os.Stderr, terminal.Colorize(terminal.ColorError, "Error (usage): %s\n"), err)
		exitcode = 1
		return
	}

	// Catch any other '--version' flags.  While instances of "apc --version", etc
	// will be caught above in our len(os.Args) case, we want to take example input
	// like "apc app --version" just in case.
	if cli.ShowVersion {
		if _, ver, err := cli.NewCmd("version"); err == nil {
			ver.RunCli()
		} else {
			fmt.Fprintln(os.Stderr, "version command not defined")
		}
		return
	}

	conn, err := grpc.Dial(determineKurmaHostPort())
	if err != nil {
		fmt.Fprintf(os.Stderr, terminal.Colorize(terminal.ColorError, ERROR_PREFIX+"%s\n"), err.Error())
		exitcode = 1
		return
	}
	defer conn.Close()
	cmd.Client = pb.NewKurmaClient(conn)

	exitcode = runCommand(cmd)
}