2024-01-11 20:36:03 +00:00
|
|
|
// Copyright (C) 2024 Umorpha Systems
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2024-01-29 02:19:58 +00:00
|
|
|
"sort"
|
2024-01-11 20:36:03 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/datawire/ocibuild/pkg/cliutil"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
2024-01-28 18:00:48 +00:00
|
|
|
source "git.mothstuff.lol/lukeshu/eclipse"
|
2024-01-11 20:36:03 +00:00
|
|
|
"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
|
2024-01-28 18:00:48 +00:00
|
|
|
argparser.PersistentFlags().StringVarP(&cache.Dir, "cache-dir", "d", source.DefaultGitCacheDir,
|
2024-01-11 20:36:03 +00:00
|
|
|
"Where to store cached data")
|
2024-01-20 18:07:48 +00:00
|
|
|
_ = argparser.MarkFlagDirname("cache-dir")
|
2024-01-11 20:45:23 +00:00
|
|
|
argparser.PersistentFlags().DurationVar(&cache.MinPeriod, "min-interval", 5*time.Second,
|
2024-01-11 20:36:03 +00:00
|
|
|
"Do not fetch from the same remote more often than this")
|
|
|
|
|
|
|
|
argparser.AddCommand(&cobra.Command{
|
2024-01-12 19:49:26 +00:00
|
|
|
Use: "fetch [flags] URL",
|
2024-01-11 20:36:03 +00:00
|
|
|
Short: "Update the cache's store of the repository at URL",
|
|
|
|
Args: cliutil.WrapPositionalArgs(cobra.ExactArgs(1)),
|
|
|
|
RunE: func(_ *cobra.Command, args []string) error {
|
2024-01-11 21:46:13 +00:00
|
|
|
return cache.Fetch(os.Stderr, args[0])
|
2024-01-11 20:36:03 +00:00
|
|
|
},
|
|
|
|
})
|
2024-01-13 00:13:26 +00:00
|
|
|
|
|
|
|
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)),
|
2024-01-11 20:36:03 +00:00
|
|
|
RunE: func(_ *cobra.Command, args []string) error {
|
2024-01-29 02:19:58 +00:00
|
|
|
url := args[0]
|
|
|
|
revglobs := args[1:]
|
2024-01-13 00:13:26 +00:00
|
|
|
if !noFetch {
|
2024-01-29 02:19:58 +00:00
|
|
|
if err := cache.Fetch(os.Stderr, url); err != nil {
|
2024-01-13 00:13:26 +00:00
|
|
|
fmt.Fprintf(os.Stderr, "[gitcache] Ignoring update error: %v\n", err)
|
|
|
|
}
|
|
|
|
}
|
2024-01-29 02:19:58 +00:00
|
|
|
|
|
|
|
ret, err := cache.RevParse(os.Stderr, url, revglobs...)
|
2024-01-11 20:36:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-01-29 02:19:58 +00:00
|
|
|
|
2024-01-13 00:13:26 +00:00
|
|
|
failed := 0
|
2024-01-29 02:19:58 +00:00
|
|
|
for _, revglob := range revglobs {
|
|
|
|
matches := ret[revglob]
|
|
|
|
if len(matches) == 0 {
|
2024-01-13 00:13:26 +00:00
|
|
|
failed++
|
|
|
|
}
|
2024-01-29 02:19:58 +00:00
|
|
|
fmt.Printf("%s => (%d)", revglob, len(matches))
|
|
|
|
refnames := make([]string, 0, len(matches))
|
|
|
|
for refname := range matches {
|
|
|
|
refnames = append(refnames, refname)
|
|
|
|
}
|
|
|
|
sort.Strings(refnames)
|
|
|
|
for _, refname := range refnames {
|
|
|
|
fmt.Printf(" %s:%s", refname, matches[refname])
|
|
|
|
}
|
|
|
|
fmt.Printf("\n")
|
2024-01-13 00:13:26 +00:00
|
|
|
}
|
|
|
|
if failed > 0 {
|
|
|
|
return fmt.Errorf("failed to resolve %d revision(s)", failed)
|
|
|
|
}
|
2024-01-11 20:36:03 +00:00
|
|
|
return nil
|
|
|
|
},
|
2024-01-13 00:13:26 +00:00
|
|
|
}
|
|
|
|
revParse.Flags().BoolVar(&noFetch, "no-fetch", false,
|
|
|
|
"Do not attempt to update the cache before resolving the rev")
|
|
|
|
argparser.AddCommand(revParse)
|
|
|
|
|
|
|
|
clone := &cobra.Command{
|
2024-01-12 19:49:26 +00:00
|
|
|
Use: "clone [flags] URL DIR [-- GIT_CLONE_FLAGS...]",
|
2024-01-11 20:36:03 +00:00
|
|
|
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 {
|
2024-01-13 00:13:26 +00:00
|
|
|
if !noFetch {
|
|
|
|
if err := cache.Fetch(os.Stderr, args[0]); err != nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "[gitcache] Ignoring update error: %v\n", err)
|
|
|
|
}
|
|
|
|
}
|
2024-01-11 21:46:13 +00:00
|
|
|
return cache.Clone(os.Stderr, args[0], args[1], args[2:]...)
|
2024-01-11 20:36:03 +00:00
|
|
|
},
|
2024-01-13 00:13:26 +00:00
|
|
|
}
|
|
|
|
clone.Flags().BoolVar(&noFetch, "no-fetch", false,
|
|
|
|
"Do not attempt to update the cache before cloning")
|
|
|
|
argparser.AddCommand(clone)
|
|
|
|
|
2024-01-12 19:50:52 +00:00
|
|
|
argparser.AddCommand(&cobra.Command{
|
2024-01-27 22:02:59 +00:00
|
|
|
Use: "maintenance [flags] [-- GIT_MAINTENANCE_FLAGS...]",
|
|
|
|
Short: "Run Git maintenance tasks (a la `git-maintenance run`)",
|
2024-01-12 19:50:52 +00:00
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
2024-01-27 22:02:59 +00:00
|
|
|
return cache.Maintenance(os.Stderr, args...)
|
2024-01-12 19:50:52 +00:00
|
|
|
},
|
|
|
|
})
|
2024-01-11 20:36:03 +00:00
|
|
|
|
2024-01-20 18:07:48 +00:00
|
|
|
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
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2024-01-11 20:36:03 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
if err := argparser.ExecuteContext(ctx); err != nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "%v: error: %v\n", argparser.CommandPath(), err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|