From ce435a893b047fef5655a4465bbb1cbb77040f84 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Fri, 29 Nov 2024 19:43:45 +0000 Subject: [PATCH 1/2] draft dump json in help --- cmd/root.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index bbe6917b836..544044cf5e4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,7 +4,9 @@ import ( "bufio" "bytes" "context" + "encoding/json" "fmt" + "html/template" "os" "path/filepath" "regexp" @@ -21,6 +23,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" + "github.com/spf13/pflag" "gopkg.in/yaml.v3" "github.com/nektos/act/pkg/artifactcache" @@ -31,6 +34,13 @@ import ( "github.com/nektos/act/pkg/runner" ) +type Flag struct { + Name string `json:"name"` + Default string `json:"default"` + Type string `json:"type"` + Usage string `json:"usage"` +} + // Execute is the entry point to running the CLI func Execute(ctx context.Context, version string) { input := new(Input) @@ -44,6 +54,51 @@ func Execute(ctx context.Context, version string) { Version: version, SilenceUsage: true, } + + cobra.AddTemplateFunc("json", func(v interface{}) template.JS { + // a, _ := json.Marshal(v) + flags := []Flag{} + rootCmd.LocalFlags().VisitAll(func(f *pflag.Flag) { + flags = append(flags, Flag{Name: f.Name, Default: f.DefValue, Usage: f.Usage, Type: f.Value.Type()}) + }) + a, _ := json.Marshal(flags) + return template.JS(a) + }) + + rootCmd.SetUsageTemplate(`We won +Usage:{{if .Runnable}} + {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} + +Aliases: + {{.NameAndAliases}}{{end}}{{if .HasExample}} + +Examples: +{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}} + +Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}} + +{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}} + +Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} + +Json Flags: +{{json .LocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} + +Global Flags: +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} + +Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} + {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +`) rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change") rootCmd.Flags().BoolP("list", "l", false, "list workflows") rootCmd.Flags().BoolP("graph", "g", false, "draw workflows") @@ -658,7 +713,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str func defaultImageSurvey(actrc string) error { var answer string confirmation := &survey.Select{ - Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in " + configLocations()[0] + " (please refer to https://github.com/nektos/act#configuration for additional information about file structure)", + Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in " + configLocations()[0] + " (please refer to https://github.com/nektos/act#configuration for additional information about file structure)", Help: "If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107", Default: "Medium", Options: []string{"Large", "Medium", "Micro"}, From 065e2eaf9dafee751c3b0962a31439752dd972be Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Fri, 6 Dec 2024 19:22:49 +0000 Subject: [PATCH 2/2] polish feature --- cmd/input.go | 1 + cmd/notices.go | 4 +++ cmd/root.go | 67 ++++++++++++++------------------------------------ 3 files changed, 23 insertions(+), 49 deletions(-) diff --git a/cmd/input.go b/cmd/input.go index 59c14002b2c..74b5653b969 100644 --- a/cmd/input.go +++ b/cmd/input.go @@ -60,6 +60,7 @@ type Input struct { networkName string useNewActionCache bool localRepository []string + listOptions bool } func (i *Input) resolve(path string) string { diff --git a/cmd/notices.go b/cmd/notices.go index a912bd9f828..26cd4000bb0 100644 --- a/cmd/notices.go +++ b/cmd/notices.go @@ -20,6 +20,10 @@ type Notice struct { } func displayNotices(input *Input) { + // Avoid causing trouble parsing the json + if input.listOptions { + return + } select { case notices := <-noticesLoaded: if len(notices) > 0 { diff --git a/cmd/root.go b/cmd/root.go index 544044cf5e4..ba0baee1f05 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,7 +6,6 @@ import ( "context" "encoding/json" "fmt" - "html/template" "os" "path/filepath" "regexp" @@ -35,10 +34,10 @@ import ( ) type Flag struct { - Name string `json:"name"` - Default string `json:"default"` - Type string `json:"type"` - Usage string `json:"usage"` + Name string `json:"name"` + Default string `json:"default"` + Type string `json:"type"` + Description string `json:"description"` } // Execute is the entry point to running the CLI @@ -55,50 +54,6 @@ func Execute(ctx context.Context, version string) { SilenceUsage: true, } - cobra.AddTemplateFunc("json", func(v interface{}) template.JS { - // a, _ := json.Marshal(v) - flags := []Flag{} - rootCmd.LocalFlags().VisitAll(func(f *pflag.Flag) { - flags = append(flags, Flag{Name: f.Name, Default: f.DefValue, Usage: f.Usage, Type: f.Value.Type()}) - }) - a, _ := json.Marshal(flags) - return template.JS(a) - }) - - rootCmd.SetUsageTemplate(`We won -Usage:{{if .Runnable}} - {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} - {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} - -Aliases: - {{.NameAndAliases}}{{end}}{{if .HasExample}} - -Examples: -{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}} - -Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}} - -{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}} - -Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} - -Json Flags: -{{json .LocalFlags}} - -Flags: -{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} - -Global Flags: -{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} - -Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} - {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} - -Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} -`) rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change") rootCmd.Flags().BoolP("list", "l", false, "list workflows") rootCmd.Flags().BoolP("graph", "g", false, "draw workflows") @@ -159,6 +114,7 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e rootCmd.PersistentFlags().StringVarP(&input.networkName, "network", "", "host", "Sets a docker network name. Defaults to host.") rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally") rootCmd.PersistentFlags().StringArrayVarP(&input.localRepository, "local-repository", "", []string{}, "Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)") + rootCmd.PersistentFlags().BoolVar(&input.listOptions, "list-options", false, "Print a json structure of compatible options") rootCmd.SetArgs(args()) if err := rootCmd.Execute(); err != nil { @@ -297,6 +253,16 @@ func generateManPage(cmd *cobra.Command) error { return nil } +func listOptions(cmd *cobra.Command) error { + flags := []Flag{} + cmd.LocalFlags().VisitAll(func(f *pflag.Flag) { + flags = append(flags, Flag{Name: f.Name, Default: f.DefValue, Description: f.Usage, Type: f.Value.Type()}) + }) + a, err := json.Marshal(flags) + fmt.Println(string(a)) + return err +} + func readArgsFile(file string, split bool) []string { args := make([]string, 0) f, err := os.Open(file) @@ -414,6 +380,9 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str if ok, _ := cmd.Flags().GetBool("man-page"); ok { return generateManPage(cmd) } + if input.listOptions { + return listOptions(cmd) + } if ret, err := container.GetSocketAndHost(input.containerDaemonSocket); err != nil { log.Warnf("Couldn't get a valid docker connection: %+v", err)