Ejemplo n.º 1
0
// reportPanic now only displays panics nicely; at some point, should
// auto-collect panics for central logging
func reportPanic() error {
	fmt.Fprintln(os.Stderr, terminal.Colorize(terminal.ColorError, "\nWe encountered an unexpected internal error."))

	// PanicStack is nil, so don't try to write it.
	if cli.PanicStack == nil {
		return nil
	}

	fmt.Fprintln(os.Stderr, string(cli.PanicStack))
	return nil
}
Ejemplo n.º 2
0
// handleTypedErrors catches typed errors, such as ApiErrors, and prints
// appropriate error messages. It also contains logic necessary for
// reauthenticating and re-executing a command.
func handleTypedErrors(cmd *cli.Cmd, err error) (code int) {
	code = 1
	// Switch off the type of error received, if any.
	switch aerr := err.(type) {
	default:
		// Unknown error received.
		fmt.Fprintf(os.Stderr, terminal.Colorize(terminal.ColorError, ERROR_PREFIX+"%s\n"), aerr.Error())
		fmt.Fprintf(os.Stdout, "Try `kurma-cli help` for more information.\n")
		return
	}
}
Ejemplo n.º 3
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)
}