Write a Go program that uses the archive/zip and filepath packages to walk a directory tree and write files into a zip archive with deterministic ordering and no compression.
package main
import (
"archive/zip"
"bytes"
"fmt"
"hash/crc32"
"io/fs"
"log"
"os"
"path/filepath"
"strings"
)
func main() {
if len(os.Args) != 2 || !strings.HasSuffix(os.Args[1], ".zip") {
log.Fatal("usage: go run generator.go output.zip")
}
var zb bytes.Buffer
zw := zip.NewWriter(&zb)
seen := make(map[string]bool)
err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
data, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
}
if strings.HasSuffix(path, ".zip") {
log.Fatalf("unexpected file during walk: %s", path)
}
name := filepath.ToSlash(path)
w, err := zw.CreateRaw(&zip.FileHeader{
Name: name,
Method: zip.Store,
CompressedSize64: uint64(len(data)),
UncompressedSize64: uint64(len(data)),
CRC32: crc32.ChecksumIEEE(data),
})
if err != nil {
log.Fatal(err)
}
if _, err := w.Write(data); err != nil {
log.Fatal(err)
}
seen[name] = true
return nil
})
if err != nil {
log.Fatal(err)
}
if err := zw.Close(); err != nil {
log.Fatal(err)
}
if len(seen) == 0 {
log.Fatalf("did not find any files to add")
}
if err := os.WriteFile(os.Args[1], zb.Bytes(), 0666); err != nil {
log.Fatal(err)
}
fmt.Println("Generated", os.Args[1])
}