package cli import ( "fmt" "os" "time" "github.com/pterm/pterm" "github.com/urfave/cli/v2" "github.com/apex/log" acli "github.com/apex/log/handlers/cli" ) type CLIApp struct { appname string version string gitrev string startupTime time.Time exitCode int app *cli.App } func (mfa *CLIApp) printBanner() { s, _ := pterm.DefaultBigText.WithLetters(pterm.NewLettersFromString(mfa.appname)).Srender() pterm.DefaultCenter.Println(s) // Print BigLetters with the default CenterPrinter } func (mfa *CLIApp) disableStyling() { pterm.DisableColor() pterm.DisableStyling() pterm.Debug.Prefix.Text = "" pterm.Info.Prefix.Text = "" pterm.Success.Prefix.Text = "" pterm.Warning.Prefix.Text = "" pterm.Error.Prefix.Text = "" pterm.Fatal.Prefix.Text = "" } func (mfa *CLIApp) VersionString() string { return fmt.Sprintf("%s (%s)", mfa.version, mfa.gitrev) } func (mfa *CLIApp) run() { mfa.startupTime = time.Now() if NO_COLOR { // shoutout to rob pike who thinks it's juvenile mfa.disableStyling() } log.SetHandler(acli.Default) log.SetLevel(log.InfoLevel) mfa.app = &cli.App{ Name: mfa.appname, Usage: "Manifest generator", Version: mfa.VersionString(), EnableBashCompletion: true, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "verbose", Usage: "Verbosity level", Aliases: []string{"v"}, }, &cli.BoolFlag{ Name: "quiet", Usage: "don't produce output except on error", Aliases: []string{"q"}, }, }, Action: func(c *cli.Context) error { if c.Bool("verbose") { log.SetLevel(log.DebugLevel) } return nil }, Commands: []*cli.Command{ { Name: "generate", Aliases: []string{"gen"}, Usage: "Generate manifest file", Action: func(c *cli.Context) error { if !c.Bool("quiet") { mfa.printBanner() } return mfa.generateManifestOperation(c) }, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "FollowSymLinks", Aliases: []string{"follow-symlinks"}, Usage: "Resolve encountered symlinks", }, &cli.BoolFlag{ Name: "IgnoreDotfiles", Aliases: []string{"ignore-dotfiles"}, Usage: "Ignore any dot (hidden) files encountered", }, // FIXME this should be a positional arg &cli.StringFlag{ Name: "input", Value: ".", Aliases: []string{"i"}, Usage: "Specify input directory.", }, &cli.StringFlag{ Name: "output", Value: "./index.mf", Aliases: []string{"o"}, Usage: "Specify output filename", }, }, }, { Name: "check", Usage: "Validate files using manifest file", Action: func(c *cli.Context) error { if !c.Bool("quiet") { mfa.printBanner() } return mfa.checkManifestOperation(c) }, }, { Name: "version", Usage: "Show version", Action: func(c *cli.Context) error { fmt.Printf("%s\n", mfa.VersionString()) return nil }, }, { Name: "fetch", Usage: "fetch manifest and referenced files", Action: func(c *cli.Context) error { if !c.Bool("quiet") { mfa.printBanner() } return mfa.fetchManifestOperation(c) }, }, }, } mfa.app.HideVersion = true err := mfa.app.Run(os.Args) if err != nil { mfa.exitCode = 1 log.WithError(err).Debugf("exiting") } }