// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package repository import ( "context" "os" "runtime" "code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/id" "code.forgejo.org/f3/gof3/v3/logger" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" "code.forgejo.org/f3/gof3/v3/tree/generic" "code.forgejo.org/f3/gof3/v3/util" ) type Interface interface { f3_tree.RepositoryDriverInterface Upsert(context.Context, *f3.Repository) id.NodeID Get(context.Context) bool Fetch(context.Context) string } type repositoryInterface interface { logger.MessageInterface f3_tree.RepositoryDriverInterface GetNode() generic.NodeInterface ToFormat() f3.Interface SetFetchFunc(func(ctx context.Context, destination string, internalRefs []string)) } type helper struct { r repositoryInterface dir *string } func (o *helper) getDir() string { if o.dir == nil { dir, err := os.MkdirTemp("", "repositoryHelper") if err != nil { panic(err) } runtime.SetFinalizer(o, func(o *helper) { err := os.RemoveAll(dir) if err != nil { panic(err) } }) o.dir = &dir } return *o.dir } func (o *helper) GetRepositoryURL() string { return o.r.GetRepositoryURL() } func (o *helper) GetRepositoryPushURL() string { return o.r.GetRepositoryPushURL() } func (o *helper) GetRepositoryInternalRefs() []string { return o.r.GetRepositoryInternalRefs() } func (o *helper) Fetch(ctx context.Context) string { to := o.getDir() o.r.Trace("%s", to) if err := util.CommandWithErr(ctx, util.CommandOptions{}, "git", "-C", to, "rev-parse", "--is-bare-repository"); err != nil { o.r.Trace(util.Command(ctx, o.r, "git", "-C", to, "init", "--bare")) } from := o.r.GetRepositoryURL() GitMirror(ctx, o.r, from, to, []string{}) return to } func (o *helper) Get(ctx context.Context) bool { from := o.r.GetRepositoryURL() o.r.Trace("%s", from) o.r.SetFetchFunc(func(ctx context.Context, destination string, internalRefs []string) { o.r.Trace("git clone %s %s", from, destination) GitMirror(ctx, o.r, from, destination, internalRefs) }) return true } func (o *helper) Upsert(ctx context.Context, f *f3.Repository) id.NodeID { if f.FetchFunc != nil { to := o.r.GetRepositoryPushURL() internalRefs := o.r.GetRepositoryInternalRefs() o.r.Trace("%s", to) f.FetchFunc(ctx, to, internalRefs) } else { o.r.Trace("NO FETCH %s", o.r.GetRepositoryPushURL()) panic("") } return o.r.GetNode().GetID() } func NewHelper(r repositoryInterface) Interface { h := &helper{r: r} return h }