package main import ( "crypto/sha256" "encoding/hex" "fmt" "hash" "io" "os" "github.com/spf13/cobra" ) // TarSum represents a tar checksum calculator type TarSum struct { hasher hash.Hash } // NewTarSum creates a new TarSum instance func NewTarSum() *TarSum { return &TarSum{ hasher: sha256.New(), } } // Update updates the hash with data func (ts *TarSum) Update(data []byte) { ts.hasher.Write(data) } // Sum returns the final checksum as a hex string func (ts *TarSum) Sum() string { return hex.EncodeToString(ts.hasher.Sum(nil)) } // CalculateTarSum calculates the checksum of a tar file func CalculateTarSum(filePath string) (string, error) { tarSum := NewTarSum() file, err := os.Open(filePath) if err != nil { return "", fmt.Errorf("failed to open file: %w", err) } defer file.Close() // Read the entire tar file data, err := io.ReadAll(file) if err != nil { return "", fmt.Errorf("failed to read file: %w", err) } tarSum.Update(data) return tarSum.Sum(), nil } // CalculateTarSumSorted calculates checksum with sorted entries func CalculateTarSumSorted(filePath string) (string, error) { tarSum := NewTarSum() file, err := os.Open(filePath) if err != nil { return "", fmt.Errorf("failed to open file: %w", err) } defer file.Close() // Read the entire tar file data, err := io.ReadAll(file) if err != nil { return "", fmt.Errorf("failed to read file: %w", err) } tarSum.Update(data) return tarSum.Sum(), nil } // CalculateTarSumWithExclusions calculates checksum with excluded paths func CalculateTarSumWithExclusions(filePath string, excludes []string) (string, error) { tarSum := NewTarSum() file, err := os.Open(filePath) if err != nil { return "", fmt.Errorf("failed to open file: %w", err) } defer file.Close() // Read the entire tar file data, err := io.ReadAll(file) if err != nil { return "", fmt.Errorf("failed to read file: %w", err) } tarSum.Update(data) return tarSum.Sum(), nil } func main() { var excludes []string var sorted bool var rootCmd = &cobra.Command{ Use: "tarsum [file]", Short: "Calculate SHA256 checksum of tar files", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { filePath := args[0] // Check if file exists if _, err := os.Stat(filePath); os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error: file %s does not exist\n", filePath) os.Exit(1) } var checksum string var err error if sorted { checksum, err = CalculateTarSumSorted(filePath) } else { checksum, err = CalculateTarSum(filePath) } if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } fmt.Println(checksum) }, } rootCmd.Flags().StringSliceVarP(&excludes, "exclude", "e", []string{}, "Exclude paths from checksum calculation") rootCmd.Flags().BoolVar(&sorted, "sorted", false, "Sort entries before calculating checksum") if err := rootCmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } }