11package main
22
33import (
4+ "context"
45 "fmt"
6+ "io"
57 "log/slog"
68 "maps"
79 "os"
810 "slices"
911 "strings"
1012
1113 "github.com/lmittmann/tint"
12- cli "github.com/urfave/cli/v2 "
14+ cli "github.com/urfave/cli/v3 "
1315 "github.com/willabides/actionslog"
1416 "github.com/willabides/actionslog/human"
1517 "golang.org/x/term"
@@ -23,6 +25,7 @@ const (
2325 flagNamespace = "namespace"
2426 flagParameter = "parameter"
2527 flagRetries = "retries"
28+ flagPrintConfig = "print-config"
2629 flagWorkflowTemplate = "workflow-template"
2730)
2831
@@ -42,13 +45,17 @@ func parseLogLevel(level string) (slog.Level, error) {
4245}
4346
4447func main () {
48+ runMain (os .Args , os .Stdout , os .Stderr )
49+ }
50+
51+ func runMain (args []string , writer io.Writer , errWriter io.Writer ) {
4552 // If we're on a terminal, we use tint, otherwise if we're on GitHub actions
4653 // we use `willabites/actionslog` to log proper Actions messages, otherwise
4754 // we use logfmt.
4855 var lv slog.LevelVar
4956
5057 logger := slog .New (
51- slog .NewTextHandler (os . Stderr , & slog.HandlerOptions {
58+ slog .NewTextHandler (errWriter , & slog.HandlerOptions {
5259 Level : & lv ,
5360 }),
5461 )
@@ -69,35 +76,64 @@ func main() {
6976 )
7077 }
7178
72- app := cli .NewApp ()
79+ app := cli.Command {}
80+ app .Writer = writer
81+ app .ErrWriter = errWriter
7382 app .Name = "Runs the Argo CLI"
7483
75- app .Action = func (c * cli.Context ) error { return run (c , & lv , logger ) }
84+ app .Action = func (ctx context.Context , c * cli.Command ) error {
85+ return fmt .Errorf ("please specify a command" )
86+ }
87+
88+ app .Commands = []* cli.Command {
89+ {
90+ Name : "submit" ,
91+ SkipFlagParsing : true ,
92+ Writer : writer ,
93+ ErrWriter : errWriter ,
94+ Action : func (ctx context.Context , c * cli.Command ) error {
95+ return run (ctx , c , & lv , logger , "submit" )
96+ },
97+ },
98+ }
7699
77100 app .Flags = []cli.Flag {
78101 & cli.BoolFlag {
79- Name : flagAddCILabels ,
80- EnvVars : []string {"ADD_CI_LABELS" },
81- Value : false ,
82- Usage : "If true, the `--labels` argument will be added with values from the environment. This is forced for the `submit` command" ,
102+ Name : flagPrintConfig ,
103+ Required : false ,
104+ Usage : "If set thie command will only print the gathered configuration and exist" ,
105+ },
106+ & cli.BoolFlag {
107+ Name : flagAddCILabels ,
108+ Sources : cli .NewValueSourceChain (
109+ cli .EnvVar ("ADD_CI_LABELS" ),
110+ ),
111+ Value : false ,
112+ Usage : "If true, the `--labels` argument will be added with values from the environment. This is forced for the `submit` command" ,
83113 },
84114 & cli.StringFlag {
85- Name : flagNamespace ,
86- EnvVars : []string {"ARGO_NAMESPACE" },
115+ Name : flagNamespace ,
116+ Sources : cli .NewValueSourceChain (
117+ cli .EnvVar ("ARGO_NAMESPACE" ),
118+ ),
87119 Required : true ,
88120 },
89121 & cli.StringFlag {
90- Name : flagArgoToken ,
91- EnvVars : []string {"ARGO_TOKEN" },
122+ Name : flagArgoToken ,
123+ Sources : cli .NewValueSourceChain (
124+ cli .EnvVar ("ARGO_TOKEN" ),
125+ ),
92126 Usage : "The Argo token to use for authentication" ,
93127 Required : true ,
94128 },
95129 & cli.StringFlag {
96- Name : flagLogLevel ,
97- EnvVars : []string {"LOG_LEVEL" },
98- Usage : "Which log level to use" ,
99- Value : "info" ,
100- Action : func (c * cli.Context , level string ) error {
130+ Name : flagLogLevel ,
131+ Sources : cli .NewValueSourceChain (
132+ cli .EnvVar ("LOG_LEVEL" ),
133+ ),
134+ Usage : "Which log level to use" ,
135+ Value : "info" ,
136+ Action : func (ctx context.Context , c * cli.Command , level string ) error {
101137 level = strings .ToLower (level )
102138
103139 lvl , err := parseLogLevel (level )
@@ -111,10 +147,12 @@ func main() {
111147 },
112148 },
113149 & cli.StringFlag {
114- Name : flagInstance ,
115- EnvVars : []string {"INSTANCE" },
116- Value : "ops" ,
117- Action : func (c * cli.Context , instance string ) error {
150+ Name : flagInstance ,
151+ Sources : cli .NewValueSourceChain (
152+ cli .EnvVar ("INSTANCE" ),
153+ ),
154+ Value : "ops" ,
155+ Action : func (ctx context.Context , c * cli.Command , instance string ) error {
118156 // Validate it is a known instance
119157 instances := slices .Collect (maps .Keys (instanceToHost ))
120158 if ! slices .Contains (instances , instance ) {
@@ -129,16 +167,20 @@ func main() {
129167 Usage : "Parameters to pass to the workflow template. Given as `key=value`. Specify multiple times for multiple parameters" ,
130168 },
131169 & cli.UintFlag {
132- Name : flagRetries ,
133- EnvVars : []string {"RETRIES" },
134- Value : 3 ,
135- Usage : "Number of retries to make if the command fails" ,
170+ Name : flagRetries ,
171+ Sources : cli .NewValueSourceChain (
172+ cli .EnvVar ("RETRIES" ),
173+ ),
174+ Value : 3 ,
175+ Usage : "Number of retries to make if the command fails" ,
136176 },
137177 & cli.StringFlag {
138- Name : flagWorkflowTemplate ,
139- EnvVars : []string {"WORKFLOW_TEMPLATE" },
140- Usage : "The workflow template to use" ,
141- Action : func (c * cli.Context , tpl string ) error {
178+ Name : flagWorkflowTemplate ,
179+ Sources : cli .NewValueSourceChain (
180+ cli .EnvVar ("WORKFLOW_TEMPLATE" ),
181+ ),
182+ Usage : "The workflow template to use" ,
183+ Action : func (ctx context.Context , c * cli.Command , tpl string ) error {
142184 // Required if command is `submit`
143185 if c .Args ().First () == "submit" && tpl == "" {
144186 return fmt .Errorf ("required flag: %s" , flagWorkflowTemplate )
@@ -148,16 +190,15 @@ func main() {
148190 },
149191 }
150192
151- if err := app .Run (os . Args ); err != nil {
193+ if err := app .Run (context . Background (), args ); err != nil {
152194 logger .With ("error" , err ).Error ("failed to run" )
153195 os .Exit (1 )
154196 }
155197}
156198
157- func run (c * cli.Context , level * slog.LevelVar , logger * slog.Logger ) error {
199+ func run (ctx context. Context , c * cli.Command , level * slog.LevelVar , logger * slog.Logger , command string ) error {
158200 addCILabels := c .Bool (flagAddCILabels )
159201 argoToken := c .String (flagArgoToken )
160- command := c .Args ().First ()
161202 instance := c .String (flagInstance )
162203 namespace := c .String (flagNamespace )
163204 parameters := c .StringSlice (flagParameter )
@@ -173,7 +214,7 @@ func run(c *cli.Context, level *slog.LevelVar, logger *slog.Logger) error {
173214 extraArgs = append (extraArgs , "--parameter" , param )
174215 }
175216
176- extraArgs = append (extraArgs , c .Args ().Tail ()... )
217+ extraArgs = append (extraArgs , c .Args ().Slice ()... )
177218
178219 md , err := NewGitHubActionsMetadata ()
179220 if err != nil {
@@ -192,8 +233,6 @@ func run(c *cli.Context, level *slog.LevelVar, logger *slog.Logger) error {
192233 "namespace" , namespace ,
193234 )
194235
195- logger .With ("extraArgs" , extraArgs ).Info ("running command" )
196-
197236 argo := App {
198237 levelVar : level ,
199238 logger : logger ,
@@ -212,5 +251,13 @@ func run(c *cli.Context, level *slog.LevelVar, logger *slog.Logger) error {
212251 retries : retries ,
213252 }
214253
215- return argo .Run (c .Context , md )
254+ if c .Bool (flagPrintConfig ) {
255+ if err := argo .PrintConfig (c .Writer , md ); err != nil {
256+ return err
257+ }
258+ return nil
259+ }
260+
261+ logger .With ("extraArgs" , extraArgs ).Info ("running command" )
262+ return argo .Run (ctx , md )
216263}
0 commit comments