Skip to content

Commit ae7ec9f

Browse files
committed
JGC-434 - Look for undeclared flags in arguments
1 parent e659f69 commit ae7ec9f

File tree

2 files changed

+130
-7
lines changed

2 files changed

+130
-7
lines changed

plugins/components/conversionlayer.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/jfrog/gofrog/datastructures"
99
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
1010
"github.com/jfrog/jfrog-cli-core/v2/docs/common"
11+
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
1112
"github.com/jfrog/jfrog-client-go/utils/errorutils"
1213
"github.com/urfave/cli"
1314
)
@@ -454,6 +455,11 @@ func getValueForStringFlag(f StringFlag, baseContext *cli.Context) (string, erro
454455
if value != "" {
455456
return value, nil
456457
}
458+
// We try to find the flag value in the command arguments.
459+
_, _, flagValue, err := coreutils.FindFlag(f.Name, baseContext.Args())
460+
if err != nil && flagValue != "" {
461+
return flagValue, nil
462+
}
457463
if f.DefaultValue != "" {
458464
// Empty but has a default value defined.
459465
return f.DefaultValue, nil
@@ -466,8 +472,15 @@ func getValueForStringFlag(f StringFlag, baseContext *cli.Context) (string, erro
466472
}
467473

468474
func getValueForBoolFlag(f BoolFlag, baseContext *cli.Context) bool {
469-
if f.DefaultValue {
470-
return baseContext.BoolT(f.Name)
475+
if baseContext.IsSet(f.Name) {
476+
return baseContext.Bool(f.Name)
471477
}
472-
return baseContext.Bool(f.Name)
478+
479+
// We try to find the flag value in the command arguments.
480+
flagIndex, _, _, _ := coreutils.FindFlag(f.Name, baseContext.Args())
481+
if flagIndex != -1 {
482+
return true
483+
}
484+
485+
return f.DefaultValue
473486
}

plugins/components/conversionlayer_test.go

Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"testing"
77

8+
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
89
"github.com/stretchr/testify/assert"
910
"github.com/urfave/cli"
1011
)
@@ -143,8 +144,7 @@ func TestCreateArgumentsSummary(t *testing.T) {
143144
},
144145
},
145146
}
146-
expected :=
147-
` first argument
147+
expected := ` first argument
148148
this is the first argument.
149149
150150
second [Optional]
@@ -172,8 +172,7 @@ func TestCreateEnvVarsSummary(t *testing.T) {
172172
},
173173
},
174174
}
175-
expected :=
176-
` FIRST_ENV
175+
expected := ` FIRST_ENV
177176
[Default: 15]
178177
This is the first env.
179178
@@ -300,6 +299,117 @@ func TestGetValueForStringFlag(t *testing.T) {
300299
finalValue, err = getValueForStringFlag(f, baseContext)
301300
assert.NoError(t, err)
302301
assert.Equal(t, finalValue, expected)
302+
303+
// Not received but present in command arguments.
304+
flagSet.Parse([]string{"--string-flag", expected})
305+
finalValue, err = getValueForStringFlag(f, baseContext)
306+
assert.NoError(t, err)
307+
assert.Equal(t, finalValue, expected)
308+
}
309+
310+
func TestGetValueForBoolFlag(t *testing.T) {
311+
t.Run("FlagSetInContext_True", func(t *testing.T) {
312+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(false))
313+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
314+
flagSet.Bool(f.Name, false, "")
315+
assert.NoError(t, flagSet.Parse([]string{"--bool-flag"}))
316+
baseContext := cli.NewContext(nil, flagSet, nil)
317+
318+
result := getValueForBoolFlag(f, baseContext)
319+
assert.True(t, result, "Flag set in context with true value should return true")
320+
})
321+
322+
t.Run("FlagSetInContext_False", func(t *testing.T) {
323+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(true))
324+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
325+
flagSet.Bool(f.Name, false, "")
326+
// For false, we need to explicitly set it or use BoolT
327+
// Since Bool flag defaults to false when not set, we'll test with explicit false
328+
baseContext := cli.NewContext(nil, flagSet, nil)
329+
330+
result := getValueForBoolFlag(f, baseContext)
331+
assert.False(t, result, "Flag not set in context should return false for Bool flag")
332+
})
333+
334+
t.Run("FlagSetInContext_BoolT_True", func(t *testing.T) {
335+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(true))
336+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
337+
flagSet.Bool(f.Name, true, "") // BoolT flag defaults to true
338+
assert.NoError(t, flagSet.Parse([]string{}))
339+
baseContext := cli.NewContext(nil, flagSet, nil)
340+
341+
result := getValueForBoolFlag(f, baseContext)
342+
assert.True(t, result, "BoolT flag set in context should return true")
343+
})
344+
345+
t.Run("FlagNotSetInContext_FoundInArgs", func(t *testing.T) {
346+
// Test the FindFlag logic directly since we can't easily set Args() in cli.Context
347+
// The function checks: flagIndex != -1, then returns true
348+
testArgs := []string{"arg1", "--bool-flag", "arg2"}
349+
flagIndex, _, _, _ := coreutils.FindFlag("--bool-flag", testArgs)
350+
assert.NotEqual(t, -1, flagIndex, "Flag should be found in args")
351+
// When flagIndex != -1, the function returns true
352+
// This verifies the logic path even though we can't test the full context integration
353+
})
354+
355+
t.Run("FlagNotSetInContext_NotFoundInArgs_DefaultTrue", func(t *testing.T) {
356+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(true))
357+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
358+
flagSet.Bool(f.Name, false, "")
359+
assert.NoError(t, flagSet.Parse([]string{}))
360+
baseContext := cli.NewContext(nil, flagSet, nil)
361+
362+
result := getValueForBoolFlag(f, baseContext)
363+
assert.True(t, result, "Flag not set and not in args should return default value (true)")
364+
})
365+
366+
t.Run("FlagNotSetInContext_NotFoundInArgs_DefaultFalse", func(t *testing.T) {
367+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(false))
368+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
369+
flagSet.Bool(f.Name, false, "")
370+
assert.NoError(t, flagSet.Parse([]string{}))
371+
baseContext := cli.NewContext(nil, flagSet, nil)
372+
373+
result := getValueForBoolFlag(f, baseContext)
374+
assert.False(t, result, "Flag not set and not in args should return default value (false)")
375+
})
376+
377+
t.Run("FlagSetInContext_OverridesDefault", func(t *testing.T) {
378+
f := NewBoolFlag("bool-flag", "Bool flag", WithBoolDefaultValue(true))
379+
flagSet := flag.NewFlagSet("test", flag.ContinueOnError)
380+
flagSet.Bool(f.Name, false, "")
381+
assert.NoError(t, flagSet.Parse([]string{"--bool-flag=false"}))
382+
baseContext := cli.NewContext(nil, flagSet, nil)
383+
384+
result := getValueForBoolFlag(f, baseContext)
385+
assert.False(t, result, "Flag set in context should override default value")
386+
})
387+
388+
t.Run("FlagNotSetInContext_FoundInArgs_ReturnsTrue", func(t *testing.T) {
389+
// Test the FindFlag logic directly since we can't easily set Args() in cli.Context
390+
// The function checks: flagIndex != -1, then returns true
391+
testArgs := []string{"arg1", "--bool-flag", "arg2"}
392+
flagIndex, _, _, _ := coreutils.FindFlag("--bool-flag", testArgs)
393+
assert.NotEqual(t, -1, flagIndex, "Flag should be found in args")
394+
// When flagIndex != -1, the function returns true
395+
// This verifies the logic path even though we can't test the full context integration
396+
})
397+
398+
t.Run("FlagNotSetInContext_NotFoundInArgs_SimilarPrefix", func(t *testing.T) {
399+
// Test that similar prefix doesn't match
400+
testArgs := []string{"--bool-flag-other"}
401+
flagIndex, _, _, _ := coreutils.FindFlag("--bool-flag", testArgs)
402+
assert.Equal(t, -1, flagIndex, "Similar flag prefix should not match")
403+
// When flagIndex == -1, the function returns default value
404+
})
405+
406+
t.Run("FlagNotSetInContext_ArgsWithEquals", func(t *testing.T) {
407+
// Test flag with =value format
408+
testArgs := []string{"--bool-flag=true"}
409+
flagIndex, _, _, _ := coreutils.FindFlag("--bool-flag", testArgs)
410+
assert.NotEqual(t, -1, flagIndex, "Flag with =value should be found")
411+
// Verify the function would return true when flag is found in args
412+
})
303413
}
304414

305415
type DummyFlagValue struct {

0 commit comments

Comments
 (0)