diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2023-01-20 19:42:33 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-20 19:42:33 +0800 |
commit | 6fe3c8b3980f850c9789f9fa62bdfee7b2708ff0 (patch) | |
tree | 5e11864dd63c60564080506291ca93e465c19940 /models/project | |
parent | 0c048e554ba42d99bd66c07447de5f35cf6c981b (diff) | |
download | gitea-6fe3c8b3980f850c9789f9fa62bdfee7b2708ff0.tar.gz gitea-6fe3c8b3980f850c9789f9fa62bdfee7b2708ff0.zip |
Support org/user level projects (#22235)
Fix #13405
<img width="1151" alt="image"
src="https://user-images.githubusercontent.com/81045/209442911-7baa3924-c389-47b6-b63b-a740803e640e.png">
Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'models/project')
-rw-r--r-- | models/project/project.go | 94 | ||||
-rw-r--r-- | models/project/project_test.go | 6 |
2 files changed, 82 insertions, 18 deletions
diff --git a/models/project/project.go b/models/project/project.go index f432d0bc4c..8bac9115ba 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -8,6 +8,9 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -78,12 +81,15 @@ func (err ErrProjectBoardNotExist) Unwrap() error { // Project represents a project board type Project struct { - ID int64 `xorm:"pk autoincr"` - Title string `xorm:"INDEX NOT NULL"` - Description string `xorm:"TEXT"` - RepoID int64 `xorm:"INDEX"` - CreatorID int64 `xorm:"NOT NULL"` - IsClosed bool `xorm:"INDEX"` + ID int64 `xorm:"pk autoincr"` + Title string `xorm:"INDEX NOT NULL"` + Description string `xorm:"TEXT"` + OwnerID int64 `xorm:"INDEX"` + Owner *user_model.User `xorm:"-"` + RepoID int64 `xorm:"INDEX"` + Repo *repo_model.Repository `xorm:"-"` + CreatorID int64 `xorm:"NOT NULL"` + IsClosed bool `xorm:"INDEX"` BoardType BoardType Type Type @@ -94,6 +100,46 @@ type Project struct { ClosedDateUnix timeutil.TimeStamp } +func (p *Project) LoadOwner(ctx context.Context) (err error) { + if p.Owner != nil { + return nil + } + p.Owner, err = user_model.GetUserByID(ctx, p.OwnerID) + return err +} + +func (p *Project) LoadRepo(ctx context.Context) (err error) { + if p.RepoID == 0 || p.Repo != nil { + return nil + } + p.Repo, err = repo_model.GetRepositoryByID(ctx, p.RepoID) + return err +} + +func (p *Project) Link() string { + if p.OwnerID > 0 { + err := p.LoadOwner(db.DefaultContext) + if err != nil { + log.Error("LoadOwner: %v", err) + return "" + } + return fmt.Sprintf("/%s/-/projects/%d", p.Owner.Name, p.ID) + } + if p.RepoID > 0 { + err := p.LoadRepo(db.DefaultContext) + if err != nil { + log.Error("LoadRepo: %v", err) + return "" + } + return fmt.Sprintf("/%s/projects/%d", p.Repo.RepoPath(), p.ID) + } + return "" +} + +func (p *Project) IsOrganizationProject() bool { + return p.Type == TypeOrganization +} + func init() { db.RegisterModel(new(Project)) } @@ -110,7 +156,7 @@ func GetProjectsConfig() []ProjectsConfig { // IsTypeValid checks if a project type is valid func IsTypeValid(p Type) bool { switch p { - case TypeRepository: + case TypeRepository, TypeOrganization: return true default: return false @@ -119,6 +165,7 @@ func IsTypeValid(p Type) bool { // SearchOptions are options for GetProjects type SearchOptions struct { + OwnerID int64 RepoID int64 Page int IsClosed util.OptionalBool @@ -126,12 +173,11 @@ type SearchOptions struct { Type Type } -// GetProjects returns a list of all projects that have been created in the repository -func GetProjects(ctx context.Context, opts SearchOptions) ([]*Project, int64, error) { - e := db.GetEngine(ctx) - projects := make([]*Project, 0, setting.UI.IssuePagingNum) - - var cond builder.Cond = builder.Eq{"repo_id": opts.RepoID} +func (opts *SearchOptions) toConds() builder.Cond { + cond := builder.NewCond() + if opts.RepoID > 0 { + cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) + } switch opts.IsClosed { case util.OptionalBoolTrue: cond = cond.And(builder.Eq{"is_closed": true}) @@ -142,6 +188,22 @@ func GetProjects(ctx context.Context, opts SearchOptions) ([]*Project, int64, er if opts.Type > 0 { cond = cond.And(builder.Eq{"type": opts.Type}) } + if opts.OwnerID > 0 { + cond = cond.And(builder.Eq{"owner_id": opts.OwnerID}) + } + return cond +} + +// CountProjects counts projects +func CountProjects(ctx context.Context, opts SearchOptions) (int64, error) { + return db.GetEngine(ctx).Where(opts.toConds()).Count(new(Project)) +} + +// FindProjects returns a list of all projects that have been created in the repository +func FindProjects(ctx context.Context, opts SearchOptions) ([]*Project, int64, error) { + e := db.GetEngine(ctx) + projects := make([]*Project, 0, setting.UI.IssuePagingNum) + cond := opts.toConds() count, err := e.Where(cond).Count(new(Project)) if err != nil { @@ -188,8 +250,10 @@ func NewProject(p *Project) error { return err } - if _, err := db.Exec(ctx, "UPDATE `repository` SET num_projects = num_projects + 1 WHERE id = ?", p.RepoID); err != nil { - return err + if p.RepoID > 0 { + if _, err := db.Exec(ctx, "UPDATE `repository` SET num_projects = num_projects + 1 WHERE id = ?", p.RepoID); err != nil { + return err + } } if err := createBoardsForProjectsType(ctx, p); err != nil { diff --git a/models/project/project_test.go b/models/project/project_test.go index 4fde0fc7ce..c2d9005c43 100644 --- a/models/project/project_test.go +++ b/models/project/project_test.go @@ -22,7 +22,7 @@ func TestIsProjectTypeValid(t *testing.T) { }{ {TypeIndividual, false}, {TypeRepository, true}, - {TypeOrganization, false}, + {TypeOrganization, true}, {UnknownType, false}, } @@ -34,13 +34,13 @@ func TestIsProjectTypeValid(t *testing.T) { func TestGetProjects(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - projects, _, err := GetProjects(db.DefaultContext, SearchOptions{RepoID: 1}) + projects, _, err := FindProjects(db.DefaultContext, SearchOptions{RepoID: 1}) assert.NoError(t, err) // 1 value for this repo exists in the fixtures assert.Len(t, projects, 1) - projects, _, err = GetProjects(db.DefaultContext, SearchOptions{RepoID: 3}) + projects, _, err = FindProjects(db.DefaultContext, SearchOptions{RepoID: 3}) assert.NoError(t, err) // 1 value for this repo exists in the fixtures |