How to Write a Code Generator in Go

Write a Go program using archive/zip and filepath.WalkDir to generate a deterministic, uncompressed zip file from a directory tree.

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])
}