aboutsummaryrefslogtreecommitdiffstats
path: root/zip
diff options
context:
space:
mode:
authorColin Cross2018-09-28 17:16:48 -0500
committerColin Cross2018-09-28 18:14:52 -0500
commit4be8f9e2a3e857050f4d6d9b3d728492828445bf (patch)
tree02d5d87c95a304bfeb58f4f436d7fa4043f06763 /zip
parent09f11056f876a9f705a53fd6f122aa7575e0b51b (diff)
downloadplatform-build-soong-4be8f9e2a3e857050f4d6d9b3d728492828445bf.tar.gz
platform-build-soong-4be8f9e2a3e857050f4d6d9b3d728492828445bf.tar.xz
platform-build-soong-4be8f9e2a3e857050f4d6d9b3d728492828445bf.zip
soong_zip: add --ignore_missing_files flag
soong_zip builds a list of files to zip early and then starts zipping them all. If a directory being zipped is concurrently modified, a file that existed when soong_zip started may not still exist. Add a flag that continues when an expected file does not exist. Print a warning, since this should be rare in normal usages but is a sign of a problem if it happens regularly. Test: zip_test.go Test: m checkbuild Test: m platform Change-Id: I78426fe66fded8528ddd436c0f71a7442183cfeb
Diffstat (limited to 'zip')
-rw-r--r--zip/cmd/main.go3
-rw-r--r--zip/zip.go63
-rw-r--r--zip/zip_test.go33
3 files changed, 73 insertions, 26 deletions
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index 4a084912..b4f75f7a 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -136,7 +136,7 @@ func main() {
136 compLevel := flags.Int("L", 5, "deflate compression level (0-9)") 136 compLevel := flags.Int("L", 5, "deflate compression level (0-9)")
137 emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'") 137 emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
138 writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed") 138 writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
139 139 ignoreMissingFiles := flags.Bool("ignore_missing_files", false, "continue if a requested file does not exist")
140 symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them") 140 symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
141 141
142 parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use") 142 parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
@@ -200,6 +200,7 @@ func main() {
200 NonDeflatedFiles: nonDeflatedFiles, 200 NonDeflatedFiles: nonDeflatedFiles,
201 WriteIfChanged: *writeIfChanged, 201 WriteIfChanged: *writeIfChanged,
202 StoreSymlinks: *symlinks, 202 StoreSymlinks: *symlinks,
203 IgnoreMissingFiles: *ignoreMissingFiles,
203 }) 204 })
204 if err != nil { 205 if err != nil {
205 fmt.Fprintln(os.Stderr, "error:", err.Error()) 206 fmt.Fprintln(os.Stderr, "error:", err.Error())
diff --git a/zip/zip.go b/zip/zip.go
index d8507df2..774966a7 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -188,9 +188,11 @@ type ZipWriter struct {
188 compressorPool sync.Pool 188 compressorPool sync.Pool
189 compLevel int 189 compLevel int
190 190
191 followSymlinks pathtools.ShouldFollowSymlinks 191 followSymlinks pathtools.ShouldFollowSymlinks
192 ignoreMissingFiles bool
192 193
193 fs pathtools.FileSystem 194 stderr io.Writer
195 fs pathtools.FileSystem
194} 196}
195 197
196type zipEntry struct { 198type zipEntry struct {
@@ -215,7 +217,9 @@ type ZipArgs struct {
215 NonDeflatedFiles map[string]bool 217 NonDeflatedFiles map[string]bool
216 WriteIfChanged bool 218 WriteIfChanged bool
217 StoreSymlinks bool 219 StoreSymlinks bool
220 IgnoreMissingFiles bool
218 221
222 Stderr io.Writer
219 Filesystem pathtools.FileSystem 223 Filesystem pathtools.FileSystem
220} 224}
221 225
@@ -271,19 +275,25 @@ func ZipTo(args ZipArgs, w io.Writer) error {
271 followSymlinks := pathtools.ShouldFollowSymlinks(!args.StoreSymlinks) 275 followSymlinks := pathtools.ShouldFollowSymlinks(!args.StoreSymlinks)
272 276
273 z := &ZipWriter{ 277 z := &ZipWriter{
274 time: jar.DefaultTime, 278 time: jar.DefaultTime,
275 createdDirs: make(map[string]string), 279 createdDirs: make(map[string]string),
276 createdFiles: make(map[string]string), 280 createdFiles: make(map[string]string),
277 directories: args.AddDirectoryEntriesToZip, 281 directories: args.AddDirectoryEntriesToZip,
278 compLevel: args.CompressionLevel, 282 compLevel: args.CompressionLevel,
279 followSymlinks: followSymlinks, 283 followSymlinks: followSymlinks,
280 fs: args.Filesystem, 284 ignoreMissingFiles: args.IgnoreMissingFiles,
285 stderr: args.Stderr,
286 fs: args.Filesystem,
281 } 287 }
282 288
283 if z.fs == nil { 289 if z.fs == nil {
284 z.fs = pathtools.OsFs 290 z.fs = pathtools.OsFs
285 } 291 }
286 292
293 if z.stderr == nil {
294 z.stderr = os.Stderr
295 }
296
287 pathMappings := []pathMapping{} 297 pathMappings := []pathMapping{}
288 298
289 noCompression := args.CompressionLevel == 0 299 noCompression := args.CompressionLevel == 0
@@ -301,29 +311,44 @@ func ZipTo(args ZipArgs, w io.Writer) error {
301 return err 311 return err
302 } 312 }
303 if len(globbed) == 0 { 313 if len(globbed) == 0 {
304 return &os.PathError{ 314 err := &os.PathError{
305 Op: "stat", 315 Op: "lstat",
306 Path: s, 316 Path: s,
307 Err: os.ErrNotExist, 317 Err: os.ErrNotExist,
308 } 318 }
319 if args.IgnoreMissingFiles {
320 fmt.Fprintln(args.Stderr, "warning:", err)
321 } else {
322 return err
323 }
309 } 324 }
310 srcs = append(srcs, globbed...) 325 srcs = append(srcs, globbed...)
311 } 326 }
312 if fa.GlobDir != "" { 327 if fa.GlobDir != "" {
313 if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil { 328 if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil {
314 return err 329 return err
315 } else if !exists { 330 } else if !exists && !args.IgnoreMissingFiles {
316 return &os.PathError{ 331 err := &os.PathError{
317 Op: "stat", 332 Op: "lstat",
318 Path: fa.GlobDir, 333 Path: fa.GlobDir,
319 Err: os.ErrNotExist, 334 Err: os.ErrNotExist,
320 } 335 }
321 } else if !isDir { 336 if args.IgnoreMissingFiles {
322 return &os.PathError{ 337 fmt.Fprintln(args.Stderr, "warning:", err)
323 Op: "stat", 338 } else {
339 return err
340 }
341 } else if !isDir && !args.IgnoreMissingFiles {
342 err := &os.PathError{
343 Op: "lstat",
324 Path: fa.GlobDir, 344 Path: fa.GlobDir,
325 Err: syscall.ENOTDIR, 345 Err: syscall.ENOTDIR,
326 } 346 }
347 if args.IgnoreMissingFiles {
348 fmt.Fprintln(args.Stderr, "warning:", err)
349 } else {
350 return err
351 }
327 } 352 }
328 globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, followSymlinks) 353 globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, followSymlinks)
329 if err != nil { 354 if err != nil {
@@ -576,6 +601,10 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) er
576 } 601 }
577 602
578 if err != nil { 603 if err != nil {
604 if os.IsNotExist(err) && z.ignoreMissingFiles {
605 fmt.Fprintln(z.stderr, "warning:", err)
606 return nil
607 }
579 return err 608 return err
580 } else if s.IsDir() { 609 } else if s.IsDir() {
581 if z.directories { 610 if z.directories {
diff --git a/zip/zip_test.go b/zip/zip_test.go
index a08fb126..93c5f3de 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -98,14 +98,15 @@ func fileArgsBuilder() *FileArgsBuilder {
98 98
99func TestZip(t *testing.T) { 99func TestZip(t *testing.T) {
100 testCases := []struct { 100 testCases := []struct {
101 name string 101 name string
102 args *FileArgsBuilder 102 args *FileArgsBuilder
103 compressionLevel int 103 compressionLevel int
104 emulateJar bool 104 emulateJar bool
105 nonDeflatedFiles map[string]bool 105 nonDeflatedFiles map[string]bool
106 dirEntries bool 106 dirEntries bool
107 manifest string 107 manifest string
108 storeSymlinks bool 108 storeSymlinks bool
109 ignoreMissingFiles bool
109 110
110 files []zip.FileHeader 111 files []zip.FileHeader
111 err error 112 err error
@@ -338,6 +339,20 @@ func TestZip(t *testing.T) {
338 fh("a/a/b", fileB, zip.Deflate), 339 fh("a/a/b", fileB, zip.Deflate),
339 }, 340 },
340 }, 341 },
342 {
343 name: "ignore missing files",
344 args: fileArgsBuilder().
345 File("a/a/a").
346 File("a/a/b").
347 File("missing"),
348 compressionLevel: 9,
349 ignoreMissingFiles: true,
350
351 files: []zip.FileHeader{
352 fh("a/a/a", fileA, zip.Deflate),
353 fh("a/a/b", fileB, zip.Deflate),
354 },
355 },
341 356
342 // errors 357 // errors
343 { 358 {
@@ -381,7 +396,9 @@ func TestZip(t *testing.T) {
381 args.NonDeflatedFiles = test.nonDeflatedFiles 396 args.NonDeflatedFiles = test.nonDeflatedFiles
382 args.ManifestSourcePath = test.manifest 397 args.ManifestSourcePath = test.manifest
383 args.StoreSymlinks = test.storeSymlinks 398 args.StoreSymlinks = test.storeSymlinks
399 args.IgnoreMissingFiles = test.ignoreMissingFiles
384 args.Filesystem = mockFs 400 args.Filesystem = mockFs
401 args.Stderr = &bytes.Buffer{}
385 402
386 buf := &bytes.Buffer{} 403 buf := &bytes.Buffer{}
387 err := ZipTo(args, buf) 404 err := ZipTo(args, buf)