mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-09-07 07:03:21 +00:00
This implements "repository flags", a way for instance administrators to
assign custom flags to repositories. The idea is that custom templates
can look at these flags, and display banners based on them, Forgejo does
not provide anything built on top of it, just the foundation. The
feature is optional, and disabled by default. To enable it, set
`[repository].ENABLE_FLAGS = true`.
On the UI side, instance administrators will see a new "Manage flags"
tab on repositories, and a list of enabled tags (if any) on the
repository home page. The "Manage flags" page allows them to remove
existing flags, or add any new ones that are listed in
`[repository].SETTABLE_FLAGS`.
The model does not enforce that only the `SETTABLE_FLAGS` are present.
If the setting is changed, old flags may remain present in the database,
and anything that uses them, will still work. The repository flag
management page will allow an instance administrator to remove them, but
not set them, once removed.
Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
(cherry picked from commit ba735ce222
)
102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repo
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.gitea.io/gitea/models/db"
|
|
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
// RepoFlag represents a single flag against a repository
|
|
type RepoFlag struct { //revive:disable-line:exported
|
|
ID int64 `xorm:"pk autoincr"`
|
|
RepoID int64 `xorm:"UNIQUE(s) INDEX"`
|
|
Name string `xorm:"UNIQUE(s) INDEX"`
|
|
}
|
|
|
|
func init() {
|
|
db.RegisterModel(new(RepoFlag))
|
|
}
|
|
|
|
// TableName provides the real table name
|
|
func (RepoFlag) TableName() string {
|
|
return "forgejo_repo_flag"
|
|
}
|
|
|
|
// ListFlags returns the array of flags on the repo.
|
|
func (repo *Repository) ListFlags(ctx context.Context) ([]RepoFlag, error) {
|
|
var flags []RepoFlag
|
|
err := db.GetEngine(ctx).Table(&RepoFlag{}).Where("repo_id = ?", repo.ID).Find(&flags)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return flags, nil
|
|
}
|
|
|
|
// IsFlagged returns whether a repo has any flags or not
|
|
func (repo *Repository) IsFlagged(ctx context.Context) bool {
|
|
has, _ := db.Exist[RepoFlag](ctx, builder.Eq{"repo_id": repo.ID})
|
|
return has
|
|
}
|
|
|
|
// GetFlag returns a single RepoFlag based on its name
|
|
func (repo *Repository) GetFlag(ctx context.Context, flagName string) (bool, *RepoFlag, error) {
|
|
flag, has, err := db.Get[RepoFlag](ctx, builder.Eq{"repo_id": repo.ID, "name": flagName})
|
|
if err != nil {
|
|
return false, nil, err
|
|
}
|
|
return has, flag, nil
|
|
}
|
|
|
|
// HasFlag returns true if a repo has a given flag, false otherwise
|
|
func (repo *Repository) HasFlag(ctx context.Context, flagName string) bool {
|
|
has, _ := db.Exist[RepoFlag](ctx, builder.Eq{"repo_id": repo.ID, "name": flagName})
|
|
return has
|
|
}
|
|
|
|
// AddFlag adds a new flag to the repo
|
|
func (repo *Repository) AddFlag(ctx context.Context, flagName string) error {
|
|
return db.Insert(ctx, RepoFlag{
|
|
RepoID: repo.ID,
|
|
Name: flagName,
|
|
})
|
|
}
|
|
|
|
// DeleteFlag removes a flag from the repo
|
|
func (repo *Repository) DeleteFlag(ctx context.Context, flagName string) (int64, error) {
|
|
return db.DeleteByBean(ctx, &RepoFlag{RepoID: repo.ID, Name: flagName})
|
|
}
|
|
|
|
// ReplaceAllFlags replaces all flags of a repo with a new set
|
|
func (repo *Repository) ReplaceAllFlags(ctx context.Context, flagNames []string) error {
|
|
ctx, committer, err := db.TxContext(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer committer.Close()
|
|
|
|
if err := db.DeleteBeans(ctx, &RepoFlag{RepoID: repo.ID}); err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(flagNames) == 0 {
|
|
return committer.Commit()
|
|
}
|
|
|
|
var flags []RepoFlag
|
|
for _, name := range flagNames {
|
|
flags = append(flags, RepoFlag{
|
|
RepoID: repo.ID,
|
|
Name: name,
|
|
})
|
|
}
|
|
if err := db.Insert(ctx, &flags); err != nil {
|
|
return err
|
|
}
|
|
|
|
return committer.Commit()
|
|
}
|