diff --git a/cmd/harbor/root/repository/cmd.go b/cmd/harbor/root/repository/cmd.go index d8ba21561..9bb69aac6 100644 --- a/cmd/harbor/root/repository/cmd.go +++ b/cmd/harbor/root/repository/cmd.go @@ -26,6 +26,7 @@ func Repository() *cobra.Command { RepoViewCmd(), RepoDeleteCmd(), SearchRepoCmd(), + UpdateRepositoryCommand(), ) return cmd diff --git a/cmd/harbor/root/repository/update.go b/cmd/harbor/root/repository/update.go index e7e70c631..94eb327fc 100644 --- a/cmd/harbor/root/repository/update.go +++ b/cmd/harbor/root/repository/update.go @@ -12,3 +12,78 @@ // See the License for the specific language governing permissions and // limitations under the License. package repository + +import ( + "fmt" + + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/goharbor/harbor-cli/pkg/prompt" + "github.com/goharbor/harbor-cli/pkg/utils" + "github.com/goharbor/harbor-cli/pkg/views/repository/update" + "github.com/spf13/cobra" +) + +func UpdateRepositoryCommand() *cobra.Command { + var description string + + cmd := &cobra.Command{ + Use: "update", + Short: "Update a repository", + Long: `Update the description of a repository. + +This command updates the description associated with a repository +within a Harbor project. + +Examples: + # Update repository description using project/repository format + harbor repository update library/nginx --description "Official nginx image"`, + RunE: func(cmd *cobra.Command, args []string) error { + var err error + var projectName string + var repoName string + + if len(args) > 0 { + projectName, repoName, err = utils.ParseProjectRepo(args[0]) + if err != nil { + return fmt.Errorf("failed to parse project/repo: %w", err) + } + } else { + projectName, err = prompt.GetProjectNameFromUser() + if err != nil { + return fmt.Errorf("failed to get project name: %w", err) + } + repoName = prompt.GetRepoNameFromUser(projectName) + } + + existingRepo, err := api.RepoView(projectName, repoName) + if err != nil { + return fmt.Errorf("failed to get existing repository: %w", err) + } + + if cmd.Flags().Changed("description") { + err = api.UpdateRepository(projectName, repoName, description, existingRepo.Payload) + if err != nil { + return fmt.Errorf("failed to update repository: %w", err) + } + } else { + updatedDescription, err := update.UpdateRepositoryView(existingRepo.Payload) + if err != nil { + return fmt.Errorf("update cancelled or failed: %w", err) + } + + err = api.UpdateRepository(projectName, repoName, updatedDescription, existingRepo.Payload) + if err != nil { + return fmt.Errorf("failed to update repository: %w", err) + } + } + + fmt.Printf("Repository %s/%s updated successfully\n", projectName, repoName) + return nil + }, + } + + flags := cmd.Flags() + flags.StringVarP(&description, "description", "d", "", "Repository description") + + return cmd +} diff --git a/doc/cli-docs/harbor-repo-update.md b/doc/cli-docs/harbor-repo-update.md new file mode 100644 index 000000000..890154daf --- /dev/null +++ b/doc/cli-docs/harbor-repo-update.md @@ -0,0 +1,44 @@ +--- +title: harbor repo update +weight: 55 +--- +## harbor repo update + +### Description + +##### Update a repository + +### Synopsis + +Update the description of a repository. + +This command updates the description associated with a repository +within a Harbor project. + +Examples: + # Update repository description using project/repository format + harbor repository update library/nginx --description "Official nginx image" + +```sh +harbor repo update [flags] +``` + +### Options + +```sh + -d, --description string Repository description + -h, --help help for update +``` + +### Options inherited from parent commands + +```sh + -c, --config string config file (default is $HOME/.config/harbor-cli/config.yaml) + -o, --output-format string Output format. One of: json|yaml + -v, --verbose verbose output +``` + +### SEE ALSO + +* [harbor repo](harbor-repo.md) - Manage repositories + diff --git a/doc/cli-docs/harbor-repo.md b/doc/cli-docs/harbor-repo.md index 0307c2fd4..16ac1ae35 100644 --- a/doc/cli-docs/harbor-repo.md +++ b/doc/cli-docs/harbor-repo.md @@ -32,5 +32,6 @@ Manage repositories in Harbor context * [harbor repo delete](harbor-repo-delete.md) - Delete a repository * [harbor repo list](harbor-repo-list.md) - list repositories within a project * [harbor repo search](harbor-repo-search.md) - search repository based on their names +* [harbor repo update](harbor-repo-update.md) - Update a repository * [harbor repo view](harbor-repo-view.md) - Get repository information diff --git a/doc/man-docs/man1/harbor-repo-update.1 b/doc/man-docs/man1/harbor-repo-update.1 new file mode 100644 index 000000000..ebbef5b9e --- /dev/null +++ b/doc/man-docs/man1/harbor-repo-update.1 @@ -0,0 +1,48 @@ +.nh +.TH "HARBOR" "1" "Harbor Community" "Harbor User Manuals" + +.SH NAME +harbor-repo-update - Update a repository + + +.SH SYNOPSIS +\fBharbor repo update [flags]\fP + + +.SH DESCRIPTION +Update the description of a repository. + +.PP +This command updates the description associated with a repository +within a Harbor project. + +.PP +Examples: + # Update repository description using project/repository format + harbor repository update library/nginx --description "Official nginx image" + + +.SH OPTIONS +\fB-d\fP, \fB--description\fP="" + Repository description + +.PP +\fB-h\fP, \fB--help\fP[=false] + help for update + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +\fB-c\fP, \fB--config\fP="" + config file (default is $HOME/.config/harbor-cli/config.yaml) + +.PP +\fB-o\fP, \fB--output-format\fP="" + Output format. One of: json|yaml + +.PP +\fB-v\fP, \fB--verbose\fP[=false] + verbose output + + +.SH SEE ALSO +\fBharbor-repo(1)\fP \ No newline at end of file diff --git a/doc/man-docs/man1/harbor-repo.1 b/doc/man-docs/man1/harbor-repo.1 index 681925e25..174b7a050 100644 --- a/doc/man-docs/man1/harbor-repo.1 +++ b/doc/man-docs/man1/harbor-repo.1 @@ -32,4 +32,4 @@ Manage repositories in Harbor context .SH SEE ALSO -\fBharbor(1)\fP, \fBharbor-repo-delete(1)\fP, \fBharbor-repo-list(1)\fP, \fBharbor-repo-search(1)\fP, \fBharbor-repo-view(1)\fP \ No newline at end of file +\fBharbor(1)\fP, \fBharbor-repo-delete(1)\fP, \fBharbor-repo-list(1)\fP, \fBharbor-repo-search(1)\fP, \fBharbor-repo-update(1)\fP, \fBharbor-repo-view(1)\fP \ No newline at end of file diff --git a/pkg/api/repository_handler.go b/pkg/api/repository_handler.go index f8fb3c203..c8b64ea84 100644 --- a/pkg/api/repository_handler.go +++ b/pkg/api/repository_handler.go @@ -16,6 +16,7 @@ package api import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/repository" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/search" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) @@ -107,3 +108,32 @@ func SearchRepository(query string) (search.SearchOK, error) { return *response, nil } + +func UpdateRepository(projectName, repoName string, description string, existingRepo *models.Repository) error { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return err + } + + repo := &models.Repository{ + ID: existingRepo.ID, + Name: existingRepo.Name, + ProjectID: existingRepo.ProjectID, + Description: description, + ArtifactCount: existingRepo.ArtifactCount, + PullCount: existingRepo.PullCount, + CreationTime: existingRepo.CreationTime, + UpdateTime: existingRepo.UpdateTime, + } + + _, err = client.Repository.UpdateRepository(ctx, &repository.UpdateRepositoryParams{ + ProjectName: projectName, + RepositoryName: repoName, + Repository: repo, + }) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/views/repository/update/view.go b/pkg/views/repository/update/view.go new file mode 100644 index 000000000..c9cd35afd --- /dev/null +++ b/pkg/views/repository/update/view.go @@ -0,0 +1,47 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package update + +import ( + "github.com/charmbracelet/huh" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" +) + +func UpdateRepositoryView(repo *models.Repository) (string, error) { + var description string + + if repo.Description != "" { + description = repo.Description + } + + theme := huh.ThemeCharm() + + form := huh.NewForm( + huh.NewGroup( + huh.NewText(). + Title("Repository Description"). + Description("Update the description for " + repo.Name). + Value(&description). + Placeholder("Enter repository description..."), + ), + ).WithTheme(theme) + + err := form.Run() + if err != nil { + return "", err + } + + return description, nil +}