func Main(ctx context.Context, app Application, args []string) {
	s := flag.NewFlagSet(app.Name(), flag.ExitOnError)
	s.Usage = func() {
		fmt.Fprint(s.Output(), app.ShortHelp())
		fmt.Fprintf(s.Output(), "\n\nUsage: %v [flags] %v\n", app.Name(), app.Usage())
		app.DetailedHelp(s)
	}
	addFlags(s, reflect.StructField{}, reflect.ValueOf(app))
	if err := Run(ctx, app, args); err != nil {
		fmt.Fprintf(s.Output(), "%s: %v\n", app.Name(), err)
		if _, printHelp := err.(commandLineError); printHelp {
			s.Usage()
		}
		os.Exit(2)
	}
}
Main should be invoked directly by main function.
It will only return if there was no error.  If an error
was encountered it is printed to standard error and the
application exits with an exit code of 2.
package tool
import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"reflect"
	"runtime"
	"runtime/pprof"
	"runtime/trace"
	"time"
)
type Profile struct {
	CPU    string `flag:"profile.cpu" help:"write CPU profile to this file"`
	Memory string `flag:"profile.mem" help:"write memory profile to this file"`
	Trace  string `flag:"profile.trace" help:"write trace log to this file"`
}
type Application interface {
	Name() string
	Usage() string
	ShortHelp() string
	DetailedHelp(*flag.FlagSet)
	Run(ctx context.Context, args ...string) error
}
type commandLineError string
func (e commandLineError) Error() string { return string(e) }
func CommandLineErrorf(message string, args ...interface{}) error {
	return commandLineError(fmt.Sprintf(message, args...))
}