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 <key> <local-dir>",
Short: "Extract a cached directory into <local-dir>",
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 <key> <local-dir>",
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)
}