1// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build ignore
6
7// Mkzip writes a zoneinfo.zip with the content of the current directory
8// and its subdirectories, with no compression, suitable for package time.
9//
10// Usage:
11//
12//	go run ../../mkzip.go ../../zoneinfo.zip
13//
14// We use this program instead of 'zip -0 -r ../../zoneinfo.zip *' to get
15// a reproducible generator that does not depend on which version of the
16// external zip tool is used or the ordering of file names in a directory
17// or the current time.
18package main
19
20import (
21	"archive/zip"
22	"bytes"
23	"flag"
24	"fmt"
25	"hash/crc32"
26	"io/fs"
27	"log"
28	"os"
29	"path/filepath"
30	"strings"
31)
32
33func usage() {
34	fmt.Fprintf(os.Stderr, "usage: go run mkzip.go zoneinfo.zip\n")
35	os.Exit(2)
36}
37
38func main() {
39	log.SetPrefix("mkzip: ")
40	log.SetFlags(0)
41	flag.Usage = usage
42	flag.Parse()
43	args := flag.Args()
44	if len(args) != 1 || !strings.HasSuffix(args[0], ".zip") {
45		usage()
46	}
47
48	var zb bytes.Buffer
49	zw := zip.NewWriter(&zb)
50	seen := make(map[string]bool)
51	err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
52		if d.IsDir() {
53			return nil
54		}
55		data, err := os.ReadFile(path)
56		if err != nil {
57			log.Fatal(err)
58		}
59		if strings.HasSuffix(path, ".zip") {
60			log.Fatalf("unexpected file during walk: %s", path)
61		}
62		name := filepath.ToSlash(path)
63		w, err := zw.CreateRaw(&zip.FileHeader{
64			Name:               name,
65			Method:             zip.Store,
66			CompressedSize64:   uint64(len(data)),
67			UncompressedSize64: uint64(len(data)),
68			CRC32:              crc32.ChecksumIEEE(data),
69		})
70		if err != nil {
71			log.Fatal(err)
72		}
73		if _, err := w.Write(data); err != nil {
74			log.Fatal(err)
75		}
76		seen[name] = true
77		return nil
78	})
79	if err != nil {
80		log.Fatal(err)
81	}
82	if err := zw.Close(); err != nil {
83		log.Fatal(err)
84	}
85	if len(seen) == 0 {
86		log.Fatalf("did not find any files to add")
87	}
88	if !seen["US/Eastern"] {
89		log.Fatalf("did not find US/Eastern to add")
90	}
91	if err := os.WriteFile(args[0], zb.Bytes(), 0666); err != nil {
92		log.Fatal(err)
93	}
94}
95