summaryrefslogtreecommitdiffstats
path: root/services/f3/driver/project.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--services/f3/driver/project.go188
1 files changed, 188 insertions, 0 deletions
diff --git a/services/f3/driver/project.go b/services/f3/driver/project.go
new file mode 100644
index 0000000..c2a2df3
--- /dev/null
+++ b/services/f3/driver/project.go
@@ -0,0 +1,188 @@
+// Copyright Earl Warren <contact@earl-warren.org>
+// Copyright Loïc Dachary <loic@dachary.org>
+// SPDX-License-Identifier: MIT
+
+package driver
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ repo_service "code.gitea.io/gitea/services/repository"
+
+ "code.forgejo.org/f3/gof3/v3/f3"
+ f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
+ "code.forgejo.org/f3/gof3/v3/tree/generic"
+ f3_util "code.forgejo.org/f3/gof3/v3/util"
+)
+
+var _ f3_tree.ForgeDriverInterface = &project{}
+
+type project struct {
+ common
+
+ forgejoProject *repo_model.Repository
+ forked *f3.Reference
+}
+
+func (o *project) SetNative(project any) {
+ o.forgejoProject = project.(*repo_model.Repository)
+}
+
+func (o *project) GetNativeID() string {
+ return fmt.Sprintf("%d", o.forgejoProject.ID)
+}
+
+func (o *project) NewFormat() f3.Interface {
+ node := o.GetNode()
+ return node.GetTree().(f3_tree.TreeInterface).NewFormat(node.GetKind())
+}
+
+func (o *project) setForkedReference(ctx context.Context) {
+ if !o.forgejoProject.IsFork {
+ return
+ }
+
+ if err := o.forgejoProject.GetBaseRepo(ctx); err != nil {
+ panic(fmt.Errorf("GetBaseRepo %v %w", o.forgejoProject, err))
+ }
+ forkParent := o.forgejoProject.BaseRepo
+ if err := forkParent.LoadOwner(ctx); err != nil {
+ panic(fmt.Errorf("LoadOwner %v %w", forkParent, err))
+ }
+ owners := "users"
+ if forkParent.Owner.IsOrganization() {
+ owners = "organizations"
+ }
+
+ o.forked = f3_tree.NewProjectReference(owners, fmt.Sprintf("%d", forkParent.Owner.ID), fmt.Sprintf("%d", forkParent.ID))
+}
+
+func (o *project) ToFormat() f3.Interface {
+ if o.forgejoProject == nil {
+ return o.NewFormat()
+ }
+ return &f3.Project{
+ Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoProject.ID)),
+ Name: o.forgejoProject.Name,
+ IsPrivate: o.forgejoProject.IsPrivate,
+ IsMirror: o.forgejoProject.IsMirror,
+ Description: o.forgejoProject.Description,
+ DefaultBranch: o.forgejoProject.DefaultBranch,
+ Forked: o.forked,
+ }
+}
+
+func (o *project) FromFormat(content f3.Interface) {
+ project := content.(*f3.Project)
+ o.forgejoProject = &repo_model.Repository{
+ ID: f3_util.ParseInt(project.GetID()),
+ Name: project.Name,
+ IsPrivate: project.IsPrivate,
+ IsMirror: project.IsMirror,
+ Description: project.Description,
+ DefaultBranch: project.DefaultBranch,
+ }
+ if project.Forked != nil {
+ o.forgejoProject.IsFork = true
+ o.forgejoProject.ForkID = project.Forked.GetIDAsInt()
+ }
+ o.forked = project.Forked
+}
+
+func (o *project) Get(ctx context.Context) bool {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+ id := node.GetID().Int64()
+ u, err := repo_model.GetRepositoryByID(ctx, id)
+ if repo_model.IsErrRepoNotExist(err) {
+ return false
+ }
+ if err != nil {
+ panic(fmt.Errorf("project %v %w", id, err))
+ }
+ o.forgejoProject = u
+ o.setForkedReference(ctx)
+ return true
+}
+
+func (o *project) Patch(ctx context.Context) {
+ o.Trace("%d", o.forgejoProject.ID)
+ o.forgejoProject.LowerName = strings.ToLower(o.forgejoProject.Name)
+ if err := repo_model.UpdateRepositoryCols(ctx, o.forgejoProject,
+ "description",
+ "name",
+ "lower_name",
+ ); err != nil {
+ panic(fmt.Errorf("UpdateRepositoryCols: %v %v", o.forgejoProject, err))
+ }
+}
+
+func (o *project) Put(ctx context.Context) generic.NodeID {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+
+ ownerID := f3_tree.GetOwnerID(o.GetNode())
+ owner, err := user_model.GetUserByID(ctx, ownerID)
+ if err != nil {
+ panic(fmt.Errorf("GetUserByID %v %w", ownerID, err))
+ }
+ doer, err := user_model.GetAdminUser(ctx)
+ if err != nil {
+ panic(fmt.Errorf("GetAdminUser %w", err))
+ }
+
+ if o.forked == nil {
+ repo, err := repo_service.CreateRepositoryDirectly(ctx, doer, owner, repo_service.CreateRepoOptions{
+ Name: o.forgejoProject.Name,
+ Description: o.forgejoProject.Description,
+ IsPrivate: o.forgejoProject.IsPrivate,
+ DefaultBranch: o.forgejoProject.DefaultBranch,
+ })
+ if err != nil {
+ panic(err)
+ }
+ o.forgejoProject = repo
+ o.Trace("project created %d", o.forgejoProject.ID)
+ } else {
+ if err = o.forgejoProject.GetBaseRepo(ctx); err != nil {
+ panic(fmt.Errorf("GetBaseRepo %v %w", o.forgejoProject, err))
+ }
+ if err = o.forgejoProject.BaseRepo.LoadOwner(ctx); err != nil {
+ panic(fmt.Errorf("LoadOwner %v %w", o.forgejoProject.BaseRepo, err))
+ }
+
+ repo, err := repo_service.ForkRepositoryIfNotExists(ctx, doer, owner, repo_service.ForkRepoOptions{
+ BaseRepo: o.forgejoProject.BaseRepo,
+ Name: o.forgejoProject.Name,
+ Description: o.forgejoProject.Description,
+ })
+ if err != nil {
+ panic(err)
+ }
+ o.forgejoProject = repo
+ o.Trace("project created %d", o.forgejoProject.ID)
+ }
+ return generic.NewNodeID(o.forgejoProject.ID)
+}
+
+func (o *project) Delete(ctx context.Context) {
+ node := o.GetNode()
+ o.Trace("%s", node.GetID())
+
+ doer, err := user_model.GetAdminUser(ctx)
+ if err != nil {
+ panic(fmt.Errorf("GetAdminUser %w", err))
+ }
+
+ if err := repo_service.DeleteRepository(ctx, doer, o.forgejoProject, true); err != nil {
+ panic(err)
+ }
+}
+
+func newProject() generic.NodeDriverInterface {
+ return &project{}
+}