137 lines
4.0 KiB
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)
|
|
}
|
|
}
|