diff --git a/.changes/unreleased/fixed-20240624-203927.yaml b/.changes/unreleased/fixed-20240624-203927.yaml new file mode 100644 index 00000000..68673248 --- /dev/null +++ b/.changes/unreleased/fixed-20240624-203927.yaml @@ -0,0 +1,5 @@ +kind: fixed +body: New command can now properly create a fragment via custom CLI arguments if using a kind with custom choices. +time: 2024-06-24T20:39:27.135679465-07:00 +custom: + Issue: "675" diff --git a/.golangci.yml b/.golangci.yml index 61102990..e770f3b5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -46,3 +46,8 @@ linters: - unused - whitespace - wsl +issues: + exclude-rules: + - path: '(.+)_test\.go' + linters: + - gosec diff --git a/core/prompt.go b/core/prompt.go index 2db7ce4e..1f295de7 100644 --- a/core/prompt.go +++ b/core/prompt.go @@ -128,11 +128,27 @@ func (p *Prompts) validateArguments() error { return errKindProvidedWhenNotConfigured } + configuredCustoms := make([]Custom, 0) + + if len(p.Config.Kinds) > 0 && len(p.Kind) > 0 { + kc := p.Config.KindFromKeyOrLabel(p.Kind) + if kc == nil { + return fmt.Errorf("%w: %s", errInvalidKind, p.Kind) + } + + configuredCustoms = append(configuredCustoms, kc.AdditionalChoices...) + if !kc.SkipGlobalChoices { + configuredCustoms = append(configuredCustoms, p.Config.CustomChoices...) + } + } else { + configuredCustoms = append(configuredCustoms, p.Config.CustomChoices...) + } + // make sure no custom values are assigned that do not exist foundCustoms := map[string]struct{}{} for key, value := range p.Customs { - for _, choice := range p.Config.CustomChoices { + for _, choice := range configuredCustoms { if choice.Key == key { foundCustoms[key] = struct{}{} @@ -140,6 +156,8 @@ func (p *Prompts) validateArguments() error { if err != nil { return err } + + break } } } diff --git a/core/prompt_test.go b/core/prompt_test.go index 8650cc60..96659eb6 100644 --- a/core/prompt_test.go +++ b/core/prompt_test.go @@ -1,6 +1,7 @@ package core import ( + "bytes" "testing" "time" @@ -740,6 +741,50 @@ func TestSkipPromptForComponentIfSet(t *testing.T) { then.Equals(t, "skip component body", c.Body) } +func TestSkipPromptForPromptsWithCustomPromptsInKindConfig(t *testing.T) { + config := &Config{ + Kinds: []KindConfig{ + { + Key: "dependency", + AdditionalChoices: []Custom{ + { + Key: "name", + Type: CustomString, + }, + { + Key: "from", + Type: CustomString, + }, + { + Key: "to", + Type: CustomString, + }, + }, + SkipBody: true, + }, + }, + } + prompts := &Prompts{ + Config: config, + StdinReader: bytes.NewReader(nil), + TimeNow: specificTimeNow, + Kind: "dependency", + Customs: map[string]string{ + "name": "go", + "from": "1.20", + "to": "1.22", + }, + } + + changes, err := prompts.BuildChanges() + then.Nil(t, err) + + c := changes[0] + then.Equals(t, "go", c.Custom["name"]) + then.Equals(t, "1.20", c.Custom["from"]) + then.Equals(t, "1.22", c.Custom["to"]) +} + func TestSkipPromptForKindIfSet(t *testing.T) { reader, writer := then.WithReadWritePipe(t) then.DelayWrite(