9
9
"os"
10
10
"path/filepath"
11
11
"strings"
12
+ "time"
12
13
13
14
"golang.org/x/xerrors"
14
15
@@ -94,33 +95,28 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
94
95
continue
95
96
}
96
97
97
- err := fs .WalkDir (root ,it .Dir ,func (filePath string ,info fs.DirEntry ,err error )error {
98
+ err := fs .WalkDir (root ,it .Dir ,func (filePath string ,d fs.DirEntry ,err error )error {
98
99
if err != nil {
99
100
return xerrors .Errorf ("failed to create modules archive: %w" ,err )
100
101
}
101
- fileType := info .Type ()
102
- if ! fileType .IsRegular ()&& ! fileType .IsDir () {
102
+ fileMode := d .Type ()
103
+ if ! fileMode .IsRegular ()&& ! fileMode .IsDir () {
103
104
return nil
104
105
}
105
- fileInfo ,err := info .Info ()
106
+ fileInfo ,err := d .Info ()
106
107
if err != nil {
107
108
return xerrors .Errorf ("failed to archive module file %q: %w" ,filePath ,err )
108
109
}
109
- header ,err := tar . FileInfoHeader ( fileInfo , "" )
110
+ header ,err := fileHeader ( filePath , fileMode , fileInfo )
110
111
if err != nil {
111
112
return xerrors .Errorf ("failed to archive module file %q: %w" ,filePath ,err )
112
113
}
113
- header .Name = filePath
114
- if fileType .IsDir () {
115
- header .Name += "/"
116
- }
117
-
118
114
err = w .WriteHeader (header )
119
115
if err != nil {
120
116
return xerrors .Errorf ("failed to add module file %q to archive: %w" ,filePath ,err )
121
117
}
122
118
123
- if ! fileType .IsRegular () {
119
+ if ! fileMode .IsRegular () {
124
120
return nil
125
121
}
126
122
empty = false
@@ -140,13 +136,7 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
140
136
}
141
137
}
142
138
143
- err = w .WriteHeader (& tar.Header {
144
- Name :".terraform/modules/modules.json" ,
145
- Size :int64 (len (modulesFileContent )),
146
- Mode :0o644 ,
147
- Uid :1000 ,
148
- Gid :1000 ,
149
- })
139
+ err = w .WriteHeader (defaultFileHeader (".terraform/modules/modules.json" ,len (modulesFileContent )))
150
140
if err != nil {
151
141
return nil ,xerrors .Errorf ("failed to write modules.json to archive: %w" ,err )
152
142
}
@@ -163,3 +153,33 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
163
153
}
164
154
return b .Bytes (),nil
165
155
}
156
+
157
+ func fileHeader (filePath string ,fileMode fs.FileMode ,fileInfo fs.FileInfo ) (* tar.Header ,error ) {
158
+ header ,err := tar .FileInfoHeader (fileInfo ,"" )
159
+ if err != nil {
160
+ return nil ,xerrors .Errorf ("failed to archive module file %q: %w" ,filePath ,err )
161
+ }
162
+ header .Name = filePath
163
+ if fileMode .IsDir () {
164
+ header .Name += "/"
165
+ }
166
+ // Erase a bunch of metadata that we don't need so that we get more consistent
167
+ // hashes from the resulting archive.
168
+ header .AccessTime = time.Time {}
169
+ header .ChangeTime = time.Time {}
170
+ header .ModTime = time.Time {}
171
+ header .Uname = ""
172
+ header .Gname = ""
173
+
174
+ return header ,nil
175
+ }
176
+
177
+ func defaultFileHeader (filePath string ,length int )* tar.Header {
178
+ return & tar.Header {
179
+ Name :filePath ,
180
+ Size :int64 (length ),
181
+ Mode :0o644 ,
182
+ Uid :1000 ,
183
+ Gid :1000 ,
184
+ }
185
+ }