package cmd import ( "context" "fmt" "io" "os" "github.com/spf13/cobra" "go.bigb.es/cacher/internal/archive" ) var dirCmd = &cobra.Command{ Use: "dir", Short: "Directory cache (tar+zstd of a tree)", Long: `Cache resolved trees keyed by content hash (e.g. ~/go/pkg/mod keyed by go.sum, or .rocks/ keyed by rockspec hash). Closes the biggest gap left by the single-file shell helper this binary replaces.`, } var dirDownloadCmd = &cobra.Command{ Use: "download ", Short: "Extract a cached directory into ", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cli, cfg, err := client() if err != nil { return err } key, err := resolveKey(args[0], cfg) if err != nil { return err } dest := args[1] ctx := context.Background() ok, err := cli.Exists(ctx, key) if err != nil { return err } if !ok { return fmt.Errorf("%w: %s", ErrNotFound, key) } if err := os.MkdirAll(dest, 0o755); err != nil { return err } fmt.Fprintf(cmd.ErrOrStderr(), "Cache HIT — %s → extract %s\n", key, dest) body, err := cli.Get(ctx, key) if err != nil { return err } defer body.Close() return archive.DecodeDir(body, dest) }, } var dirUploadCmd = &cobra.Command{ Use: "upload ", Short: "Pack a local directory (tar+zstd) and upload", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { cli, cfg, err := client() if err != nil { return err } key, err := resolveKey(args[0], cfg) if err != nil { return err } src := args[1] ctx := context.Background() if !flagForce { ok, err := cli.Exists(ctx, key) if err != nil { return err } if ok { fmt.Fprintf(cmd.ErrOrStderr(), "Skipped — %s already present (use --force)\n", key) return nil } } st, err := os.Stat(src) if err != nil { return err } if !st.IsDir() { return fmt.Errorf("%s is not a directory", src) } fmt.Fprintf(cmd.ErrOrStderr(), "Packing %s → %s\n", src, key) pr, pw := io.Pipe() go func() { err := archive.EncodeDir(pw, src) pw.CloseWithError(err) }() return cli.Put(ctx, key, pr) }, } func init() { for _, c := range []*cobra.Command{dirDownloadCmd, dirUploadCmd} { addS3Flags(c) addKeyFlags(c) } dirUploadCmd.Flags().BoolVar(&flagForce, "force", false, "overwrite if key already exists") dirCmd.AddCommand(dirDownloadCmd, dirUploadCmd) rootCmd.AddCommand(dirCmd) }