43ff02cc63a23c2935a978fc9b2c349d109124a0

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

feat(backend): hide repository from ui

Diff

  1diff --git a/server/backend/repo.go b/server/backend/repo.go
  2index 2f72164e9e27d50f5d1e063db30d06be4d3f62b0..ddc4c934b3aff06887f8fb2a1e1cbd2a3875fd95 100644
  3--- a/server/backend/repo.go
  4+++ b/server/backend/repo.go
  5@@ -10,6 +10,7 @@ type RepositoryOptions struct {
  6 	Description string
  7 	ProjectName string
  8 	Mirror      bool
  9+	Hidden      bool
 10 }
 11 
 12 // RepositoryStore is an interface for managing repositories.
 13@@ -46,6 +47,10 @@ type RepositoryMetadata interface {
 14 	SetPrivate(repo string, private bool) error
 15 	// IsMirror returns whether the repository is a mirror.
 16 	IsMirror(repo string) bool
 17+	// IsHidden returns whether the repository is hidden.
 18+	IsHidden(repo string) bool
 19+	// SetHidden sets whether the repository is hidden.
 20+	SetHidden(repo string, hidden bool) error
 21 }
 22 
 23 // RepositoryAccess is an interface for managing repository access.
 24@@ -71,6 +76,8 @@ type Repository interface {
 25 	IsPrivate() bool
 26 	// IsMirror returns whether the repository is a mirror.
 27 	IsMirror() bool
 28+	// IsHidden returns whether the repository is hidden.
 29+	IsHidden() bool
 30 	// Open returns the underlying git.Repository.
 31 	Open() (*git.Repository, error)
 32 }
 33diff --git a/server/backend/sqlite/repo.go b/server/backend/sqlite/repo.go
 34index bdd4384e714d17d6b528147c342b9cda54fccf29..9259f8bea5b063085fd8ea76c30ca3364c41de74 100644
 35--- a/server/backend/sqlite/repo.go
 36+++ b/server/backend/sqlite/repo.go
 37@@ -86,3 +86,17 @@ func (r *Repo) ProjectName() string {
 38 
 39 	return name
 40 }
 41+
 42+// IsHidden returns whether the repository is hidden.
 43+//
 44+// It implements backend.Repository.
 45+func (r *Repo) IsHidden() bool {
 46+	var hidden bool
 47+	if err := wrapTx(r.db, context.Background(), func(tx *sqlx.Tx) error {
 48+		return tx.Get(&hidden, "SELECT hidden FROM repo WHERE name = ?", r.name)
 49+	}); err != nil {
 50+		return false
 51+	}
 52+
 53+	return hidden
 54+}
 55diff --git a/server/backend/sqlite/sql.go b/server/backend/sqlite/sql.go
 56index 8158cac5ae65dda25092946025cb282bb487fc37..719c0707711133ded792eb02d6c1f807311cbbcd 100644
 57--- a/server/backend/sqlite/sql.go
 58+++ b/server/backend/sqlite/sql.go
 59@@ -37,6 +37,7 @@ var (
 60 		description TEXT NOT NULL,
 61 		private BOOLEAN NOT NULL,
 62 		mirror BOOLEAN NOT NULL,
 63+		hidden BOOLEAN NOT NULL,
 64 		created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
 65 		updated_at DATETIME NOT NULL
 66 	);`
 67diff --git a/server/backend/sqlite/sqlite.go b/server/backend/sqlite/sqlite.go
 68index 158993db2e5dd37fd8859e6b6bd657fe8ff8b0bb..2dd6bd39d7d840c6849675daf3d49dceed8e3a05 100644
 69--- a/server/backend/sqlite/sqlite.go
 70+++ b/server/backend/sqlite/sqlite.go
 71@@ -133,9 +133,9 @@ func (d *SqliteBackend) CreateRepository(name string, opts backend.RepositoryOpt
 72 	}
 73 
 74 	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
 75-		_, err := tx.Exec(`INSERT INTO repo (name, project_name, description, private, mirror, updated_at)
 76+		_, err := tx.Exec(`INSERT INTO repo (name, project_name, description, private, mirror, hidden, updated_at)
 77 			VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP);`,
 78-			name, opts.ProjectName, opts.Description, opts.Private, opts.Mirror)
 79+			name, opts.ProjectName, opts.Description, opts.Private, opts.Mirror, opts.Hidden)
 80 		return err
 81 	}); err != nil {
 82 		logger.Debug("failed to create repository in database", "err", err)
 83@@ -324,6 +324,32 @@ func (d *SqliteBackend) IsPrivate(repo string) bool {
 84 	return private
 85 }
 86 
 87+// IsHidden returns true if the repository is hidden.
 88+//
 89+// It implements backend.Backend.
 90+func (d *SqliteBackend) IsHidden(repo string) bool {
 91+	repo = utils.SanitizeRepo(repo)
 92+	var hidden bool
 93+	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
 94+		return tx.Get(&hidden, "SELECT hidden FROM repo WHERE name = ?", repo)
 95+	}); err != nil {
 96+		return false
 97+	}
 98+
 99+	return hidden
