1
0
Fork 0
golang-forgejo-f3-gof3/cmd/mirror.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

129 lines
3.6 KiB
Go

// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"fmt"
"code.forgejo.org/f3/gof3/v3/logger"
"code.forgejo.org/f3/gof3/v3/options"
"code.forgejo.org/f3/gof3/v3/path"
"code.forgejo.org/f3/gof3/v3/tree/generic"
"code.forgejo.org/f3/gof3/v3/util"
"github.com/urfave/cli/v3"
)
var (
directionFrom = "from"
flagFrom = "--" + directionFrom
directionTo = "to"
flagTo = "--" + directionTo
)
func BuildForgePrefix(prefix, forge string) string {
return prefix + "-" + forge
}
func FlagsToTree(ctx context.Context, c *cli.Command, direction string) generic.TreeInterface {
forgeType := c.String(ForgeTypeOption(direction))
opts := options.GetFactory(forgeType)()
opts.(options.LoggerInterface).SetLogger(logger.ContextGetLogger(ctx))
if o, ok := opts.(options.CLIInterface); ok {
o.FromFlags(ctx, c, BuildForgePrefix(direction, forgeType))
} else {
panic("not implemented")
}
return generic.GetFactory("f3")(ctx, opts)
}
func CreateCmdMirror() *cli.Command {
flags := make([]cli.Flag, 0, 10)
for _, direction := range []string{"from", "to"} {
flags = append(flags, GetFlagsCommon(direction, "common")...)
for name, factory := range options.GetFactories() {
if opts, ok := factory().(options.CLIInterface); ok {
flags = append(flags, opts.GetFlags(BuildForgePrefix(direction, name), name)...)
}
}
}
flags = func(flags []cli.Flag) []cli.Flag {
dedup := make([]cli.Flag, 0, 10)
names := make(map[string]any, 10)
flagLoop:
for _, flag := range flags {
for _, name := range flag.Names() {
_, found := names[name]
if found {
continue flagLoop
}
}
dedup = append(dedup, flag)
for _, name := range flag.Names() {
names[name] = nil
}
}
return dedup
}(flags)
return &cli.Command{
Name: "mirror",
Usage: "Mirror",
Description: "Mirror",
Action: func(ctx context.Context, c *cli.Command) error {
return util.PanicToError(func() { runMirror(ctx, c) })
},
Flags: flags,
}
}
func runMirror(ctx context.Context, c *cli.Command) {
from := FlagsToTree(ctx, c, directionFrom)
to := FlagsToTree(ctx, c, directionTo)
fromPathString := c.String(BuildForgePrefix(directionFrom, "path"))
fromPath := generic.NewPathFromString(fromPathString)
toPathString := c.String(BuildForgePrefix(directionTo, "path"))
toPath := generic.NewPathFromString(toPathString)
log := from.GetLogger()
fromURL := "(unset)"
if url, ok := from.GetOptions().(options.URLInterface); ok {
fromURL = url.GetURL()
}
toURL := "(unset)"
if url, ok := to.GetOptions().(options.URLInterface); ok {
toURL = url.GetURL()
}
log.Info("mirror %s (%s at %s) to %s (%s at %s)",
fromPath, c.String(ForgeTypeOption(directionFrom)), fromURL,
toPath, c.String(ForgeTypeOption(directionTo)), toURL,
)
log.Debug("read %s from %T", fromPath, from)
var fromNode generic.NodeInterface
fromNode = generic.NilNode
walkAndGet := func(ctx context.Context, parent, p path.Path, node generic.NodeInterface) {
node.WalkAndGet(ctx, parent, generic.NewWalkOptions(nil))
fromNode = node
}
from.ApplyAndGet(ctx, fromPath, generic.NewApplyOptions(walkAndGet))
if fromNode == generic.NilNode {
panic(fmt.Errorf("from %s not found", fromPath))
}
from.Debug("copy %s from %T to %T", fromPath, from, to)
if toPathString == "" {
generic.TreeMirror(ctx, from, to, fromPath, generic.NewMirrorOptions())
} else {
toNode := to.FindAndGet(ctx, toPath)
if toNode == generic.NilNode {
panic(fmt.Errorf("to %s not found", toPath))
}
generic.NodeMirror(ctx, fromNode, toNode, generic.NewMirrorOptions())
}
}