diff --git a/api/badge.go b/api/badge.go new file mode 100644 index 0000000000000000000000000000000000000000..17d05b49ab13287d86b5ad5ba9a1a41f8d6b69c3 --- /dev/null +++ b/api/badge.go @@ -0,0 +1,85 @@ +package api + +import ( + "fmt" + "net/url" + + "github.com/xanzy/go-gitlab" +) + +func CreateOrUpdateBadge(client *gitlab.Client, projectID int, badgeName, badgeValue string) (*gitlab.ProjectBadge, error) { + // List existing badges + badges, _, err := client.ProjectBadges.ListProjectBadges(projectID, &gitlab.ListProjectBadgesOptions{}) + if err != nil { + return nil, fmt.Errorf("error listing badges: %v", err) + } + + // Check if badge exists + var existingBadge *gitlab.ProjectBadge + for _, badge := range badges { + if badge.Name == badgeName { + existingBadge = badge + break + } + } + + // Prepare badge data + imageURL := fmt.Sprintf("https://img.shields.io/badge/%s-%s-blue", url.PathEscape(badgeName), url.PathEscape(badgeValue)) + + var badge *gitlab.ProjectBadge + if existingBadge == nil { + badgeOptions := &gitlab.AddProjectBadgeOptions{ + Name: gitlab.Ptr(badgeName), + ImageURL: gitlab.Ptr(imageURL), + LinkURL: gitlab.Ptr(imageURL), + } + // Create new badge + badge, _, err = client.ProjectBadges.AddProjectBadge(projectID, badgeOptions) + if err != nil { + return nil, fmt.Errorf("error creating badge: %v", err) + } + } else { + badgeOptions := &gitlab.EditProjectBadgeOptions{ + Name: gitlab.Ptr(badgeName), + ImageURL: gitlab.Ptr(imageURL), + LinkURL: gitlab.Ptr(imageURL), + } + // Update existing badge + badge, _, err = client.ProjectBadges.EditProjectBadge(projectID, existingBadge.ID, badgeOptions) + if err != nil { + return nil, fmt.Errorf("error updating badge: %v", err) + } + } + + return badge, nil +} + +// create a func to delete a badget given the project id and badge name +func DeleteBadge(client *gitlab.Client, projectID int, badgeName string) error { + // List existing badges + badges, _, err := client.ProjectBadges.ListProjectBadges(projectID, &gitlab.ListProjectBadgesOptions{}) + if err != nil { + return fmt.Errorf("error listing badges: %v", err) + } + + // Find the badge with the given name + var badgeID int + for _, badge := range badges { + if badge.Name == badgeName { + badgeID = badge.ID + break + } + } + + if badgeID == 0 { + return fmt.Errorf("badge with name '%s' not found", badgeName) + } + + // Delete the badge + _, err = client.ProjectBadges.DeleteProjectBadge(projectID, badgeID) + if err != nil { + return fmt.Errorf("error deleting badge: %v", err) + } + + return nil +} diff --git a/commands/badge/badge.go b/commands/badge/badge.go new file mode 100644 index 0000000000000000000000000000000000000000..85707df2b70b3e5bca55c5cd28678daa872f952d --- /dev/null +++ b/commands/badge/badge.go @@ -0,0 +1,20 @@ +package badge + +import ( + "github.com/spf13/cobra" + "gitlab.com/gitlab-org/cli/commands/badge/remove" + "gitlab.com/gitlab-org/cli/commands/badge/set" + "gitlab.com/gitlab-org/cli/commands/cmdutils" +) + +func NewCmdBadge(f *cmdutils.Factory) *cobra.Command { + badgeCmd := &cobra.Command{ + Use: "badge", + Short: "Manage project badges", + } + + badgeCmd.AddCommand(set.NewCmdSet(f)) + badgeCmd.AddCommand(remove.NewCmdRemove(f)) + + return badgeCmd +} diff --git a/commands/badge/remove/remove.go b/commands/badge/remove/remove.go new file mode 100644 index 0000000000000000000000000000000000000000..d76668222bad9879db2a3c81a97f17dedb62a210 --- /dev/null +++ b/commands/badge/remove/remove.go @@ -0,0 +1,48 @@ +package remove + +import ( + "fmt" + + "github.com/spf13/cobra" + "gitlab.com/gitlab-org/cli/api" + "gitlab.com/gitlab-org/cli/commands/cmdutils" +) + +// create NewCmdRemove function that relies upon the DeleteBadge function +func NewCmdRemove(f *cmdutils.Factory) *cobra.Command { + badgeRemoveCmd := &cobra.Command{ + Use: "remove ", + Short: "Remove a badge from a project", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := f.HttpClient() + if err != nil { + return err + } + + projectID, err := cmd.Flags().GetInt("project-id") + if err != nil { + return err + } + + if projectID <= 0 { + return fmt.Errorf("error removing badge: --project-id is required") + } + + badgeName := args[0] + + err = api.DeleteBadge(apiClient, projectID, badgeName) + if err != nil { + return fmt.Errorf("error removing badge: %v", err) + } + + fmt.Fprintf(f.IO.StdOut, "Badge '%s' removed successfully\n", badgeName) + return nil + }, + } + + badgeRemoveCmd.Flags().Int("project-id", 0, "The ID of the project") + _ = badgeRemoveCmd.MarkFlagRequired("project-id") + + return badgeRemoveCmd +} diff --git a/commands/badge/set/set.go b/commands/badge/set/set.go new file mode 100644 index 0000000000000000000000000000000000000000..afcaa164b2b69783575ed1603ded90e2ab12bba6 --- /dev/null +++ b/commands/badge/set/set.go @@ -0,0 +1,63 @@ +package set + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/xanzy/go-gitlab" + "gitlab.com/gitlab-org/cli/api" + "gitlab.com/gitlab-org/cli/commands/cmdutils" + "gitlab.com/gitlab-org/cli/internal/glrepo" + "gitlab.com/gitlab-org/cli/pkg/iostreams" +) + +type BadgeOptions struct { + ProjectID int + APIClient *gitlab.Client + + IO *iostreams.IOStreams + Repo glrepo.Interface +} + +func NewCmdSet(f *cmdutils.Factory) *cobra.Command { + badgeSetCmd := &cobra.Command{ + Use: "set ", + Short: "Set a badge for a project", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := f.HttpClient() + if err != nil { + return err + } + + opts := &BadgeOptions{} + + // Set the config file + if s, _ := cmd.Flags().GetInt("project-id"); s > 0 { + opts.ProjectID = s + } else { + return fmt.Errorf("error setting badge without --project-id") + } + + badgeName := args[0] + badgeValue := args[1] + + badge, err := api.CreateOrUpdateBadge(apiClient, opts.ProjectID, badgeName, badgeValue) + if err != nil { + return fmt.Errorf("error setting badge: %v", err) + } + + if badge != nil { + fmt.Fprintf(f.IO.StdOut, "Badge '%s' set successfully with value '%s'\n", badgeName, badgeValue) + } + + return nil + }, + } + + // changelogGenerateCmd.Flags().StringP("config-file", "", "", "Path of the changelog configuration file in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'.") + // add a flag for project-id + badgeSetCmd.Flags().Int("project-id", 0, "The ID of the project") + + return badgeSetCmd +} diff --git a/commands/badge/set/set_test.go b/commands/badge/set/set_test.go new file mode 100644 index 0000000000000000000000000000000000000000..05e26e380402689da67100f2329fb8964048053e --- /dev/null +++ b/commands/badge/set/set_test.go @@ -0,0 +1 @@ +package set diff --git a/commands/root.go b/commands/root.go index 9917f6b70fcf44bf31423f4048fd38de5d5a6299..a5aa0cf5cbd615a88e04078f7ca71ebbc902443b 100644 --- a/commands/root.go +++ b/commands/root.go @@ -9,6 +9,7 @@ import ( aliasCmd "gitlab.com/gitlab-org/cli/commands/alias" apiCmd "gitlab.com/gitlab-org/cli/commands/api" authCmd "gitlab.com/gitlab-org/cli/commands/auth" + badgeCmd "gitlab.com/gitlab-org/cli/commands/badge" changelogCmd "gitlab.com/gitlab-org/cli/commands/changelog" pipelineCmd "gitlab.com/gitlab-org/cli/commands/ci" clusterCmd "gitlab.com/gitlab-org/cli/commands/cluster" @@ -105,6 +106,7 @@ func NewCmdRoot(f *cmdutils.Factory, version, buildDate string) *cobra.Command { // Child commands rootCmd.AddCommand(aliasCmd.NewCmdAlias(f)) + rootCmd.AddCommand(badgeCmd.NewCmdBadge(f)) rootCmd.AddCommand(configCmd.NewCmdConfig(f)) rootCmd.AddCommand(completionCmd.NewCmdCompletion(f.IO)) rootCmd.AddCommand(versionCmd.NewCmdVersion(f.IO, version, buildDate)) diff --git a/docs/source/badge/help.md b/docs/source/badge/help.md new file mode 100644 index 0000000000000000000000000000000000000000..2438b6869310a6e9759c43e4eda81725c00dc992 --- /dev/null +++ b/docs/source/badge/help.md @@ -0,0 +1,24 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab badge help` + +Help about any command + +```plaintext +glab badge help [command] [flags] +``` + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +``` diff --git a/docs/source/badge/index.md b/docs/source/badge/index.md new file mode 100644 index 0000000000000000000000000000000000000000..51fb3e73b6af742be1516e7c5c994900dfb24784 --- /dev/null +++ b/docs/source/badge/index.md @@ -0,0 +1,25 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab badge` + +Manage project badges + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +``` + +## Subcommands + +- [`remove`](remove.md) +- [`set`](set.md) diff --git a/docs/source/badge/remove.md b/docs/source/badge/remove.md new file mode 100644 index 0000000000000000000000000000000000000000..50c7a30a156548bc0621c84cebaece212f23360f --- /dev/null +++ b/docs/source/badge/remove.md @@ -0,0 +1,30 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab badge remove` + +Remove a badge from a project + +```plaintext +glab badge remove [flags] +``` + +## Options + +```plaintext + --project-id int The ID of the project +``` + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +``` diff --git a/docs/source/badge/set.md b/docs/source/badge/set.md new file mode 100644 index 0000000000000000000000000000000000000000..faca067cc992f962aebc9d5e86195c76d8400742 --- /dev/null +++ b/docs/source/badge/set.md @@ -0,0 +1,30 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab badge set` + +Set a badge for a project + +```plaintext +glab badge set [flags] +``` + +## Options + +```plaintext + --project-id int The ID of the project +``` + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +```