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
diff --git a/zip/zip.go b/zip/zip.go
index d8507df..774966a 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -188,9 +188,11 @@
compressorPool sync.Pool
compLevel int
- followSymlinks pathtools.ShouldFollowSymlinks
+ followSymlinks pathtools.ShouldFollowSymlinks
+ ignoreMissingFiles bool
- fs pathtools.FileSystem
+ stderr io.Writer
+ fs pathtools.FileSystem
}
type zipEntry struct {
@@ -215,7 +217,9 @@
NonDeflatedFiles map[string]bool
WriteIfChanged bool
StoreSymlinks bool
+ IgnoreMissingFiles bool
+ Stderr io.Writer
Filesystem pathtools.FileSystem
}
@@ -271,19 +275,25 @@
followSymlinks := pathtools.ShouldFollowSymlinks(!args.StoreSymlinks)
z := &ZipWriter{
- time: jar.DefaultTime,
- createdDirs: make(map[string]string),
- createdFiles: make(map[string]string),
- directories: args.AddDirectoryEntriesToZip,
- compLevel: args.CompressionLevel,
- followSymlinks: followSymlinks,
- fs: args.Filesystem,
+ time: jar.DefaultTime,
+ createdDirs: make(map[string]string),
+ createdFiles: make(map[string]string),
+ directories: args.AddDirectoryEntriesToZip,
+ compLevel: args.CompressionLevel,
+ followSymlinks: followSymlinks,
+ ignoreMissingFiles: args.IgnoreMissingFiles,
+ stderr: args.Stderr,
+ fs: args.Filesystem,
}
if z.fs == nil {
z.fs = pathtools.OsFs
}
+ if z.stderr == nil {
+ z.stderr = os.Stderr
+ }
+
pathMappings := []pathMapping{}
noCompression := args.CompressionLevel == 0
@@ -301,29 +311,44 @@
return err
}
if len(globbed) == 0 {
- return &os.PathError{
- Op: "stat",
+ err := &os.PathError{
+ Op: "lstat",
Path: s,
Err: os.ErrNotExist,
}
+ if args.IgnoreMissingFiles {
+ fmt.Fprintln(args.Stderr, "warning:", err)
+ } else {
+ return err
+ }
}
srcs = append(srcs, globbed...)
}
if fa.GlobDir != "" {
if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil {
return err
- } else if !exists {
- return &os.PathError{
- Op: "stat",
+ } else if !exists && !args.IgnoreMissingFiles {
+ err := &os.PathError{
+ Op: "lstat",
Path: fa.GlobDir,
Err: os.ErrNotExist,
}
- } else if !isDir {
- return &os.PathError{
- Op: "stat",
+ if args.IgnoreMissingFiles {
+ fmt.Fprintln(args.Stderr, "warning:", err)
+ } else {
+ return err
+ }
+ } else if !isDir && !args.IgnoreMissingFiles {
+ err := &os.PathError{
+ Op: "lstat",
Path: fa.GlobDir,
Err: syscall.ENOTDIR,
}
+ if args.IgnoreMissingFiles {
+ fmt.Fprintln(args.Stderr, "warning:", err)
+ } else {
+ return err
+ }
}
globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, followSymlinks)
if err != nil {
@@ -576,6 +601,10 @@
}
if err != nil {
+ if os.IsNotExist(err) && z.ignoreMissingFiles {
+ fmt.Fprintln(z.stderr, "warning:", err)
+ return nil
+ }
return err
} else if s.IsDir() {
if z.directories {