chore: update gof3/v3 v3.11.15 (#10673)

Update the Forgejo driver for gof3 with modifications for non-backward compatible changes. The changes are isolated behind the f3.Enable flag and not yet functional. The purpose of this upgrade is to not drift from the gof3 implementation while the work continues.

The `fix: include remote users when counting users` commit is a functional change to Forgejo itself but does not change the behavior because the remote users are only created in fixtures or by F3.

https://codeberg.org/forgejo/forgejo/src/commit/59c721d26b1a01e6e6ca812b63066a33e7e5e4da/models/user/user.go#L65-L66

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10673
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: limiting-factor <limiting-factor@posteo.com>
Co-committed-by: limiting-factor <limiting-factor@posteo.com>
This commit is contained in:
limiting-factor
2026-01-13 16:59:56 +01:00
committed by Gusted
parent 8cf17e3826
commit a71392c6aa
39 changed files with 348 additions and 194 deletions
+5 -2
View File
@@ -24,7 +24,6 @@ import (
) )
func CmdF3(ctx context.Context) *cli.Command { func CmdF3(ctx context.Context) *cli.Command {
ctx = f3_logger.ContextSetLogger(ctx, util.NewF3Logger(nil, log.GetLogger(log.DEFAULT)))
return &cli.Command{ return &cli.Command{
Name: "f3", Name: "f3",
Usage: "F3", Usage: "F3",
@@ -38,7 +37,9 @@ func SubcmdF3Mirror(ctx context.Context) *cli.Command {
mirrorCmd := f3_cmd.CreateCmdMirror() mirrorCmd := f3_cmd.CreateCmdMirror()
mirrorCmd.Before = prepareWorkPathAndCustomConf(ctx) mirrorCmd.Before = prepareWorkPathAndCustomConf(ctx)
f3Action := mirrorCmd.Action f3Action := mirrorCmd.Action
mirrorCmd.Action = func(ctx context.Context, cli *cli.Command) error { return runMirror(ctx, cli, f3Action) } mirrorCmd.Action = func(ctx context.Context, cli *cli.Command) error {
return runMirror(ctx, cli, f3Action)
}
return mirrorCmd return mirrorCmd
} }
@@ -67,6 +68,8 @@ func runMirror(ctx context.Context, c *cli.Command, action cli.ActionFunc) error
if err := models.Init(ctx); err != nil { if err := models.Init(ctx); err != nil {
return err return err
} }
ctx = f3_logger.ContextSetLogger(ctx, util.NewF3Logger(nil, log.GetLogger(log.DEFAULT)))
} }
err := action(ctx, c) err := action(ctx, c)
+1 -1
View File
@@ -2552,7 +2552,7 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[F3] ;[f3]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
+3 -3
View File
@@ -5,7 +5,7 @@ go 1.25.0
toolchain go1.25.5 toolchain go1.25.5
require ( require (
code.forgejo.org/f3/gof3/v3 v3.11.1 code.forgejo.org/f3/gof3/v3 v3.11.15
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251
code.forgejo.org/forgejo/actions-proto v0.6.0 code.forgejo.org/forgejo/actions-proto v0.6.0
code.forgejo.org/forgejo/go-rpmutils v1.0.0 code.forgejo.org/forgejo/go-rpmutils v1.0.0
@@ -63,7 +63,7 @@ require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gorilla/feeds v1.2.0 github.com/gorilla/feeds v1.2.0
github.com/gorilla/sessions v1.4.0 github.com/gorilla/sessions v1.4.0
github.com/hashicorp/go-version v1.7.0 github.com/hashicorp/go-version v1.8.0
github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/huandu/xstrings v1.5.0 github.com/huandu/xstrings v1.5.0
github.com/inbucket/html2text v0.9.0 github.com/inbucket/html2text v0.9.0
@@ -94,7 +94,7 @@ require (
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
github.com/syndtr/goleveldb v1.0.0 github.com/syndtr/goleveldb v1.0.0
github.com/ulikunitz/xz v0.5.15 github.com/ulikunitz/xz v0.5.15
github.com/urfave/cli/v3 v3.5.0 github.com/urfave/cli/v3 v3.6.1
github.com/valyala/fastjson v1.6.7 github.com/valyala/fastjson v1.6.7
github.com/yohcop/openid-go v1.0.1 github.com/yohcop/openid-go v1.0.1
github.com/yuin/goldmark v1.7.16 github.com/yuin/goldmark v1.7.16
+4 -4
View File
@@ -16,8 +16,8 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
code.forgejo.org/f3/gof3/v3 v3.11.1 h1:c0vE8XvqpbXuSv8gzttn96k5T2FQi0u9bYnux46qSAs= code.forgejo.org/f3/gof3/v3 v3.11.15 h1:/EzJWRQUhVVia1EmCWRZHCuW8qdAX1DEXY0M1n0mECc=
code.forgejo.org/f3/gof3/v3 v3.11.1/go.mod h1:1p2UKrqZiwxKneQF2DKrMnc403YIgR/lfcfvadZtmDs= code.forgejo.org/f3/gof3/v3 v3.11.15/go.mod h1:k99wl7QiI9LjS3qEd1RXLdcZPE3wZP5gkVhy8/WhzJ4=
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU=
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM=
code.forgejo.org/forgejo/actions-proto v0.6.0 h1:dw1Dogk9A4V/yrLVkhe9dSZPsqNAIkI1kCXPSqG3tZA= code.forgejo.org/forgejo/actions-proto v0.6.0 h1:dw1Dogk9A4V/yrLVkhe9dSZPsqNAIkI1kCXPSqG3tZA=
@@ -660,8 +660,8 @@ github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli/v3 v3.5.0 h1:qCuFMmdayTF3zmjG8TSsoBzrDqszNrklYg2x3g4MSgw= github.com/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo=
github.com/urfave/cli/v3 v3.5.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM=
github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
+1 -1
View File
@@ -888,7 +888,7 @@ func CountUsers(ctx context.Context, opts *CountUserFilter) int64 {
func countUsers(ctx context.Context, opts *CountUserFilter) int64 { func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
cond := builder.NewCond() cond := builder.NewCond()
cond = cond.And(builder.Eq{"type": UserTypeIndividual}) cond = cond.And(builder.In("type", UserTypeIndividual, UserTypeRemoteUser))
if opts != nil { if opts != nil {
if opts.LastLoginSince != nil { if opts.LastLoginSince != nil {
+16 -1
View File
@@ -3,6 +3,9 @@
package setting package setting
import ( import (
"os"
"path/filepath"
"forgejo.org/modules/log" "forgejo.org/modules/log"
) )
@@ -10,8 +13,10 @@ import (
var ( var (
F3 = struct { F3 = struct {
Enabled bool Enabled bool
Path string
}{ }{
Enabled: false, Enabled: false,
Path: "f3",
} }
) )
@@ -20,7 +25,17 @@ func LoadF3Setting() {
} }
func loadF3From(rootCfg ConfigProvider) { func loadF3From(rootCfg ConfigProvider) {
if err := rootCfg.Section("F3").MapTo(&F3); err != nil { if err := rootCfg.Section("f3").MapTo(&F3); err != nil {
log.Fatal("Failed to map F3 settings: %v", err) log.Fatal("Failed to map F3 settings: %v", err)
} }
if !filepath.IsAbs(F3.Path) {
F3.Path = filepath.Join(AppDataPath, F3.Path)
} else {
F3.Path = filepath.Clean(F3.Path)
}
if err := os.MkdirAll(F3.Path, os.ModePerm); err != nil {
log.Fatal("Failed to create F3 path %s: %v", F3.Path, err)
}
} }
+74
View File
@@ -0,0 +1,74 @@
// Copyright 2024 The Forgejo Authors.
// SPDX-License-Identifier: GPLv3-or-later
package setting
import (
"fmt"
"testing"
"forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSettingF3(t *testing.T) {
restoreF3 := test.MockProtect(&F3)
restoreAppDataPath := test.MockProtect(&AppDataPath)
restore := func() {
restoreF3()
restoreAppDataPath()
}
defer restore()
t.Run("enabled", func(t *testing.T) {
restore()
cfg, err := NewConfigProviderFromData(`
[f3]
ENABLED = true
`)
require.NoError(t, err)
loadF3From(cfg)
assert.True(t, F3.Enabled)
assert.DirExists(t, F3.Path)
})
t.Run("disabled by default", func(t *testing.T) {
restore()
cfg, err := NewConfigProviderFromData(`
[f3]
`)
require.NoError(t, err)
loadF3From(cfg)
assert.False(t, F3.Enabled)
})
t.Run("default f3 path", func(t *testing.T) {
restore()
cfg, err := NewConfigProviderFromData(`
[f3]
ENABLED = true
`)
require.NoError(t, err)
AppDataPath = t.TempDir()
loadF3From(cfg)
assert.Equal(t, AppDataPath+"/f3", F3.Path)
assert.DirExists(t, F3.Path)
})
t.Run("absolute f3 path", func(t *testing.T) {
restore()
other := t.TempDir()
cfg, err := NewConfigProviderFromData(fmt.Sprintf(`
[f3]
ENABLED = true
PATH = %[1]s
`, other))
require.NoError(t, err)
AppDataPath = t.TempDir()
loadF3From(cfg)
assert.Equal(t, other, F3.Path)
assert.DirExists(t, F3.Path)
})
}
+6 -5
View File
@@ -21,8 +21,9 @@ import (
"code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util" f3_util "code.forgejo.org/f3/gof3/v3/util"
"github.com/google/uuid" "github.com/google/uuid"
) )
@@ -145,11 +146,11 @@ func (o *attachment) Put(ctx context.Context) f3_id.NodeID {
attachableID := f3_tree.GetAttachableID(o.GetNode()) attachableID := f3_tree.GetAttachableID(o.GetNode())
switch attachable.GetKind() { switch attachable.GetKind() {
case f3_tree.KindRelease: case f3_kind.KindRelease:
o.forgejoAttachment.ReleaseID = attachableID o.forgejoAttachment.ReleaseID = attachableID
case f3_tree.KindComment: case f3_kind.KindComment:
o.forgejoAttachment.CommentID = attachableID o.forgejoAttachment.CommentID = attachableID
case f3_tree.KindIssue, f3_tree.KindPullRequest: case f3_kind.KindIssue, f3_kind.KindPullRequest:
o.forgejoAttachment.IssueID = attachableID o.forgejoAttachment.IssueID = attachableID
default: default:
panic(fmt.Errorf("unexpected type %s", attachable.GetKind())) panic(fmt.Errorf("unexpected type %s", attachable.GetKind()))
@@ -180,6 +181,6 @@ func (o *attachment) Delete(ctx context.Context) {
} }
} }
func newAttachment() generic.NodeDriverInterface { func newAttachment() f3_tree_generic.NodeDriverInterface {
return &attachment{} return &attachment{}
} }
+8 -7
View File
@@ -11,17 +11,18 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
repo_model "forgejo.org/models/repo" repo_model "forgejo.org/models/repo"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type attachments struct { type attachments struct {
container container
} }
func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *attachments) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
if page > 1 { if page > 1 {
return generic.NewChildrenSlice(0) return f3_tree_generic.NewChildrenList(0)
} }
attachable := f3_tree.GetAttachable(o.GetNode()) attachable := f3_tree.GetAttachable(o.GetNode())
@@ -30,7 +31,7 @@ func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSl
var attachments []*repo_model.Attachment var attachments []*repo_model.Attachment
switch attachable.GetKind() { switch attachable.GetKind() {
case f3_tree.KindRelease: case f3_kind.KindRelease:
release, err := repo_model.GetReleaseByID(ctx, attachableID) release, err := repo_model.GetReleaseByID(ctx, attachableID)
if err != nil { if err != nil {
panic(fmt.Errorf("GetReleaseByID %v %w", attachableID, err)) panic(fmt.Errorf("GetReleaseByID %v %w", attachableID, err))
@@ -42,7 +43,7 @@ func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSl
attachments = release.Attachments attachments = release.Attachments
case f3_tree.KindComment: case f3_kind.KindComment:
comment, err := issues_model.GetCommentByID(ctx, attachableID) comment, err := issues_model.GetCommentByID(ctx, attachableID)
if err != nil { if err != nil {
panic(fmt.Errorf("GetCommentByID %v %w", attachableID, err)) panic(fmt.Errorf("GetCommentByID %v %w", attachableID, err))
@@ -54,7 +55,7 @@ func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSl
attachments = comment.Attachments attachments = comment.Attachments
case f3_tree.KindIssue, f3_tree.KindPullRequest: case f3_kind.KindIssue, f3_kind.KindPullRequest:
repoID := f3_tree.GetProjectID(o.GetNode()) repoID := f3_tree.GetProjectID(o.GetNode())
issue, err := issues_model.GetIssueByIndex(ctx, repoID, attachableID) issue, err := issues_model.GetIssueByIndex(ctx, repoID, attachableID)
if err != nil { if err != nil {
@@ -74,6 +75,6 @@ func (o *attachments) ListPage(ctx context.Context, page int) generic.ChildrenSl
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(attachments...)...) return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(attachments...)...)
} }
func newAttachments() generic.NodeDriverInterface { func newAttachments() f3_tree_generic.NodeDriverInterface {
return &attachments{} return &attachments{}
} }
+11 -2
View File
@@ -47,7 +47,7 @@ func (o *comment) ToFormat() f3.Interface {
} }
return &f3.Comment{ return &f3.Comment{
Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoComment.ID)), Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoComment.ID)),
PosterID: f3_tree.NewUserReference(o.forgejoComment.Poster.ID), PosterID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoComment.Poster.ID)),
Content: o.forgejoComment.Content, Content: o.forgejoComment.Content,
Created: o.forgejoComment.CreatedUnix.AsTime(), Created: o.forgejoComment.CreatedUnix.AsTime(),
Updated: o.forgejoComment.UpdatedUnix.AsTime(), Updated: o.forgejoComment.UpdatedUnix.AsTime(),
@@ -59,6 +59,7 @@ func (o *comment) FromFormat(content f3.Interface) {
o.forgejoComment = &issues_model.Comment{ o.forgejoComment = &issues_model.Comment{
ID: f3_util.ParseInt(comment.GetID()), ID: f3_util.ParseInt(comment.GetID()),
Type: issues_model.CommentTypeComment,
PosterID: comment.PosterID.GetIDAsInt(), PosterID: comment.PosterID.GetIDAsInt(),
Poster: &user_model.User{ Poster: &user_model.User{
ID: comment.PosterID.GetIDAsInt(), ID: comment.PosterID.GetIDAsInt(),
@@ -98,7 +99,15 @@ func (o *comment) Patch(ctx context.Context) {
func (o *comment) Put(ctx context.Context) f3_id.NodeID { func (o *comment) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode() node := o.GetNode()
o.Trace("%s", node.GetID())
issueIndex := f3_tree.GetCommentableID(node)
repositoryID := f3_tree.GetProjectID(node)
issue, err := issues_model.GetIssueByIndex(ctx, repositoryID, issueIndex)
if issues_model.IsErrIssueNotExist(err) {
panic(fmt.Errorf("issue index %d not found in repository id %d", issueIndex, repositoryID))
}
o.forgejoComment.IssueID = issue.ID
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
+12 -6
View File
@@ -12,18 +12,18 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type comments struct { type comments struct {
container container
} }
func (o *comments) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *comments) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
commentable := f3_tree.GetCommentableID(o.GetNode()) commentable := f3_tree.GetCommentableID(node)
issue, err := issues_model.GetIssueByIndex(ctx, project, commentable) issue, err := issues_model.GetIssueByIndex(ctx, project, commentable)
if err != nil { if err != nil {
@@ -41,9 +41,15 @@ func (o *comments) ListPage(ctx context.Context, page int) generic.ChildrenSlice
panic(fmt.Errorf("error while listing comments: %v", err)) panic(fmt.Errorf("error while listing comments: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoComments...)...) for _, forgejoComment := range forgejoComments {
if err := forgejoComment.LoadPoster(ctx); err != nil {
panic(fmt.Errorf("LoadPoster %+v %w", *forgejoComment, err))
}
}
return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoComments...)...)
} }
func newComments() generic.NodeDriverInterface { func newComments() f3_tree_generic.NodeDriverInterface {
return &comments{} return &comments{}
} }
+5 -5
View File
@@ -8,19 +8,19 @@ import (
"context" "context"
f3_kind "code.forgejo.org/f3/gof3/v3/kind" f3_kind "code.forgejo.org/f3/gof3/v3/kind"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type common struct { type common struct {
generic.NullDriver f3_tree_generic.NullDriver
} }
func (o *common) GetHelper() any { func (o *common) GetHelper() any {
panic("not implemented") panic("not implemented")
} }
func (o *common) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *common) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
return generic.NewChildrenSlice(0) return f3_tree_generic.NewChildrenList(0)
} }
func (o *common) GetNativeID() string { func (o *common) GetNativeID() string {
@@ -30,7 +30,7 @@ func (o *common) GetNativeID() string {
func (o *common) SetNative(native any) { func (o *common) SetNative(native any) {
} }
func (o *common) getTree() generic.TreeInterface { func (o *common) getTree() f3_tree_generic.TreeInterface {
return o.GetNode().GetTree() return o.GetNode().GetTree()
} }
+4 -5
View File
@@ -13,7 +13,6 @@ import (
"code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_kind "code.forgejo.org/f3/gof3/v3/kind" f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" "code.forgejo.org/f3/gof3/v3/tree/generic"
"code.forgejo.org/f3/gof3/v3/util" "code.forgejo.org/f3/gof3/v3/util"
) )
@@ -37,17 +36,17 @@ func (o *forge) getOwnersKind(ctx context.Context, id string) f3_kind.Kind {
if err != nil { if err != nil {
panic(fmt.Errorf("user_repo.GetUserByID: %w", err)) panic(fmt.Errorf("user_repo.GetUserByID: %w", err))
} }
kind = f3_tree.KindUsers kind = f3_kind.KindUsers
if user.IsOrganization() { if user.IsOrganization() {
kind = f3_tree.KindOrganization kind = f3_kind.KindOrganization
} }
o.ownersKind[id] = kind o.ownersKind[id] = kind
} }
return kind return kind
} }
func (o *forge) getOwnersPath(ctx context.Context, id string) f3_tree.Path { func (o *forge) getOwnersPath(ctx context.Context, id string) generic.Path {
return f3_tree.NewPathFromString("/").SetForge().SetOwners(o.getOwnersKind(ctx, id)) return generic.NewNodePathFromString("/").SetForge().SetOwners(o.getOwnersKind(ctx, id))
} }
func (o *forge) Equals(context.Context, generic.NodeInterface) bool { return true } func (o *forge) Equals(context.Context, generic.NodeInterface) bool { return true }
+4 -4
View File
@@ -51,23 +51,23 @@ func (o *issue) ToFormat() f3.Interface {
milestone := &f3.Reference{} milestone := &f3.Reference{}
if o.forgejoIssue.Milestone != nil { if o.forgejoIssue.Milestone != nil {
milestone = f3_tree.NewIssueMilestoneReference(o.forgejoIssue.Milestone.ID) milestone = f3_tree.NewIssueMilestoneReference(f3_util.ToString(o.forgejoIssue.Milestone.ID))
} }
assignees := make([]*f3.Reference, 0, len(o.forgejoIssue.Assignees)) assignees := make([]*f3.Reference, 0, len(o.forgejoIssue.Assignees))
for _, assignee := range o.forgejoIssue.Assignees { for _, assignee := range o.forgejoIssue.Assignees {
assignees = append(assignees, f3_tree.NewUserReference(assignee.ID)) assignees = append(assignees, f3_tree.NewUserReference(f3_util.ToString(assignee.ID)))
} }
labels := make([]*f3.Reference, 0, len(o.forgejoIssue.Labels)) labels := make([]*f3.Reference, 0, len(o.forgejoIssue.Labels))
for _, label := range o.forgejoIssue.Labels { for _, label := range o.forgejoIssue.Labels {
labels = append(labels, f3_tree.NewIssueLabelReference(label.ID)) labels = append(labels, f3_tree.NewIssueLabelReference(f3_util.ToString(label.ID)))
} }
return &f3.Issue{ return &f3.Issue{
Title: o.forgejoIssue.Title, Title: o.forgejoIssue.Title,
Common: f3.NewCommon(o.GetNativeID()), Common: f3.NewCommon(o.GetNativeID()),
PosterID: f3_tree.NewUserReference(o.forgejoIssue.Poster.ID), PosterID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoIssue.Poster.ID)),
Assignees: assignees, Assignees: assignees,
Labels: labels, Labels: labels,
Content: o.forgejoIssue.Content, Content: o.forgejoIssue.Content,
+5 -5
View File
@@ -12,17 +12,17 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type issues struct { type issues struct {
container container
} }
func (o *issues) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *issues) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
forgejoIssues, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{ forgejoIssues, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
Paginator: &db.ListOptions{Page: page, PageSize: pageSize}, Paginator: &db.ListOptions{Page: page, PageSize: pageSize},
@@ -32,9 +32,9 @@ func (o *issues) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
panic(fmt.Errorf("error while listing issues: %v", err)) panic(fmt.Errorf("error while listing issues: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoIssues...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoIssues...)...)
} }
func newIssues() generic.NodeDriverInterface { func newIssues() f3_tree_generic.NodeDriverInterface {
return &issues{} return &issues{}
} }
+5 -5
View File
@@ -12,26 +12,26 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type labels struct { type labels struct {
container container
} }
func (o *labels) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *labels) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
forgejoLabels, err := issues_model.GetLabelsByRepoID(ctx, project, "", db.ListOptions{Page: page, PageSize: pageSize}) forgejoLabels, err := issues_model.GetLabelsByRepoID(ctx, project, "", db.ListOptions{Page: page, PageSize: pageSize})
if err != nil { if err != nil {
panic(fmt.Errorf("error while listing labels: %v", err)) panic(fmt.Errorf("error while listing labels: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoLabels...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoLabels...)...)
} }
func newLabels() generic.NodeDriverInterface { func newLabels() f3_tree_generic.NodeDriverInterface {
return &labels{} return &labels{}
} }
+5
View File
@@ -8,6 +8,7 @@ import (
"testing" "testing"
"forgejo.org/models/unittest" "forgejo.org/models/unittest"
"forgejo.org/modules/log"
"forgejo.org/modules/setting" "forgejo.org/modules/setting"
"forgejo.org/modules/test" "forgejo.org/modules/test"
driver_options "forgejo.org/services/f3/driver/options" driver_options "forgejo.org/services/f3/driver/options"
@@ -25,6 +26,10 @@ import (
func TestF3(t *testing.T) { func TestF3(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase()) require.NoError(t, unittest.PrepareTestDatabase())
defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())() defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())()
log.SetConsoleLogger(log.DEFAULT, "console", log.TRACE)
defer func() {
log.SetConsoleLogger(log.DEFAULT, "console", log.INFO)
}()
tests_f3.ForgeCompliance(t, driver_options.Name) tests_f3.ForgeCompliance(t, driver_options.Name)
} }
+5 -5
View File
@@ -12,17 +12,17 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type milestones struct { type milestones struct {
container container
} }
func (o *milestones) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *milestones) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
forgejoMilestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ forgejoMilestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{
ListOptions: db.ListOptions{Page: page, PageSize: pageSize}, ListOptions: db.ListOptions{Page: page, PageSize: pageSize},
@@ -32,9 +32,9 @@ func (o *milestones) ListPage(ctx context.Context, page int) generic.ChildrenSli
panic(fmt.Errorf("error while listing milestones: %v", err)) panic(fmt.Errorf("error while listing milestones: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoMilestones...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoMilestones...)...)
} }
func newMilestones() generic.NodeDriverInterface { func newMilestones() f3_tree_generic.NodeDriverInterface {
return &milestones{} return &milestones{}
} }
+14 -5
View File
@@ -12,16 +12,17 @@ import (
org_model "forgejo.org/models/organization" org_model "forgejo.org/models/organization"
user_model "forgejo.org/models/user" user_model "forgejo.org/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type organizations struct { type organizations struct {
container container
} }
func (o *organizations) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *organizations) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
if page != 0 { if page != 0 {
sess = db.SetSessionPagination(sess, &db.ListOptions{Page: page, PageSize: o.getPageSize()}) sess = db.SetSessionPagination(sess, &db.ListOptions{Page: page, PageSize: o.getPageSize()})
@@ -34,18 +35,26 @@ func (o *organizations) ListPage(ctx context.Context, page int) generic.Children
panic(fmt.Errorf("error while listing organizations: %v", err)) panic(fmt.Errorf("error while listing organizations: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(organizations...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(organizations...)...)
}
func (o *organizations) LookupMappedID(ctx context.Context, id f3_id.NodeID, f f3.Interface) f3_id.NodeID {
organization := f.(*f3.Organization)
return o.GetIDFromName(ctx, organization.Name)
} }
func (o *organizations) GetIDFromName(ctx context.Context, name string) f3_id.NodeID { func (o *organizations) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
organization, err := org_model.GetOrgByName(ctx, name) organization, err := org_model.GetOrgByName(ctx, name)
if org_model.IsErrOrgNotExist(err) {
return f3_id.NilID
}
if err != nil { if err != nil {
panic(fmt.Errorf("GetOrganizationByName: %v", err)) panic(fmt.Errorf("GetOrgByName(%s): %v", name, err))
} }
return f3_id.NewNodeID(organization.ID) return f3_id.NewNodeID(organization.ID)
} }
func newOrganizations() generic.NodeDriverInterface { func newOrganizations() f3_tree_generic.NodeDriverInterface {
return &organizations{} return &organizations{}
} }
+11 -5
View File
@@ -11,15 +11,21 @@ import (
"forgejo.org/models/db" "forgejo.org/models/db"
repo_model "forgejo.org/models/repo" repo_model "forgejo.org/models/repo"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type projects struct { type projects struct {
container container
} }
func (o *projects) LookupMappedID(ctx context.Context, id f3_id.NodeID, f f3.Interface) f3_id.NodeID {
project := f.(*f3.Project)
return o.GetIDFromName(ctx, project.Name)
}
func (o *projects) GetIDFromName(ctx context.Context, name string) f3_id.NodeID { func (o *projects) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
owner := f3_tree.GetOwnerName(o.GetNode()) owner := f3_tree.GetOwnerName(o.GetNode())
forgejoProject, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, name) forgejoProject, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, name)
@@ -34,10 +40,10 @@ func (o *projects) GetIDFromName(ctx context.Context, name string) f3_id.NodeID
return f3_id.NewNodeID(forgejoProject.ID) return f3_id.NewNodeID(forgejoProject.ID)
} }
func (o *projects) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *projects) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
owner := f3_tree.GetOwner(o.GetNode()) owner := f3_tree.GetOwner(node)
forgejoProjects, _, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ forgejoProjects, _, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{Page: page, PageSize: pageSize}, ListOptions: db.ListOptions{Page: page, PageSize: pageSize},
@@ -48,9 +54,9 @@ func (o *projects) ListPage(ctx context.Context, page int) generic.ChildrenSlice
panic(fmt.Errorf("error while listing projects: %v", err)) panic(fmt.Errorf("error while listing projects: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoProjects...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoProjects...)...)
} }
func newProjects() generic.NodeDriverInterface { func newProjects() f3_tree_generic.NodeDriverInterface {
return &projects{} return &projects{}
} }
+7 -7
View File
@@ -19,7 +19,7 @@ import (
"code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_path "code.forgejo.org/f3/gof3/v3/path" f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" "code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util" f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -53,17 +53,17 @@ func (o *pullRequest) repositoryToReference(ctx context.Context, repository *rep
if repository == nil { if repository == nil {
panic("unexpected nil repository") panic("unexpected nil repository")
} }
forge := o.getTree().GetRoot().GetChild(f3_id.NewNodeID(f3_tree.KindForge)).GetDriver().(*forge) forge := o.getTree().GetRoot().GetChild(f3_id.NewNodeID(f3_kind.KindForge)).GetDriver().(*forge)
owners := forge.getOwnersPath(ctx, fmt.Sprintf("%d", repository.OwnerID)) owners := forge.getOwnersPath(ctx, fmt.Sprintf("%d", repository.OwnerID))
return f3_tree.NewRepositoryReference(owners.String(), repository.OwnerID, repository.ID) return f3_tree.NewRepositoryReference(owners.String(), f3_util.ToString(repository.OwnerID), f3_util.ToString(repository.ID), f3.RepositoryNameDefault)
} }
func (o *pullRequest) referenceToRepository(reference *f3.Reference) int64 { func (o *pullRequest) referenceToRepository(reference *f3.Reference) int64 {
var project int64 var project int64
if reference.Get() == "../../repository/vcs" { if reference.Get() == "../../repositories/vcs" {
project = f3_tree.GetProjectID(o.GetNode()) project = f3_tree.GetProjectID(o.GetNode())
} else { } else {
p := f3_tree.ToPath(f3_path.PathAbsolute(generic.NewElementNode, o.GetNode().GetCurrentPath().String(), reference.Get())) p := generic.PathAbsolute(generic.NewNode, o.GetNode().GetCurrentPath().String(), reference.Get())
o.Trace("%v %v", o.GetNode().GetCurrentPath().String(), p) o.Trace("%v %v", o.GetNode().GetCurrentPath().String(), p)
_, project = p.OwnerAndProjectID() _, project = p.OwnerAndProjectID()
} }
@@ -77,7 +77,7 @@ func (o *pullRequest) ToFormat() f3.Interface {
var milestone *f3.Reference var milestone *f3.Reference
if o.forgejoPullRequest.Milestone != nil { if o.forgejoPullRequest.Milestone != nil {
milestone = f3_tree.NewIssueMilestoneReference(o.forgejoPullRequest.Milestone.ID) milestone = f3_tree.NewIssueMilestoneReference(f3_util.ToString(o.forgejoPullRequest.Milestone.ID))
} }
var mergedTime *time.Time var mergedTime *time.Time
@@ -125,7 +125,7 @@ func (o *pullRequest) ToFormat() f3.Interface {
return &f3.PullRequest{ return &f3.PullRequest{
Common: f3.NewCommon(o.GetNativeID()), Common: f3.NewCommon(o.GetNativeID()),
PosterID: f3_tree.NewUserReference(o.forgejoPullRequest.Poster.ID), PosterID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoPullRequest.Poster.ID)),
Title: o.forgejoPullRequest.Title, Title: o.forgejoPullRequest.Title,
Content: o.forgejoPullRequest.Content, Content: o.forgejoPullRequest.Content,
Milestone: milestone, Milestone: milestone,
+5 -5
View File
@@ -13,17 +13,17 @@ import (
"forgejo.org/modules/optional" "forgejo.org/modules/optional"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type pullRequests struct { type pullRequests struct {
container container
} }
func (o *pullRequests) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *pullRequests) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
forgejoPullRequests, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{ forgejoPullRequests, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{
Paginator: &db.ListOptions{Page: page, PageSize: pageSize}, Paginator: &db.ListOptions{Page: page, PageSize: pageSize},
@@ -34,9 +34,9 @@ func (o *pullRequests) ListPage(ctx context.Context, page int) generic.ChildrenS
panic(fmt.Errorf("error while listing pullRequests: %v", err)) panic(fmt.Errorf("error while listing pullRequests: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoPullRequests...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoPullRequests...)...)
} }
func newPullRequests() generic.NodeDriverInterface { func newPullRequests() f3_tree_generic.NodeDriverInterface {
return &pullRequests{} return &pullRequests{}
} }
+6 -5
View File
@@ -14,6 +14,7 @@ import (
"code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" "code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util" f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -46,7 +47,7 @@ func (o *reaction) ToFormat() f3.Interface {
} }
return &f3.Reaction{ return &f3.Reaction{
Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoReaction.ID)), Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoReaction.ID)),
UserID: f3_tree.NewUserReference(o.forgejoReaction.User.ID), UserID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoReaction.User.ID)),
Content: o.forgejoReaction.Type, Content: o.forgejoReaction.Type,
} }
} }
@@ -89,7 +90,7 @@ func (o *reaction) Patch(ctx context.Context) {
} }
func (o *reaction) Put(ctx context.Context) f3_id.NodeID { func (o *reaction) Put(ctx context.Context) f3_id.NodeID {
o.Trace("%v", o.forgejoReaction.User) o.Trace("%+v", o.forgejoReaction.User)
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
@@ -97,20 +98,20 @@ func (o *reaction) Put(ctx context.Context) f3_id.NodeID {
reactionableID := f3_tree.GetReactionableID(o.GetNode()) reactionableID := f3_tree.GetReactionableID(o.GetNode())
switch reactionable.GetKind() { switch reactionable.GetKind() {
case f3_tree.KindIssue, f3_tree.KindPullRequest: case f3_kind.KindIssue, f3_kind.KindPullRequest:
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(o.GetNode())
issue, err := issues_model.GetIssueByIndex(ctx, project, reactionableID) issue, err := issues_model.GetIssueByIndex(ctx, project, reactionableID)
if err != nil { if err != nil {
panic(fmt.Errorf("GetIssueByIndex %v %w", reactionableID, err)) panic(fmt.Errorf("GetIssueByIndex %v %w", reactionableID, err))
} }
o.forgejoReaction.IssueID = issue.ID o.forgejoReaction.IssueID = issue.ID
case f3_tree.KindComment: case f3_kind.KindComment:
o.forgejoReaction.CommentID = reactionableID o.forgejoReaction.CommentID = reactionableID
default: default:
panic(fmt.Errorf("unexpected type %v", reactionable.GetKind())) panic(fmt.Errorf("unexpected type %v", reactionable.GetKind()))
} }
o.Trace("%v", o.forgejoReaction) o.Trace("%+v", o.forgejoReaction)
if _, err := sess.Insert(o.forgejoReaction); err != nil { if _, err := sess.Insert(o.forgejoReaction); err != nil {
panic(err) panic(err)
+10 -9
View File
@@ -11,8 +11,9 @@ import (
"forgejo.org/models/db" "forgejo.org/models/db"
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
"xorm.io/builder" "xorm.io/builder"
) )
@@ -20,23 +21,23 @@ type reactions struct {
container container
} }
func (o *reactions) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *reactions) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
reactionable := f3_tree.GetReactionable(o.GetNode()) reactionable := f3_tree.GetReactionable(node)
reactionableID := f3_tree.GetReactionableID(o.GetNode()) reactionableID := f3_tree.GetReactionableID(node)
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
cond := builder.NewCond() cond := builder.NewCond()
switch reactionable.GetKind() { switch reactionable.GetKind() {
case f3_tree.KindIssue, f3_tree.KindPullRequest: case f3_kind.KindIssue, f3_kind.KindPullRequest:
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
issue, err := issues_model.GetIssueByIndex(ctx, project, reactionableID) issue, err := issues_model.GetIssueByIndex(ctx, project, reactionableID)
if err != nil { if err != nil {
panic(fmt.Errorf("GetIssueByIndex %v %w", reactionableID, err)) panic(fmt.Errorf("GetIssueByIndex %v %w", reactionableID, err))
} }
cond = cond.And(builder.Eq{"reaction.issue_id": issue.ID}) cond = cond.And(builder.Eq{"reaction.issue_id": issue.ID})
case f3_tree.KindComment: case f3_kind.KindComment:
cond = cond.And(builder.Eq{"reaction.comment_id": reactionableID}) cond = cond.And(builder.Eq{"reaction.comment_id": reactionableID})
default: default:
panic(fmt.Errorf("unexpected type %v", reactionable.GetKind())) panic(fmt.Errorf("unexpected type %v", reactionable.GetKind()))
@@ -51,9 +52,9 @@ func (o *reactions) ListPage(ctx context.Context, page int) generic.ChildrenSlic
panic(fmt.Errorf("error while listing reactions: %v", err)) panic(fmt.Errorf("error while listing reactions: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(reactions...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(reactions...)...)
} }
func newReactions() generic.NodeDriverInterface { func newReactions() f3_tree_generic.NodeDriverInterface {
return &reactions{} return &reactions{}
} }
+1 -1
View File
@@ -56,7 +56,7 @@ func (o *release) ToFormat() f3.Interface {
Body: o.forgejoRelease.Note, Body: o.forgejoRelease.Note,
Draft: o.forgejoRelease.IsDraft, Draft: o.forgejoRelease.IsDraft,
Prerelease: o.forgejoRelease.IsPrerelease, Prerelease: o.forgejoRelease.IsPrerelease,
PublisherID: f3_tree.NewUserReference(o.forgejoRelease.Publisher.ID), PublisherID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoRelease.Publisher.ID)),
Created: o.forgejoRelease.CreatedUnix.AsTime(), Created: o.forgejoRelease.CreatedUnix.AsTime(),
} }
} }
+5 -5
View File
@@ -12,17 +12,17 @@ import (
repo_model "forgejo.org/models/repo" repo_model "forgejo.org/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type releases struct { type releases struct {
container container
} }
func (o *releases) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *releases) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
forgejoReleases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ forgejoReleases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{
ListOptions: db.ListOptions{Page: page, PageSize: pageSize}, ListOptions: db.ListOptions{Page: page, PageSize: pageSize},
@@ -34,9 +34,9 @@ func (o *releases) ListPage(ctx context.Context, page int) generic.ChildrenSlice
panic(fmt.Errorf("error while listing releases: %v", err)) panic(fmt.Errorf("error while listing releases: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoReleases...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoReleases...)...)
} }
func newReleases() generic.NodeDriverInterface { func newReleases() f3_tree_generic.NodeDriverInterface {
return &releases{} return &releases{}
} }
+7 -7
View File
@@ -9,28 +9,28 @@ import (
"code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/f3"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type repositories struct { type repositories struct {
container container
} }
func (o *repositories) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *repositories) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
children := generic.NewChildrenSlice(0) children := f3_tree_generic.NewChildrenList(0)
if page > 1 { if page > 1 {
return children return children
} }
names := []string{f3.RepositoryNameDefault} names := []string{f3.RepositoryNameDefault}
project := f3_tree.GetProject(o.GetNode()).ToFormat().(*f3.Project) project := f3_tree.GetProject(node).ToFormat().(*f3.Project)
if project.HasWiki { if project.HasWiki {
names = append(names, f3.RepositoryNameWiki) names = append(names, RepositoryNameWiki)
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(names...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(names...)...)
} }
func newRepositories() generic.NodeDriverInterface { func newRepositories() f3_tree_generic.NodeDriverInterface {
return &repositories{} return &repositories{}
} }
+7 -1
View File
@@ -76,10 +76,12 @@ func (o *repository) SetFetchFunc(fetchFunc func(ctx context.Context, destinatio
o.f.FetchFunc = fetchFunc o.f.FetchFunc = fetchFunc
} }
const RepositoryNameWiki = "vcs.wiki"
func (o *repository) getURL() string { func (o *repository) getURL() string {
owner := f3_tree.GetOwnerName(o.GetNode()) owner := f3_tree.GetOwnerName(o.GetNode())
repoName := f3_tree.GetProjectName(o.GetNode()) repoName := f3_tree.GetProjectName(o.GetNode())
if o.f.GetID() == f3.RepositoryNameWiki { if o.f.GetID() == RepositoryNameWiki {
repoName += ".wiki" repoName += ".wiki"
} }
return repo_model.RepoPath(owner, repoName) return repo_model.RepoPath(owner, repoName)
@@ -89,6 +91,10 @@ func (o *repository) GetRepositoryURL() string {
return o.getURL() return o.getURL()
} }
func (o *repository) Delete(ctx context.Context) {
o.Trace("ignore attempt to delete repository")
}
func (o *repository) GetRepositoryPushURL() string { func (o *repository) GetRepositoryPushURL() string {
return o.getURL() return o.getURL()
} }
+2 -2
View File
@@ -48,7 +48,7 @@ func (o *review) ToFormat() f3.Interface {
review := &f3.Review{ review := &f3.Review{
Common: f3.NewCommon(o.GetNativeID()), Common: f3.NewCommon(o.GetNativeID()),
ReviewerID: f3_tree.NewUserReference(o.forgejoReview.ReviewerID), ReviewerID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoReview.ReviewerID)),
Official: o.forgejoReview.Official, Official: o.forgejoReview.Official,
CommitID: o.forgejoReview.CommitID, CommitID: o.forgejoReview.CommitID,
Content: o.forgejoReview.Content, Content: o.forgejoReview.Content,
@@ -71,7 +71,7 @@ func (o *review) ToFormat() f3.Interface {
} }
if o.forgejoReview.Reviewer != nil { if o.forgejoReview.Reviewer != nil {
review.ReviewerID = f3_tree.NewUserReference(o.forgejoReview.Reviewer.ID) review.ReviewerID = f3_tree.NewUserReference(f3_util.ToString(o.forgejoReview.Reviewer.ID))
} }
return review return review
+1 -1
View File
@@ -57,7 +57,7 @@ func (o *reviewComment) ToFormat() f3.Interface {
return &f3.ReviewComment{ return &f3.ReviewComment{
Common: f3.NewCommon(o.GetNativeID()), Common: f3.NewCommon(o.GetNativeID()),
PosterID: f3_tree.NewUserReference(o.forgejoReviewComment.Poster.ID), PosterID: f3_tree.NewUserReference(f3_util.ToString(o.forgejoReviewComment.Poster.ID)),
Content: o.forgejoReviewComment.Content, Content: o.forgejoReviewComment.Content,
TreePath: o.forgejoReviewComment.TreePath, TreePath: o.forgejoReviewComment.TreePath,
DiffHunk: patch2diff(o.forgejoReviewComment.PatchQuoted), DiffHunk: patch2diff(o.forgejoReviewComment.PatchQuoted),
+5 -5
View File
@@ -12,17 +12,17 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type reviewComments struct { type reviewComments struct {
container container
} }
func (o *reviewComments) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *reviewComments) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
id := f3_tree.GetReviewID(o.GetNode()) id := f3_tree.GetReviewID(node)
sess := db.GetEngine(ctx). sess := db.GetEngine(ctx).
Table("comment"). Table("comment").
@@ -35,9 +35,9 @@ func (o *reviewComments) ListPage(ctx context.Context, page int) generic.Childre
panic(fmt.Errorf("error while listing reviewComments: %v", err)) panic(fmt.Errorf("error while listing reviewComments: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoReviewComments...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoReviewComments...)...)
} }
func newReviewComments() generic.NodeDriverInterface { func newReviewComments() f3_tree_generic.NodeDriverInterface {
return &reviewComments{} return &reviewComments{}
} }
+6 -6
View File
@@ -12,18 +12,18 @@ import (
issues_model "forgejo.org/models/issues" issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type reviews struct { type reviews struct {
container container
} }
func (o *reviews) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *reviews) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
project := f3_tree.GetProjectID(o.GetNode()) project := f3_tree.GetProjectID(node)
pullRequest := f3_tree.GetPullRequestID(o.GetNode()) pullRequest := f3_tree.GetPullRequestID(node)
issue, err := issues_model.GetIssueByIndex(ctx, project, pullRequest) issue, err := issues_model.GetIssueByIndex(ctx, project, pullRequest)
if err != nil { if err != nil {
@@ -41,9 +41,9 @@ func (o *reviews) ListPage(ctx context.Context, page int) generic.ChildrenSlice
panic(fmt.Errorf("error while listing reviews: %v", err)) panic(fmt.Errorf("error while listing reviews: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(forgejoReviews...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(forgejoReviews...)...)
} }
func newReviews() generic.NodeDriverInterface { func newReviews() f3_tree_generic.NodeDriverInterface {
return &reviews{} return &reviews{}
} }
+2 -1
View File
@@ -16,6 +16,7 @@ import (
func newTestOptions(_ *testing.T) options.Interface { func newTestOptions(_ *testing.T) options.Interface {
o := options.GetFactory(driver_options.Name)().(*driver_options.Options) o := options.GetFactory(driver_options.Name)().(*driver_options.Options)
o.SetLogger(util.NewF3Logger(nil, forgejo_log.GetLogger(forgejo_log.DEFAULT))) l := forgejo_log.GetLogger(forgejo_log.DEFAULT)
o.SetLogger(util.NewF3Logger(nil, l))
return o return o
} }
+4 -4
View File
@@ -12,14 +12,14 @@ import (
repo_model "forgejo.org/models/repo" repo_model "forgejo.org/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type topics struct { type topics struct {
container container
} }
func (o *topics) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *topics) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
pageSize := o.getPageSize() pageSize := o.getPageSize()
sess := db.GetEngine(ctx) sess := db.GetEngine(ctx)
@@ -33,9 +33,9 @@ func (o *topics) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
panic(fmt.Errorf("error while listing topics: %v", err)) panic(fmt.Errorf("error while listing topics: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(topics...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(topics...)...)
} }
func newTopics() generic.NodeDriverInterface { func newTopics() f3_tree_generic.NodeDriverInterface {
return &topics{} return &topics{}
} }
+31 -31
View File
@@ -27,67 +27,67 @@ func (o *treeDriver) Init() {
func (o *treeDriver) Factory(ctx context.Context, kind f3_kind.Kind) generic.NodeDriverInterface { func (o *treeDriver) Factory(ctx context.Context, kind f3_kind.Kind) generic.NodeDriverInterface {
switch kind { switch kind {
case f3_tree.KindForge: case f3_kind.KindForge:
return newForge() return newForge()
case f3_tree.KindOrganizations: case f3_kind.KindOrganizations:
return newOrganizations() return newOrganizations()
case f3_tree.KindOrganization: case f3_kind.KindOrganization:
return newOrganization() return newOrganization()
case f3_tree.KindUsers: case f3_kind.KindUsers:
return newUsers() return newUsers()
case f3_tree.KindUser: case f3_kind.KindUser:
return newUser() return newUser()
case f3_tree.KindProjects: case f3_kind.KindProjects:
return newProjects() return newProjects()
case f3_tree.KindProject: case f3_kind.KindProject:
return newProject() return newProject()
case f3_tree.KindIssues: case f3_kind.KindIssues:
return newIssues() return newIssues()
case f3_tree.KindIssue: case f3_kind.KindIssue:
return newIssue() return newIssue()
case f3_tree.KindComments: case f3_kind.KindComments:
return newComments() return newComments()
case f3_tree.KindComment: case f3_kind.KindComment:
return newComment() return newComment()
case f3_tree.KindAttachments: case f3_kind.KindAttachments:
return newAttachments() return newAttachments()
case f3_tree.KindAttachment: case f3_kind.KindAttachment:
return newAttachment() return newAttachment()
case f3_tree.KindLabels: case f3_kind.KindLabels:
return newLabels() return newLabels()
case f3_tree.KindLabel: case f3_kind.KindLabel:
return newLabel() return newLabel()
case f3_tree.KindReactions: case f3_kind.KindReactions:
return newReactions() return newReactions()
case f3_tree.KindReaction: case f3_kind.KindReaction:
return newReaction() return newReaction()
case f3_tree.KindReviews: case f3_kind.KindReviews:
return newReviews() return newReviews()
case f3_tree.KindReview: case f3_kind.KindReview:
return newReview() return newReview()
case f3_tree.KindReviewComments: case f3_kind.KindReviewComments:
return newReviewComments() return newReviewComments()
case f3_tree.KindReviewComment: case f3_kind.KindReviewComment:
return newReviewComment() return newReviewComment()
case f3_tree.KindMilestones: case f3_kind.KindMilestones:
return newMilestones() return newMilestones()
case f3_tree.KindMilestone: case f3_kind.KindMilestone:
return newMilestone() return newMilestone()
case f3_tree.KindPullRequests: case f3_kind.KindPullRequests:
return newPullRequests() return newPullRequests()
case f3_tree.KindPullRequest: case f3_kind.KindPullRequest:
return newPullRequest() return newPullRequest()
case f3_tree.KindReleases: case f3_kind.KindReleases:
return newReleases() return newReleases()
case f3_tree.KindRelease: case f3_kind.KindRelease:
return newRelease() return newRelease()
case f3_tree.KindTopics: case f3_kind.KindTopics:
return newTopics() return newTopics()
case f3_tree.KindTopic: case f3_kind.KindTopic:
return newTopic() return newTopic()
case f3_tree.KindRepositories: case f3_kind.KindRepositories:
return newRepositories() return newRepositories()
case f3_tree.KindRepository: case f3_kind.KindRepository:
return newRepository(ctx) return newRepository(ctx)
case f3_kind.KindRoot: case f3_kind.KindRoot:
return newRoot(o.GetTree().(f3_tree.TreeInterface).NewFormat(kind)) return newRoot(o.GetTree().(f3_tree.TreeInterface).NewFormat(kind))
+21 -1
View File
@@ -28,6 +28,19 @@ type user struct {
forgejoUser *user_model.User forgejoUser *user_model.User
} }
const fakeEmailSuffix = ".fakeemail"
func fromFakeEmail(mail string) string {
return strings.TrimSuffix(mail, fakeEmailSuffix)
}
func toFakeEmail(mail string) string {
if !strings.HasSuffix(mail, fakeEmailSuffix) {
return mail + fakeEmailSuffix
}
return mail
}
func getSystemUserByName(name string) *user_model.User { func getSystemUserByName(name string) *user_model.User {
switch name { switch name {
case user_model.GhostUserName: case user_model.GhostUserName:
@@ -90,6 +103,7 @@ func (o *user) Get(ctx context.Context) bool {
if err != nil { if err != nil {
panic(fmt.Errorf("user %v %w", id, err)) panic(fmt.Errorf("user %v %w", id, err))
} }
u.Email = fromFakeEmail(u.Email)
o.forgejoUser = u o.forgejoUser = u
return true return true
} }
@@ -103,7 +117,8 @@ func (o *user) Put(ctx context.Context) f3_id.NodeID {
} }
o.forgejoUser.LowerName = strings.ToLower(o.forgejoUser.Name) o.forgejoUser.LowerName = strings.ToLower(o.forgejoUser.Name)
o.Trace("%v", *o.forgejoUser) o.forgejoUser.Email = toFakeEmail(o.forgejoUser.Email)
o.Trace("%+v", *o.forgejoUser)
overwriteDefault := &user_model.CreateUserOverwriteOptions{ overwriteDefault := &user_model.CreateUserOverwriteOptions{
IsActive: optional.Some(true), IsActive: optional.Some(true),
} }
@@ -119,6 +134,11 @@ func (o *user) Delete(ctx context.Context) {
node := o.GetNode() node := o.GetNode()
o.Trace("%s", node.GetID()) o.Trace("%s", node.GetID())
if o.forgejoUser.ID == 1 && o.forgejoUser.IsAdmin {
o.Debug("silently ignore a request to delete the admin user with ID 1 because it is assumed to be required: %+v", o.forgejoUser.Type)
return
}
if err := user_service.DeleteUser(ctx, o.forgejoUser, true); err != nil { if err := user_service.DeleteUser(ctx, o.forgejoUser, true); err != nil {
panic(err) panic(err)
} }
+14 -5
View File
@@ -11,16 +11,17 @@ import (
"forgejo.org/models/db" "forgejo.org/models/db"
user_model "forgejo.org/models/user" user_model "forgejo.org/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
f3_id "code.forgejo.org/f3/gof3/v3/id" f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic" f3_tree_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
) )
type users struct { type users struct {
container container
} }
func (o *users) ListPage(ctx context.Context, page int) generic.ChildrenSlice { func (o *users) ListPage(ctx context.Context, node f3_tree_generic.NodeInterface, _ f3_tree_generic.ListOptions, page int) f3_tree_generic.ChildrenList {
sess := db.GetEngine(ctx).In("type", user_model.UserTypeIndividual, user_model.UserTypeRemoteUser) sess := db.GetEngine(ctx).In("type", user_model.UserTypeIndividual, user_model.UserTypeRemoteUser)
if page != 0 { if page != 0 {
sess = db.SetSessionPagination(sess, &db.ListOptions{Page: page, PageSize: o.getPageSize()}) sess = db.SetSessionPagination(sess, &db.ListOptions{Page: page, PageSize: o.getPageSize()})
@@ -32,18 +33,26 @@ func (o *users) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
panic(fmt.Errorf("error while listing users: %v", err)) panic(fmt.Errorf("error while listing users: %v", err))
} }
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(users...)...) return f3_tree.ConvertListed(ctx, node, f3_tree.ConvertToAny(users...)...)
}
func (o *users) LookupMappedID(ctx context.Context, id f3_id.NodeID, f f3.Interface) f3_id.NodeID {
user := f.(*f3.User)
return o.GetIDFromName(ctx, user.UserName)
} }
func (o *users) GetIDFromName(ctx context.Context, name string) f3_id.NodeID { func (o *users) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
user, err := user_model.GetUserByName(ctx, name) user, err := user_model.GetUserByName(ctx, name)
if user_model.IsErrUserNotExist(err) {
return f3_id.NilID
}
if err != nil { if err != nil {
panic(fmt.Errorf("GetUserByName: %v", err)) panic(fmt.Errorf("GetUserByName(%s): %v", name, err))
} }
return f3_id.NewNodeID(user.ID) return f3_id.NewNodeID(user.ID)
} }
func newUsers() generic.NodeDriverInterface { func newUsers() f3_tree_generic.NodeDriverInterface {
return &users{} return &users{}
} }
+1 -1
View File
@@ -29,7 +29,7 @@ func TestNodeinfo(t *testing.T) {
DecodeJSON(t, resp, &nodeinfo) DecodeJSON(t, resp, &nodeinfo)
assert.True(t, nodeinfo.OpenRegistrations) assert.True(t, nodeinfo.OpenRegistrations)
assert.Equal(t, "forgejo", nodeinfo.Software.Name) assert.Equal(t, "forgejo", nodeinfo.Software.Name)
assert.Equal(t, 29, nodeinfo.Usage.Users.Total) assert.Equal(t, 30, nodeinfo.Usage.Users.Total)
assert.Equal(t, 23, nodeinfo.Usage.LocalPosts) assert.Equal(t, 23, nodeinfo.Usage.LocalPosts)
assert.Equal(t, 4, nodeinfo.Usage.LocalComments) assert.Equal(t, 4, nodeinfo.Usage.LocalComments)
} }
+14 -26
View File
@@ -24,6 +24,7 @@ import (
f3_generic "code.forgejo.org/f3/gof3/v3/tree/generic" f3_generic "code.forgejo.org/f3/gof3/v3/tree/generic"
f3_tests "code.forgejo.org/f3/gof3/v3/tree/tests/f3" f3_tests "code.forgejo.org/f3/gof3/v3/tree/tests/f3"
f3_tests_forge "code.forgejo.org/f3/gof3/v3/tree/tests/f3/forge" f3_tests_forge "code.forgejo.org/f3/gof3/v3/tree/tests/f3/forge"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v3"
) )
@@ -61,14 +62,14 @@ func TestF3_CmdMirror_LocalForgejo(t *testing.T) {
ctx := t.Context() ctx := t.Context()
mirrorOptions := f3_tests_forge.GetFactory(options.Name)().NewOptions(t) mirrorForge := f3_tests_forge.GetFactory(options.Name)()
mirrorOptions := mirrorForge.NewOptions(t)
mirrorTree := f3_generic.GetFactory("f3")(ctx, mirrorOptions) mirrorTree := f3_generic.GetFactory("f3")(ctx, mirrorOptions)
fixtureOptions := f3_tests_forge.GetFactory(f3_filesystem_options.Name)().NewOptions(t) fixtureOptions := f3_tests_forge.GetFactory(f3_filesystem_options.Name)().NewOptions(t)
fixtureTree := f3_generic.GetFactory("f3")(ctx, fixtureOptions) fixtureTree := f3_generic.GetFactory("f3")(ctx, fixtureOptions)
log := fixtureTree.GetLogger() log := fixtureTree.GetLogger()
creator := f3_tests.NewCreator(t, "CmdMirrorLocalForgejo", log)
log.Trace("======= build fixture") log.Trace("======= build fixture")
@@ -77,9 +78,10 @@ func TestF3_CmdMirror_LocalForgejo(t *testing.T) {
fixtureUserID := "userID01" fixtureUserID := "userID01"
fixtureProjectID := "projectID01" fixtureProjectID := "projectID01"
creator := f3_tests.NewCreator(t, "CMFixture", fixtureTree)
userFormat := creator.GenerateUser() userFormat := creator.GenerateUser()
userFormat.SetID(fixtureUserID) userFormat.SetID(fixtureUserID)
users := fixtureTree.MustFind(f3_generic.NewPathFromString("/forge/users")) users := fixtureTree.MustFind(f3_generic.NewNodePathFromString("/forge/users"))
user := users.CreateChild(ctx) user := users.CreateChild(ctx)
user.FromFormat(userFormat) user.FromFormat(userFormat)
user.Upsert(ctx) user.Upsert(ctx)
@@ -87,7 +89,7 @@ func TestF3_CmdMirror_LocalForgejo(t *testing.T) {
projectFormat := creator.GenerateProject() projectFormat := creator.GenerateProject()
projectFormat.SetID(fixtureProjectID) projectFormat.SetID(fixtureProjectID)
projects := user.MustFind(f3_generic.NewPathFromString("projects")) projects := f3_generic.MustFind(user, f3_generic.NewNodePathFromString("projects"))
project := projects.CreateChild(ctx) project := projects.CreateChild(ctx)
project.FromFormat(projectFormat) project.FromFormat(projectFormat)
project.Upsert(ctx) project.Upsert(ctx)
@@ -98,25 +100,8 @@ func TestF3_CmdMirror_LocalForgejo(t *testing.T) {
log.Trace("======= create mirror") log.Trace("======= create mirror")
var toPath string otherProjectName := "otherproject"
var projects f3_generic.NodeInterface toPath := "/forge/users/otheruser/projects/" + otherProjectName
{
userFormat := creator.GenerateUser()
users := mirrorTree.MustFind(f3_generic.NewPathFromString("/forge/users"))
user := users.CreateChild(ctx)
user.FromFormat(userFormat)
user.Upsert(ctx)
require.Equal(t, user.GetID(), users.GetIDFromName(ctx, userFormat.UserName))
projectFormat := creator.GenerateProject()
projects = user.MustFind(f3_generic.NewPathFromString("projects"))
project := projects.CreateChild(ctx)
project.FromFormat(projectFormat)
project.Upsert(ctx)
require.Equal(t, project.GetID(), projects.GetIDFromName(ctx, projectFormat.Name))
toPath = fmt.Sprintf("/forge/users/%s/projects/%s", userFormat.UserName, projectFormat.Name)
}
log.Trace("======= mirror %s => %s", fromPath, toPath) log.Trace("======= mirror %s => %s", fromPath, toPath)
output, err := runApp(ctx, output, err := runApp(ctx,
@@ -131,7 +116,10 @@ func TestF3_CmdMirror_LocalForgejo(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
log.Trace("======= assert") log.Trace("======= assert")
require.Contains(t, output, fmt.Sprintf("mirror %s", fromPath)) require.Contains(t, output, fmt.Sprintf("mirror %s", fromPath))
projects.List(ctx) project := f3_generic.NilNode
require.NotEmpty(t, projects.GetChildren()) mirrorTree.ApplyAndGet(ctx, f3_generic.NewNodePathFromString(toPath), f3_generic.NewApplyOptions(func(ctx context.Context, parent, p f3_generic.Path, node f3_generic.NodeInterface) {
log.Trace("======= project %s", projects.GetChildren()[0]) project = node
}))
require.NotEqual(t, f3_generic.NilNode, project)
assert.Equal(t, otherProjectName, project.GetName())
} }