From 0232841936355090a7cabb2b5619ac1cbc14563c Mon Sep 17 00:00:00 2001 From: Viktor Nagy Date: Sat, 29 Jun 2024 15:06:12 +0200 Subject: [PATCH] Use a custom flag for visibility validation Signed-off-by: Viktor Nagy --- cmd/flux/bootstrap_gitlab.go | 18 ++--------- internal/flags/gitlab_visibility.go | 41 ++++++++++++++++++++++++ internal/flags/gitlab_visibility_test.go | 31 ++++++++++++++++++ 3 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 internal/flags/gitlab_visibility.go create mode 100644 internal/flags/gitlab_visibility_test.go diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index 5403d7b0e1..667314534d 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -86,7 +86,7 @@ type gitlabFlags struct { repository string interval time.Duration personal bool - visibility string + visibility flags.GitLabVisibility private bool hostname string path flags.SafeRelativePath @@ -105,7 +105,7 @@ func init() { bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.personal, "personal", false, "if true, the owner is assumed to be a GitLab user; otherwise a group") bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.private, "private", true, "if true, the repository is setup or configured as private") bootstrapGitLabCmd.Flags().MarkDeprecated("private", "use --visibility instead") - bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.visibility, "visibility", glDefaultVisibility, "specifies the visibility of the repository. Valid values are public, private, internal") + bootstrapGitLabCmd.Flags().Var(&gitlabArgs.visibility, "visibility", "specifies the visibility of the repository. Valid values are public, private, internal") bootstrapGitLabCmd.Flags().DurationVar(&gitlabArgs.interval, "interval", time.Minute, "sync interval") bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.hostname, "hostname", glDefaultDomain, "GitLab hostname") bootstrapGitLabCmd.Flags().Var(&gitlabArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") @@ -141,9 +141,6 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { gitlabArgs.visibility = "public" fmt.Println("Using visibility public as --private=false") } - if visibilityValid, err := isValidVisibility(gitlabArgs.visibility); !visibilityValid || err != nil { - return fmt.Errorf("Invalid value (%s) for visibility. Valid values are public, private, internal", gitlabArgs.visibility) - } if err := bootstrapValidate(); err != nil { return err @@ -294,7 +291,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // Bootstrap config bootstrapOpts := []bootstrap.GitProviderOption{ bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal), - bootstrap.WithProviderVisibility(gitlabArgs.visibility), + bootstrap.WithProviderVisibility(gitlabArgs.visibility.String()), bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithBootstrapTransportType("https"), bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), @@ -327,12 +324,3 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // Run return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout) } - -func isValidVisibility(visibility string) (valid bool, err error) { - switch visibility { - case "private", "public", "internal": - return true, nil - default: - return false, fmt.Errorf("invalid visibility") - } -} diff --git a/internal/flags/gitlab_visibility.go b/internal/flags/gitlab_visibility.go new file mode 100644 index 0000000000..b5b0d98adb --- /dev/null +++ b/internal/flags/gitlab_visibility.go @@ -0,0 +1,41 @@ +package flags + +import ( + "fmt" + "strings" + + "github.com/fluxcd/flux2/v2/internal/utils" +) + +var supportedGitLabVisibilities = []string{ + "public", + "internal", + "private", +} + +type GitLabVisibility string + +func (d *GitLabVisibility) String() string { + return string(*d) +} + +func (d *GitLabVisibility) Set(str string) error { + if strings.TrimSpace(str) == "" { + str = "private" + } + if !utils.ContainsItemString(supportedGitLabVisibilities, str) { + return fmt.Errorf("unsupported visibility '%s', must be one of: %s", + str, strings.Join(supportedGitLabVisibilities, ", ")) + + } + *d = GitLabVisibility(str) + return nil +} + +func (d *GitLabVisibility) Type() string { + return "GitLabVisibility" +} + +func (d *GitLabVisibility) Description() string { + return fmt.Sprintf("visibility, available options are: (%s)", strings.Join(supportedGitLabVisibilities, ", ")) +} diff --git a/internal/flags/gitlab_visibility_test.go b/internal/flags/gitlab_visibility_test.go new file mode 100644 index 0000000000..8635eb30f4 --- /dev/null +++ b/internal/flags/gitlab_visibility_test.go @@ -0,0 +1,31 @@ +package flags + +import ( + "testing" +) + +func TestGitLabVisibility_Set(t *testing.T) { + tests := []struct { + name string + str string + expect string + expectErr bool + }{ + {"private", "private", "private", false}, + {"internal", "internal", "internal", false}, + {"public", "public", "public", false}, + {"unsupported", "unsupported", "", true}, + {"default", "", "private", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var p GitLabVisibility + if err := p.Set(tt.str); (err != nil) != tt.expectErr { + t.Errorf("Set() error = %v, expectErr %v", err, tt.expectErr) + } + if str := p.String(); str != tt.expect { + t.Errorf("Set() = %v, expect %v", str, tt.expect) + } + }) + } +}