...
1
16
17 package main
18
19 import (
20 "archive/tar"
21 "compress/gzip"
22 "fmt"
23 "io"
24 "os"
25 "path/filepath"
26 "strings"
27 )
28
29
30
31 func tarDir(dir, outpath string) error {
32
33 if _, err := os.Stat(dir); err != nil {
34 return fmt.Errorf("tar unable to stat directory %v: %w", dir, err)
35 }
36
37 outfile, err := os.Create(outpath)
38 if err != nil {
39 return fmt.Errorf("creating tarball %v: %w", outpath, err)
40 }
41 defer outfile.Close()
42
43 gzw := gzip.NewWriter(outfile)
44 defer gzw.Close()
45
46 tw := tar.NewWriter(gzw)
47 defer tw.Close()
48
49 return filepath.Walk(dir, func(file string, fi os.FileInfo, err error) error {
50
51 if err != nil {
52 return err
53 }
54
55
56 if !fi.Mode().IsRegular() || filepath.Join(dir, fi.Name()) == outpath {
57 return nil
58 }
59
60
61 header, err := tar.FileInfoHeader(fi, fi.Name())
62 if err != nil {
63 return fmt.Errorf("creating file info header %v: %w", fi.Name(), err)
64 }
65
66
67 header.Name = strings.TrimPrefix(strings.Replace(file, dir, "", -1), string(filepath.Separator))
68 if err := tw.WriteHeader(header); err != nil {
69 return fmt.Errorf("writing header for tarball %v: %w", header.Name, err)
70 }
71
72
73 f, err := os.Open(file)
74 if err != nil {
75 return fmt.Errorf("opening file %v for writing into tarball: %w", file, err)
76 }
77 defer f.Close()
78
79 _, err = io.Copy(tw, f)
80 if err != nil {
81 return fmt.Errorf("creating file %v contents into tarball: %w", file, err)
82 }
83
84 return nil
85 })
86 }
87
View as plain text