task/1.9
Raw Download raw file
  1//go:build ignore
  2
  3// Command tools/vendor/unpack.go  extracts `vendor.tar.gz` into the current
  4// project `vendor` directory.  Intended for use as a build support tool.
  5package main
  6
  7import (
  8	"archive/tar"
  9	"compress/gzip"
 10	"errors"
 11	"io"
 12	"log/slog"
 13	"os"
 14	"path/filepath"
 15	"runtime"
 16)
 17
 18// vendor.tar.gz unpack
 19func main() {
 20	const (
 21		archiveName   = "vendor.tar.gz"
 22		vendorDir     = "vendor"
 23		vendorDirMode = 0o755
 24	)
 25
 26	// discover this file's location
 27	_, callerFilepath, _, callerFound := runtime.Caller(0)
 28	if !callerFound {
 29		slog.Error("failed to find caller location")
 30		return
 31	}
 32	archivePath := filepath.Join(filepath.Dir(callerFilepath), archiveName)
 33
 34	archiveFile, err := os.Open(archivePath)
 35	if err != nil {
 36		slog.Error("failed to open vendor tarball",
 37			slog.String("err", err.Error()),
 38			slog.String("path", archivePath))
 39		return
 40	}
 41	defer func() { _ = archiveFile.Close() }()
 42
 43	gzr, err := gzip.NewReader(archiveFile)
 44	if err != nil {
 45		slog.Error("failed to open gzip reader",
 46			slog.String("err", err.Error()),
 47			slog.String("path", archivePath))
 48		return
 49	}
 50	defer func() { _ = gzr.Close() }()
 51
 52	tr := tar.NewReader(gzr)
 53	for {
 54		header, err := tr.Next()
 55		if err != nil {
 56			if errors.Is(err, io.EOF) {
 57				break
 58			}
 59			slog.Error("failed to read next tar entry",
 60				slog.String("err", err.Error()))
 61		}
 62		info := header.FileInfo()
 63
 64		if !info.IsDir() {
 65			target := filepath.Join(vendorDir, header.Name)
 66			dir := filepath.Dir(target)
 67
 68			err = os.MkdirAll(dir, vendorDirMode)
 69			if err != nil {
 70				slog.Error("failed to create vendor dir",
 71					slog.String("err", err.Error()),
 72					slog.String("dir", dir))
 73				return
 74			}
 75
 76			vendorFile, err := os.OpenFile(
 77				target,
 78				os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
 79				info.Mode())
 80			if err != nil {
 81				slog.Error("failed to open vendor file",
 82					slog.String("err", err.Error()),
 83					slog.String("path", target))
 84				_ = vendorFile.Close()
 85				return
 86			}
 87
 88			_, err = io.Copy(vendorFile, tr)
 89			if err != nil {
 90				slog.Error("failed to copy vendor file from tar",
 91					slog.String("err", err.Error()),
 92					slog.String("path", target))
 93				_ = vendorFile.Close()
 94				return
 95			}
 96
 97			err = vendorFile.Close()
 98			if err != nil {
 99				slog.Error("failed to close vendor file",
100					slog.String("err", err.Error()),
101					slog.String("path", target))
102				return
103			}
104		}
105	}
106}