@@ -185,71 +185,104 @@ func Test_CreateCommandsForWorkflowWithSubcommands(t *testing.T) {
185185 assert .True (t , cmd2 .Hidden )
186186}
187187
188- func Test_runMainWorkflow_unknownargs (t * testing.T ) {
188+ // setupMainWorkflowTestEnv wires up the global engine/config that runMainWorkflow needs and
189+ // returns a fresh per-invocation config plus a command. Callers should `defer cleanup()`.
190+ func setupMainWorkflowTestEnv (t * testing.T ) (configuration.Configuration , * cobra.Command ) {
191+ t .Helper ()
192+
193+ globalConfiguration = configuration .New ()
194+ globalConfiguration .Set (configuration .DEBUG , true )
195+ globalEngine = workflow .NewWorkFlowEngine (globalConfiguration )
196+
197+ noopWorkflow := func (workflow.InvocationContext , []workflow.Data ) ([]workflow.Data , error ) {
198+ return []workflow.Data {}, nil
199+ }
200+ for _ , name := range []string {"command" , localworkflows .WORKFLOWID_OUTPUT_WORKFLOW .Host } {
201+ opts := workflow .ConfigurationOptionsFromFlagset (pflag .NewFlagSet ("pla" , pflag .ContinueOnError ))
202+ _ , err := globalEngine .Register (workflow .NewWorkflowIdentifier (name ), opts , noopWorkflow )
203+ require .NoError (t , err )
204+ }
205+ require .NoError (t , localworkflows .InitDataTransformationWorkflow (globalEngine ))
206+ _ = globalEngine .Init ()
207+ require .NoError (t , localworkflows .InitFilterFindingsWorkflow (globalEngine ))
208+
209+ return configuration .NewWithOpts (configuration .WithAutomaticEnv ()), & cobra.Command {Use : "command" }
210+ }
211+
212+ // Test_runMainWorkflow_inputDirectoryParsing is the CLI-1631 regression coverage. It asserts how
213+ // positional paths and "--" passthrough args map onto INPUT_DIRECTORY and UNKNOWN_ARGS. The key
214+ // invariant: passthrough tokens after "--" must never leak into INPUT_DIRECTORY (which would make
215+ // the downstream flow router misread them as package names and force the legacy, no-Risk-Score flow),
216+ // regardless of the path shape. wantInputDirs == nil means INPUT_DIRECTORY must be left unset so it
217+ // later defaults to the working directory.
218+ func Test_runMainWorkflow_inputDirectoryParsing (t * testing.T ) {
189219 tests := map [string ]struct {
190- inputDir string
191- unknownArgs []string
220+ positionalArgs []string
221+ rawArgs []string
222+ wantInputDirs []string
223+ wantUnknownArgs []string
192224 }{
193- "input dir with unknown arguments" : {inputDir : "a/b/c" , unknownArgs : []string {"a" , "b" , "c" }},
194- "no input dir with unknown arguments" : {inputDir : "" , unknownArgs : []string {"a" , "b" , "c" }},
195- "input dir without unknown arguments" : {inputDir : "a" , unknownArgs : []string {}},
225+ "path with -- passthrough, current dir" : {
226+ positionalArgs : []string {"." , "-s" , "settings.xml" },
227+ rawArgs : []string {"snyk" , "test" , "." , "--" , "-s" , "settings.xml" },
228+ wantInputDirs : []string {"." },
229+ wantUnknownArgs : []string {"-s" , "settings.xml" },
230+ },
231+ "path with -- passthrough, relative" : {
232+ positionalArgs : []string {"sub/project" , "-s" , "settings.xml" },
233+ rawArgs : []string {"snyk" , "test" , "sub/project" , "--" , "-s" , "settings.xml" },
234+ wantInputDirs : []string {"sub/project" },
235+ wantUnknownArgs : []string {"-s" , "settings.xml" },
236+ },
237+ "path with -- passthrough, absolute" : {
238+ positionalArgs : []string {"/home/user/project" , "-s" , "settings.xml" },
239+ rawArgs : []string {"snyk" , "test" , "/home/user/project" , "--" , "-s" , "settings.xml" },
240+ wantInputDirs : []string {"/home/user/project" },
241+ wantUnknownArgs : []string {"-s" , "settings.xml" },
242+ },
243+ "only -- passthrough, no path" : {
244+ positionalArgs : []string {"-s" , "settings.xml" },
245+ rawArgs : []string {"snyk" , "test" , "--" , "-s" , "settings.xml" },
246+ wantInputDirs : nil ,
247+ wantUnknownArgs : []string {"-s" , "settings.xml" },
248+ },
249+ "no --, single path" : {
250+ positionalArgs : []string {"." },
251+ rawArgs : []string {"snyk" , "test" , "." },
252+ wantInputDirs : []string {"." },
253+ },
254+ "no --, multiple paths" : {
255+ positionalArgs : []string {"dir1" , "dir2" },
256+ rawArgs : []string {"snyk" , "test" , "dir1" , "dir2" },
257+ wantInputDirs : []string {"dir1" , "dir2" },
258+ },
259+ "bare command, no path no --" : {
260+ positionalArgs : []string {},
261+ rawArgs : []string {"snyk" , "test" },
262+ wantInputDirs : nil ,
263+ },
196264 }
197265
198266 for name , tc := range tests {
199267 t .Run (name , func (t * testing.T ) {
200- expectedInputDir := tc .inputDir
201- expectedUnknownArgs := tc .unknownArgs
202-
203268 defer cleanup ()
204- globalConfiguration = configuration .New ()
205- globalConfiguration .Set (configuration .DEBUG , true )
206- globalEngine = workflow .NewWorkFlowEngine (globalConfiguration )
207-
208- fn := func (invocation workflow.InvocationContext , input []workflow.Data ) ([]workflow.Data , error ) {
209- return []workflow.Data {}, nil
210- }
211-
212- // setup workflow engine to contain a workflow with subcommands
213- commandList := []string {"command" , localworkflows .WORKFLOWID_OUTPUT_WORKFLOW .Host }
214- for _ , v := range commandList {
215- workflowConfig := workflow .ConfigurationOptionsFromFlagset (pflag .NewFlagSet ("pla" , pflag .ContinueOnError ))
216- workflowId1 := workflow .NewWorkflowIdentifier (v )
217- _ , err := globalEngine .Register (workflowId1 , workflowConfig , fn )
218- assert .NoError (t , err )
219- }
269+ config , cmd := setupMainWorkflowTestEnv (t )
220270
221- // Register our data transformation workflow
222- err := localworkflows .InitDataTransformationWorkflow (globalEngine )
223- assert .NoError (t , err )
271+ require .NoError (t , runMainWorkflow (config , cmd , tc .positionalArgs , tc .rawArgs ))
224272
225- _ = globalEngine .Init ()
226- // Register our data filter workflow
227- err = localworkflows .InitFilterFindingsWorkflow (globalEngine )
228- assert .NoError (t , err )
229-
230- config := configuration .NewWithOpts (configuration .WithAutomaticEnv ())
231- cmd := & cobra.Command {
232- Use : "command" ,
273+ if tc .wantInputDirs == nil {
274+ assert .Nil (t , config .Get (configuration .INPUT_DIRECTORY ),
275+ "INPUT_DIRECTORY must be left unset so it defaults to the working directory" )
276+ } else {
277+ assert .Equal (t , tc .wantInputDirs , config .GetStringSlice (configuration .INPUT_DIRECTORY ),
278+ "passthrough args after -- must not leak into INPUT_DIRECTORY" )
233279 }
234280
235- positionalArgs := []string {expectedInputDir }
236- positionalArgs = append (positionalArgs , expectedUnknownArgs ... )
237-
238- rawArgs := []string {"app" , "command" , "--sad" , expectedInputDir }
239- if len (expectedUnknownArgs ) > 0 {
240- rawArgs = append (rawArgs , "--" )
241- rawArgs = append (rawArgs , expectedUnknownArgs ... )
281+ if len (tc .wantUnknownArgs ) == 0 {
282+ assert .Empty (t , config .GetStringSlice (configuration .UNKNOWN_ARGS ))
283+ } else {
284+ assert .Equal (t , tc .wantUnknownArgs , config .GetStringSlice (configuration .UNKNOWN_ARGS ))
242285 }
243-
244- // call method under test
245- err = runMainWorkflow (config , cmd , positionalArgs , rawArgs )
246- assert .Nil (t , err )
247-
248- actualInputDir := config .GetString (configuration .INPUT_DIRECTORY )
249- assert .Equal (t , expectedInputDir , actualInputDir )
250-
251- actualUnknownArgs := config .GetStringSlice (configuration .UNKNOWN_ARGS )
252- assert .Equal (t , expectedUnknownArgs , actualUnknownArgs )
253286 })
254287 }
255288}
0 commit comments