From 550c27a25fd6759b54a44084a770e6007ab3e7bf Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 29 Mar 2023 17:03:12 -0400 Subject: [PATCH] feat(backend,ui): add repo project name --- server/backend/file/file.go | 23 +++++++++++++++++++++ server/backend/file/repo.go | 12 +++++++++-- server/backend/repo.go | 6 ++++++ server/cmd/cmd.go | 1 + server/cmd/project_name.go | 40 +++++++++++++++++++++++++++++++++++++ ui/pages/repo/repo.go | 6 +++++- ui/pages/selection/item.go | 7 ++++++- 7 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 server/cmd/project_name.go diff --git a/server/backend/file/file.go b/server/backend/file/file.go index 9f855db570573db36b0b313e8ce6addf49d877a6..dfb80526172c31df5976ab7838b0098261765e04 100644 --- a/server/backend/file/file.go +++ b/server/backend/file/file.go @@ -49,6 +49,7 @@ const ( description = "description" exportOk = "git-daemon-export-ok" private = "private" + projectName = "project-name" settings = "settings" ) @@ -573,6 +574,23 @@ func (fb *FileBackend) SetPrivate(repo string, priv bool) error { return nil } +// ProjectName returns the project name. +// +// It implements backend.Backend. +func (fb *FileBackend) ProjectName(repo string) string { + repo = utils.SanitizeRepo(repo) + ".git" + r := &Repo{path: filepath.Join(fb.reposPath(), repo), root: fb.reposPath()} + return r.ProjectName() +} + +// SetProjectName sets the project name of the given repo. +// +// It implements backend.Backend. +func (fb *FileBackend) SetProjectName(repo string, name string) error { + repo = utils.SanitizeRepo(repo) + ".git" + return os.WriteFile(filepath.Join(fb.reposPath(), repo, projectName), []byte(name), 0600) +} + // CreateRepository creates a new repository. // // Created repositories are always bare. @@ -607,6 +625,11 @@ func (fb *FileBackend) CreateRepository(repo string, private bool) (backend.Repo return nil, err } + if err := fb.SetProjectName(repo, name); err != nil { + logger.Debug("failed to set project name", "err", err) + return nil, err + } + r := &Repo{path: rp, root: fb.reposPath()} // Add to cache. fb.repos[name] = r diff --git a/server/backend/file/repo.go b/server/backend/file/repo.go index 6e760d4295ea089d1951192ca369c1484e70038c..3888201045f5a16b39f85a373b2adfec9a46a452 100644 --- a/server/backend/file/repo.go +++ b/server/backend/file/repo.go @@ -27,14 +27,22 @@ func (r *Repo) Name() string { return strings.TrimPrefix(name, "/") } +// ProjectName returns the repository's project name. +func (r *Repo) ProjectName() string { + pn, err := readOneLine(filepath.Join(r.path, projectName)) + if err != nil { + return "" + } + + return strings.TrimSpace(pn) +} + // Description returns the repository's description. // // It implements backend.Repository. func (r *Repo) Description() string { desc, err := readAll(filepath.Join(r.path, description)) if err != nil { - logger.Debug("failed to read description file", "err", err, - "path", filepath.Join(r.path, description)) return "" } diff --git a/server/backend/repo.go b/server/backend/repo.go index 05d2de240656cca7749dcec0afb5bdd5d4bfd8e8..9fcad1c45516d21201e65021877635f82c6320b8 100644 --- a/server/backend/repo.go +++ b/server/backend/repo.go @@ -21,6 +21,10 @@ type RepositoryStore interface { // RepositoryMetadata is an interface for managing repository metadata. type RepositoryMetadata interface { + // ProjectName returns the repository's project name. + ProjectName(repo string) string + // SetProjectName sets the repository's project name. + SetProjectName(repo, name string) error // Description returns the repository's description. Description(repo string) string // SetDescription sets the repository's description. @@ -57,6 +61,8 @@ type RepositoryAccess interface { type Repository interface { // Name returns the repository's name. Name() string + // ProjectName returns the repository's project name. + ProjectName() string // Description returns the repository's description. Description() string // IsPrivate returns whether the repository is private. diff --git a/server/cmd/cmd.go b/server/cmd/cmd.go index 461a9041f126e3526dfb0fed2f5f7bce7cc0d914..f6fcdb13164b478c9488d1f9b46a5104bacd43bf 100644 --- a/server/cmd/cmd.go +++ b/server/cmd/cmd.go @@ -64,6 +64,7 @@ func rootCommand() *cobra.Command { hookCommand(), listCommand(), privateCommand(), + projectName(), renameCommand(), settingCommand(), tagCommand(), diff --git a/server/cmd/project_name.go b/server/cmd/project_name.go new file mode 100644 index 0000000000000000000000000000000000000000..68ca47c50bd0e06f61b67d4d2b64e330f7ce2e97 --- /dev/null +++ b/server/cmd/project_name.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "strings" + + "github.com/spf13/cobra" +) + +func projectName() *cobra.Command { + cmd := &cobra.Command{ + Use: "project-name REPOSITORY [NAME]", + Aliases: []string{"project"}, + Short: "Set or get the project name for a repository", + Args: cobra.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cfg, _ := fromContext(cmd) + rn := strings.TrimSuffix(args[0], ".git") + switch len(args) { + case 1: + if err := checkIfReadable(cmd, args); err != nil { + return err + } + + pn := cfg.Backend.ProjectName(rn) + cmd.Println(pn) + default: + if err := checkIfCollab(cmd, args); err != nil { + return err + } + if err := cfg.Backend.SetProjectName(rn, strings.Join(args[1:], " ")); err != nil { + return err + } + } + + return nil + }, + } + + return cmd +} diff --git a/ui/pages/repo/repo.go b/ui/pages/repo/repo.go index 75f3ac38ad302cc3af82ef9633141fe11479ffbb..ff94c890d955ada5b2fd679619d5c0764db72c0a 100644 --- a/ui/pages/repo/repo.go +++ b/ui/pages/repo/repo.go @@ -327,7 +327,11 @@ func (r *Repo) headerView() string { return "" } truncate := lipgloss.NewStyle().MaxWidth(r.common.Width) - name := r.common.Styles.Repo.HeaderName.Render(r.selectedRepo.Name()) + name := r.selectedRepo.ProjectName() + if name == "" { + name = r.selectedRepo.Name() + } + name = r.common.Styles.Repo.HeaderName.Render(name) desc := r.selectedRepo.Description() if desc == "" { desc = name diff --git a/ui/pages/selection/item.go b/ui/pages/selection/item.go index 83bf3e6c3cdb17f60d1580de113059ea1c15f078..79c5b634622e9f5d016eb7175d4f11639cf4323e 100644 --- a/ui/pages/selection/item.go +++ b/ui/pages/selection/item.go @@ -79,7 +79,12 @@ func (i Item) ID() string { // Title returns the item title. Implements list.DefaultItem. func (i Item) Title() string { - return i.repo.Name() + name := i.repo.ProjectName() + if name == "" { + name = i.repo.Name() + } + + return name } // Description returns the item description. Implements list.DefaultItem.