zsvo/cmd/cache.go

135 lines
3.3 KiB
Go

package cmd
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"zsvo/pkg/builder"
)
var CacheCmd = &cobra.Command{
Use: "cache",
Short: "Manage build cache",
Long: `Clean or show information about build cache`,
}
var CleanCacheCmd = &cobra.Command{
Use: "clean",
Short: "Clean build cache",
Long: `Remove all cached packages, sources, and build artifacts`,
RunE: func(cmd *cobra.Command, args []string) error {
workDir, _ := cmd.Flags().GetString("work-dir")
if workDir == "" {
workDir = "/tmp/pkg-work"
}
b := builder.NewBuilder(workDir)
// Show cache size before cleaning
if size, err := b.GetCacheSize(); err == nil {
fmt.Printf("Cache size: %s\n", formatBytes(size))
}
if err := b.CleanCache(); err != nil {
return fmt.Errorf("failed to clean cache: %w", err)
}
fmt.Printf("Cache cleaned successfully\n")
return nil
},
}
var InfoCacheCmd = &cobra.Command{
Use: "info",
Short: "Show cache information",
Long: `Display detailed information about build cache usage`,
RunE: func(cmd *cobra.Command, args []string) error {
workDir, _ := cmd.Flags().GetString("work-dir")
if workDir == "" {
workDir = "/tmp/pkg-work"
}
b := builder.NewBuilder(workDir)
fmt.Printf("=== Build Cache Information ===\n\n")
fmt.Printf("Work directory: %s\n", workDir)
// Calculate total size
totalSize, err := b.GetCacheSize()
if err != nil {
fmt.Printf("Error calculating cache size: %v\n", err)
} else {
fmt.Printf("Total cache size: %s\n", formatBytes(totalSize))
}
// Show individual directories
dirs := map[string]string{
"Download cache": filepath.Join(workDir, "cache"),
"Built packages": filepath.Join(workDir, "packages"),
"Source files": filepath.Join(workDir, "sources"),
"Staging files": filepath.Join(workDir, "staging"),
}
fmt.Printf("\nCache breakdown:\n")
for name, dir := range dirs {
if size, err := getDirSize(dir); err == nil && size > 0 {
fmt.Printf(" %s: %s\n", name, formatBytes(size))
} else {
fmt.Printf(" %s: empty or missing\n", name)
}
}
// Count cached packages
pkgDir := filepath.Join(workDir, "packages")
if entries, err := os.ReadDir(pkgDir); err == nil {
pkgCount := 0
for _, entry := range entries {
if entry.IsDir() {
pkgCount++
}
}
fmt.Printf("\nCached packages: %d\n", pkgCount)
}
return nil
},
}
func init() {
CacheCmd.AddCommand(CleanCacheCmd)
CacheCmd.AddCommand(InfoCacheCmd)
// Add work-dir flag to subcommands
CleanCacheCmd.Flags().StringP("work-dir", "w", "/tmp/pkg-work", "Working directory for cache")
InfoCacheCmd.Flags().StringP("work-dir", "w", "/tmp/pkg-work", "Working directory for cache")
}
func formatBytes(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
// getDirSize calculates total size of directory recursively
func getDirSize(path string) (int64, error) {
var size int64
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
size += info.Size()
}
return nil
})
return size, err
}