100+}
101+
102+// SetHidden sets the hidden flag of a repository.
103+//
104+// It implements backend.Backend.
105+func (d *SqliteBackend) SetHidden(repo string, hidden bool) error {
106+	repo = utils.SanitizeRepo(repo)
107+	return wrapDbErr(wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
108+		_, err := tx.Exec("UPDATE repo SET hidden = ?, updated_at = CURRENT_TIMESTAMP WHERE name = ?;", hidden, repo)
109+		return err
110+	}))
111+}
112+
113 // ProjectName returns the project name of a repository.
114 //
115 // It implements backend.Backend.
116diff --git a/server/cmd/hidden.go b/server/cmd/hidden.go
117new file mode 100644
118index 0000000000000000000000000000000000000000..7146579b36262771b56bf618857b8478932c48c9
119--- /dev/null
120+++ b/server/cmd/hidden.go
121@@ -0,0 +1,37 @@
122+package cmd
123+
124+import "github.com/spf13/cobra"
125+
126+func hiddenCommand() *cobra.Command {
127+	cmd := &cobra.Command{
128+		Use:   "hidden REPOSITORY [TRUE|FALSE]",
129+		Short: "Hide or unhide a repository",
130+		Args:  cobra.MinimumNArgs(1),
131+		RunE: func(cmd *cobra.Command, args []string) error {
132+			cfg, _ := fromContext(cmd)
133+			repo := args[0]
134+			switch len(args) {
135+			case 1:
136+				if err := checkIfReadable(cmd, args); err != nil {
137+					return err
138+				}
139+
140+				hidden := cfg.Backend.IsHidden(repo)
141+				cmd.Println(hidden)
142+			case 2:
143+				if err := checkIfCollab(cmd, args); err != nil {
144+					return err
145+				}
146+
147+				hidden := args[1] == "true"
148+				if err := cfg.Backend.SetHidden(repo, hidden); err != nil {
149+					return err
150+				}
151+			}
152+
153+			return nil
154+		},
155+	}
156+
157+	return cmd
158+}
159diff --git a/server/cmd/repo.go b/server/cmd/repo.go
160index 577ab30304ed4092d0e1a035bda06c713fec42b4..a4c60d680e6444a1104d789b2d345442d4c74265 100644
161--- a/server/cmd/repo.go
162+++ b/server/cmd/repo.go
163@@ -16,6 +16,7 @@ func repoCommand() *cobra.Command {
164 		createCommand(),
165 		deleteCommand(),
166 		descriptionCommand(),
167+		hiddenCommand(),
168 		importCommand(),
169 		listCommand(),
170 		privateCommand(),
171diff --git a/ui/pages/selection/selection.go b/ui/pages/selection/selection.go
172index 97e47ff9708d67612a754dcc9a7735b03f5576a1..4e0056edad21c674e56baf4358a3edc5c177512a 100644
173--- a/ui/pages/selection/selection.go
174+++ b/ui/pages/selection/selection.go
175@@ -198,6 +198,9 @@ func (s *Selection) Init() tea.Cmd {
176 	}
177 	sortedItems := make(Items, 0)
178 	for _, r := range repos {
179+		if r.IsHidden() {
180+			continue
181+		}
182 		al := cfg.Backend.AccessLevelByPublicKey(r.Name(), pk)
183 		if al >= backend.ReadOnlyAccess {
184 			item, err := NewItem(r, cfg)