1
0
Fork 0
golang-forgejo-f3-gof3/forges/gitlab/tree.go
Daniel Baumann 03bfe4079e
Adding upstream version 3.10.8.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-18 09:37:23 +02:00

213 lines
6 KiB
Go

// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// SPDX-License-Identifier: MIT
package gitlab
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
gitlab_options "code.forgejo.org/f3/gof3/v3/forges/gitlab/options"
"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"
"github.com/hashicorp/go-version"
"gitlab.com/gitlab-org/api/client-go"
)
type treeDriver struct {
generic.NullTreeDriver
user *gitlab.User
client *gitlab.Client
options *gitlab_options.Options
version *version.Version
}
func (o *treeDriver) GetClient() *gitlab.Client {
return o.client
}
func (o *treeDriver) GetIsAdmin() bool {
return o.user.IsAdmin
}
func (o *treeDriver) SetIsAdmin() {
user, _, err := o.client.Users.CurrentUser()
if err != nil {
panic(fmt.Errorf("Failed to get information about the user for: %s. Error: %v", o.options.GetURL(), err))
}
o.user = user
o.options.SetUsername(user.Username)
}
var (
ForgejoVersion700 = version.Must(version.NewVersion("7.0.0")) // 1.22
ForgejoVersion600 = version.Must(version.NewVersion("6.0.0")) // 1.21
ForgejoVersion500 = version.Must(version.NewVersion("5.0.0")) // 1.20.1
ForgejoVersion501 = version.Must(version.NewVersion("5.0.1")) // 1.20.2
ForgejoVersion502 = version.Must(version.NewVersion("5.0.2")) // 1.20.3
ForgejoVersion503 = version.Must(version.NewVersion("5.0.3")) // 1.20.4
ForgejoVersion504 = version.Must(version.NewVersion("5.0.4")) // 1.20.5
ForgejoVersion4 = version.Must(version.NewVersion("4.0.0")) // 1.19
ForgejoVersionNotFound = version.Must(version.NewVersion("1.0.0"))
)
func (o *treeDriver) GetVersion() *version.Version {
o.SetVersion()
return o.version
}
func (o *treeDriver) SetVersion() {
if o.version != nil {
return
}
client := &http.Client{}
url := fmt.Sprintf("%s/api/forgejo/v1/version", o.options.GetURL())
req, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(fmt.Errorf("while getting %s %w", url, err))
}
switch resp.StatusCode {
case http.StatusNotFound:
o.version = ForgejoVersionNotFound
case http.StatusOK:
v := struct{ Version string }{}
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(fmt.Errorf("reading response body %+v %w", resp, err))
}
if err := json.Unmarshal(body, &v); err != nil {
panic(fmt.Errorf("decoding JSON response from %s %s %w", url, string(body), err))
}
o.version = version.Must(version.NewVersion(v.Version))
default:
panic(fmt.Errorf("unexpected status code fetching %s %d %v", url, resp.StatusCode, resp))
}
}
func (o *treeDriver) maybeSudo(uid interface{}) []gitlab.RequestOptionFunc {
if !o.GetIsAdmin() {
return []gitlab.RequestOptionFunc{}
}
if name, ok := uid.(string); ok && name == o.options.GetUsername() {
return []gitlab.RequestOptionFunc{}
}
return []gitlab.RequestOptionFunc{
gitlab.WithSudo(uid),
}
}
func (o *treeDriver) Init() {
o.NullTreeDriver.Init()
var err error
var client *gitlab.Client
if o.options.GetToken() != "" {
o.Debug("Connecting to %s with token", o.options.GetURL())
client, err = gitlab.NewClient(o.options.GetToken(), gitlab.WithBaseURL(o.options.GetURL()), gitlab.WithHTTPClient(o.options.GetNewMigrationHTTPClient()()))
} else {
o.Debug("Connecting to %s as user %s", o.options.GetURL(), o.options.GetUsername())
client, err = gitlab.NewBasicAuthClient(o.options.GetUsername(), o.options.GetPassword(), gitlab.WithBaseURL(o.options.GetURL()), gitlab.WithHTTPClient(o.options.GetNewMigrationHTTPClient()()))
}
if err != nil {
panic(fmt.Errorf("Failed to create Forgejo client for: %s. Error: %v", o.options.GetURL(), err))
}
o.client = client
o.SetIsAdmin()
if o.GetIsAdmin() {
o.Debug("Connected as admin")
} else {
o.Debug("Connected as regular user")
}
}
func newTreeDriver(tree generic.TreeInterface, anyOptions any) generic.TreeDriverInterface {
driver := &treeDriver{
options: anyOptions.(*gitlab_options.Options),
}
driver.SetTree(tree)
driver.Init()
return driver
}
func (o *treeDriver) Factory(ctx context.Context, k kind.Kind) generic.NodeDriverInterface {
switch k {
case f3_tree.KindForge:
return newForge()
case f3_tree.KindOrganizations:
return newOrganizations()
case f3_tree.KindOrganization:
return newOrganization()
case f3_tree.KindUsers:
return newUsers()
case f3_tree.KindUser:
return newUser()
case f3_tree.KindProjects:
return newProjects()
// case f3_tree.KindProject:
// return newProject()
// case f3_tree.KindIssues:
// return newIssues()
// case f3_tree.KindIssue:
// return newIssue()
// case f3_tree.KindComments:
// return newComments()
// case f3_tree.KindComment:
// return newComment()
// case f3_tree.KindAssets:
// return newAssets()
// case f3_tree.KindAsset:
// return newAsset()
// case f3_tree.KindLabels:
// return newLabels()
// case f3_tree.KindLabel:
// return newLabel()
// case f3_tree.KindReactions:
// return newReactions()
// case f3_tree.KindReaction:
// return newReaction()
// case f3_tree.KindReviews:
// return newReviews()
// case f3_tree.KindReview:
// return newReview()
// case f3_tree.KindReviewComments:
// return newReviewComments()
// case f3_tree.KindReviewComment:
// return newReviewComment()
// case f3_tree.KindMilestones:
// return newMilestones()
// case f3_tree.KindMilestone:
// return newMilestone()
// case f3_tree.KindPullRequests:
// return newPullRequests()
// case f3_tree.KindPullRequest:
// return newPullRequest()
// case f3_tree.KindReleases:
// return newReleases()
// case f3_tree.KindRelease:
// return newRelease()
case f3_tree.KindTopics:
return newTopics()
// case f3_tree.KindRepositories:
// return newRepositories()
// case f3_tree.KindRepository:
// return newRepository(ctx)
case kind.KindRoot:
return newRoot(o.GetTree().(f3_tree.TreeInterface).NewFormat(k))
default:
panic(fmt.Errorf("unexpected kind %s", k))
}
}