package command import ( "context" "fmt" "os" "sort" "time" "forge.cadoles.com/Cadoles/emissary/internal/command/common" "github.com/davecgh/go-spew/spew" "github.com/getsentry/sentry-go" "github.com/pkg/errors" "github.com/urfave/cli/v2" ) func Main(buildDate, projectVersion, gitRef, defaultConfigPath string, commands ...*cli.Command) { ctx := context.Background() compiled, err := time.Parse(time.RFC3339, buildDate) if err != nil { panic(errors.Wrapf(err, "could not parse build date '%s'", buildDate)) } app := &cli.App{ Version: fmt.Sprintf("%s (%s, %s)", projectVersion, gitRef, buildDate), Compiled: compiled, Name: "emissary", Usage: "Control plane for edge devices", Commands: commands, Before: func(ctx *cli.Context) error { workdir := ctx.String("workdir") // Switch to new working directory if defined if workdir != "" { if err := os.Chdir(workdir); err != nil { return errors.Wrap(err, "could not change working directory") } } if err := ctx.Set("projectVersion", projectVersion); err != nil { return errors.WithStack(err) } if err := ctx.Set("gitRef", gitRef); err != nil { return errors.WithStack(err) } if err := ctx.Set("buildDate", buildDate); err != nil { return errors.WithStack(err) } conf, err := common.LoadConfig(ctx) if err != nil { return errors.Wrap(err, "Could not load configuration") } if conf.Sentry.DSN != "" { spew.Dump(conf.Sentry) err = sentry.Init(sentry.ClientOptions{ Dsn: conf.Sentry.DSN, Debug: ctx.Bool("debug"), AttachStacktrace: true, Environment: conf.Sentry.Environment, }) if err != nil { return errors.WithStack(err) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "workdir", Value: "", Usage: "The working directory", }, &cli.StringFlag{ Name: "projectVersion", Value: "", Hidden: true, }, &cli.StringFlag{ Name: "gitRef", Value: "", Hidden: true, }, &cli.StringFlag{ Name: "buildDate", Value: "", Hidden: true, }, &cli.BoolFlag{ Name: "debug", EnvVars: []string{"EMISSARY_DEBUG"}, Value: false, }, &cli.StringFlag{ Name: "config", Aliases: []string{"c"}, EnvVars: []string{"EMISSARY_CONFIG"}, Value: defaultConfigPath, TakesFile: true, }, }, } defer sentry.Flush(2 * time.Second) app.ExitErrHandler = func(ctx *cli.Context, err error) { if err == nil { return } sentry.CaptureException(err) debug := ctx.Bool("debug") if !debug { fmt.Printf("[ERROR] %v\n", err) } else { fmt.Printf("%+v", err) } } sort.Sort(cli.FlagsByName(app.Flags)) sort.Sort(cli.CommandsByName(app.Commands)) if err := app.RunContext(ctx, os.Args); err != nil { os.Exit(1) } }