eclipse/cmd/eclipse-gitcache/main.go

137 lines
4.0 KiB
Go

// Copyright (C) 2024 Umorpha Systems
// SPDX-License-Identifier: AGPL-3.0-or-later
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/datawire/ocibuild/pkg/cliutil"
"github.com/spf13/cobra"
source "git.mothstuff.lol/lukeshu/eclipse"
"git.mothstuff.lol/lukeshu/eclipse/lib/gitcache"
)
func main() {
argparser := &cobra.Command{
Use: os.Args[0] + " {[flags]|SUBCOMMAND...}",
Short: "Directly interact with a gitcache",
Args: cliutil.WrapPositionalArgs(cliutil.OnlySubcommands),
RunE: cliutil.RunSubcommands,
SilenceErrors: true, // we'll handle this ourselves after .ExecuteContext()
SilenceUsage: true, // FlagErrorFunc will handle this
CompletionOptions: cobra.CompletionOptions{
DisableDefaultCmd: true,
},
}
argparser.SetFlagErrorFunc(cliutil.FlagErrorFunc)
argparser.SetHelpTemplate(cliutil.HelpTemplate)
var cache gitcache.Cache
argparser.PersistentFlags().StringVarP(&cache.Dir, "cache-dir", "d", source.DefaultGitCacheDir,
"Where to store cached data")
_ = argparser.MarkFlagDirname("cache-dir")
argparser.PersistentFlags().DurationVar(&cache.MinPeriod, "min-interval", 5*time.Second,
"Do not fetch from the same remote more often than this")
argparser.AddCommand(&cobra.Command{
Use: "fetch [flags] URL",
Short: "Update the cache's store of the repository at URL",
Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)),
RunE: func(_ *cobra.Command, args []string) error {
return cache.Fetch(os.Stderr, args[0])
},
})
var noFetch bool
revParse := &cobra.Command{
Use: "rev-parse [flags] URL REVS...",
Short: "Resolve each REV to an object ID within the repository at URL",
Args: cliutil.WrapPositionalArgs(cobra.MinimumNArgs(2)),
RunE: func(_ *cobra.Command, args []string) error {
if !noFetch {
if err := cache.Fetch(os.Stderr, args[0]); err != nil {
fmt.Fprintf(os.Stderr, "[gitcache] Ignoring update error: %v\n", err)
}
}
objIDs, err := cache.RevParse(os.Stderr, args[0], args[1:]...)
if err != nil {
return err
}
failed := 0
for _, objID := range objIDs {
if objID == "" {
failed++
}
fmt.Println(objID)
}
if failed > 0 {
return fmt.Errorf("failed to resolve %d revision(s)", failed)
}
return nil
},
}
revParse.Flags().BoolVar(&noFetch, "no-fetch", false,
"Do not attempt to update the cache before resolving the rev")
argparser.AddCommand(revParse)
clone := &cobra.Command{
Use: "clone [flags] URL DIR [-- GIT_CLONE_FLAGS...]",
Short: "Clone the repository at URL from the cache to DIR",
Args: cliutil.WrapPositionalArgs(cobra.MinimumNArgs(2)),
RunE: func(cmd *cobra.Command, args []string) error {
if !noFetch {
if err := cache.Fetch(os.Stderr, args[0]); err != nil {
fmt.Fprintf(os.Stderr, "[gitcache] Ignoring update error: %v\n", err)
}
}
return cache.Clone(os.Stderr, args[0], args[1], args[2:]...)
},
}
clone.Flags().BoolVar(&noFetch, "no-fetch", false,
"Do not attempt to update the cache before cloning")
argparser.AddCommand(clone)
argparser.AddCommand(&cobra.Command{
Use: "maintenance [flags] [-- GIT_MAINTENANCE_FLAGS...]",
Short: "Run Git maintenance tasks (a la `git-maintenance run`)",
RunE: func(cmd *cobra.Command, args []string) error {
return cache.Maintenance(os.Stderr, args...)
},
})
argparser.AddCommand(&cobra.Command{
Use: "url2ns [flags] URL",
Short: "Convert a URL to a cache namespace",
Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)),
RunE: func(_ *cobra.Command, args []string) error {
fmt.Println(gitcache.URL2NS(args[0]))
return nil
},
})
argparser.AddCommand(&cobra.Command{
Use: "ns2url [flags] URL",
Short: "Convert cache namespace to a URL",
Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)),
RunE: func(_ *cobra.Command, args []string) error {
fmt.Println(gitcache.NS2URL(args[0]))
return nil
},
})
ctx := context.Background()
if err := argparser.ExecuteContext(ctx); err != nil {
fmt.Fprintf(os.Stderr, "%v: error: %v\n", argparser.CommandPath(), err)
os.Exit(1)
}
}