44"archive/tar"
55"bytes"
66"io"
7- "io/fs"
87"os"
98"path/filepath"
109"strings"
@@ -32,37 +31,43 @@ func dirHasExt(dir string, ext string) (bool, error) {
3231return false ,nil
3332}
3433
34+ // Tar archives a Terraform directory.
35+ func Tar (directory string ,limit int64 ) ([]byte ,error ) {
36+ var buffer bytes.Buffer
37+ tarWriter := tar .NewWriter (& buffer )
38+ totalSize := int64 (0 )
3539
36- type archiver struct {
40+ const tfExt = ".tf"
41+ hasTf ,err := dirHasExt (directory ,tfExt )
42+ if err != nil {
43+ return nil ,err
44+ }
45+ if ! hasTf {
46+ absPath ,err := filepath .Abs (directory )
47+ if err != nil {
48+ return nil ,err
49+ }
3750
38- }
51+ // Show absolute path to aid in debugging. E.g. showing "." is
52+ // useless.
53+ return nil ,xerrors .Errorf (
54+ "%s is not a valid template since it has no %s files" ,
55+ absPath ,tfExt ,
56+ )
57+ }
3958
40- func ( a * archiver ) walkFn ( path string ,fileInfo os.FileInfo ,err error )error {
59+ err = filepath . Walk ( directory , func ( file string ,fileInfo os.FileInfo ,err error )error {
4160if err != nil {
4261return err
4362}
63+ var link string
4464if fileInfo .Mode ()& os .ModeSymlink == os .ModeSymlink {
45- // Per https://github.com/coder/coder/issues/5677, we want to
46- // follow symlinks.
47- var linkDest string
48- linkDest ,err = os .Readlink (file )
65+ link ,err = os .Readlink (file )
4966if err != nil {
5067return err
5168}
52-
53- destInfo ,err := os .Stat (linkDest )
54- if err != nil {
55- return err
56- }
57- if destInfo .IsDir () {
58- return filepath .Walk (linkDest ,func (path string ,info fs.FileInfo ,err error )error {
59- walkFn (path ,info ,err )
60- })
61- }
62- return nil
6369}
64-
65- header ,err := tar .FileInfoHeader (fileInfo ,"" )
70+ header ,err := tar .FileInfoHeader (fileInfo ,link )
6671if err != nil {
6772return err
6873}
@@ -71,10 +76,11 @@ func (a *archiver) walkFn(path string, fileInfo os.FileInfo, err error) error {
7176return err
7277}
7378if strings .HasPrefix (rel ,"." )|| strings .HasPrefix (filepath .Base (rel ),"." ) {
74- // Don't archive hidden files!
7579if fileInfo .IsDir ()&& rel != "." {
80+ // Don't archive hidden files!
7681return filepath .SkipDir
7782}
83+ // Don't archive hidden files!
7884return nil
7985}
8086if strings .Contains (rel ,".tfstate" ) {
@@ -103,35 +109,7 @@ func (a *archiver) walkFn(path string, fileInfo os.FileInfo, err error) error {
103109return xerrors .Errorf ("Archive too big. Must be <= %d bytes" ,limit )
104110}
105111return data .Close ()
106- }
107- }
108-
109- // Tar archives a Terraform directory.
110- func Tar (directory string ,limit int64 ) ([]byte ,error ) {
111- var buffer bytes.Buffer
112- tarWriter := tar .NewWriter (& buffer )
113- totalSize := int64 (0 )
114-
115- const tfExt = ".tf"
116- hasTf ,err := dirHasExt (directory ,tfExt )
117- if err != nil {
118- return nil ,err
119- }
120- if ! hasTf {
121- absPath ,err := filepath .Abs (directory )
122- if err != nil {
123- return nil ,err
124- }
125-
126- // Show absolute path to aid in debugging. E.g. showing "." is
127- // useless.
128- return nil ,xerrors .Errorf (
129- "%s is not a valid template since it has no %s files" ,
130- absPath ,tfExt ,
131- )
132- }
133-
134- err = filepath .Walk (directory ,tarWalkFn ())
112+ })
135113if err != nil {
136114return nil ,err
137115}