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
This commit is contained in:
parent
09f11056f8
commit
4be8f9e2a3
|
@ -136,7 +136,7 @@ func main() {
|
||||||
compLevel := flags.Int("L", 5, "deflate compression level (0-9)")
|
compLevel := flags.Int("L", 5, "deflate compression level (0-9)")
|
||||||
emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
|
emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
|
||||||
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
|
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
|
||||||
|
ignoreMissingFiles := flags.Bool("ignore_missing_files", false, "continue if a requested file does not exist")
|
||||||
symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
|
symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
|
||||||
|
|
||||||
parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
|
parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
|
||||||
|
@ -200,6 +200,7 @@ func main() {
|
||||||
NonDeflatedFiles: nonDeflatedFiles,
|
NonDeflatedFiles: nonDeflatedFiles,
|
||||||
WriteIfChanged: *writeIfChanged,
|
WriteIfChanged: *writeIfChanged,
|
||||||
StoreSymlinks: *symlinks,
|
StoreSymlinks: *symlinks,
|
||||||
|
IgnoreMissingFiles: *ignoreMissingFiles,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error:", err.Error())
|
fmt.Fprintln(os.Stderr, "error:", err.Error())
|
||||||
|
|
45
zip/zip.go
45
zip/zip.go
|
@ -189,7 +189,9 @@ type ZipWriter struct {
|
||||||
compLevel int
|
compLevel int
|
||||||
|
|
||||||
followSymlinks pathtools.ShouldFollowSymlinks
|
followSymlinks pathtools.ShouldFollowSymlinks
|
||||||
|
ignoreMissingFiles bool
|
||||||
|
|
||||||
|
stderr io.Writer
|
||||||
fs pathtools.FileSystem
|
fs pathtools.FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +217,9 @@ type ZipArgs struct {
|
||||||
NonDeflatedFiles map[string]bool
|
NonDeflatedFiles map[string]bool
|
||||||
WriteIfChanged bool
|
WriteIfChanged bool
|
||||||
StoreSymlinks bool
|
StoreSymlinks bool
|
||||||
|
IgnoreMissingFiles bool
|
||||||
|
|
||||||
|
Stderr io.Writer
|
||||||
Filesystem pathtools.FileSystem
|
Filesystem pathtools.FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +281,8 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
||||||
directories: args.AddDirectoryEntriesToZip,
|
directories: args.AddDirectoryEntriesToZip,
|
||||||
compLevel: args.CompressionLevel,
|
compLevel: args.CompressionLevel,
|
||||||
followSymlinks: followSymlinks,
|
followSymlinks: followSymlinks,
|
||||||
|
ignoreMissingFiles: args.IgnoreMissingFiles,
|
||||||
|
stderr: args.Stderr,
|
||||||
fs: args.Filesystem,
|
fs: args.Filesystem,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +290,10 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
||||||
z.fs = pathtools.OsFs
|
z.fs = pathtools.OsFs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if z.stderr == nil {
|
||||||
|
z.stderr = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
pathMappings := []pathMapping{}
|
pathMappings := []pathMapping{}
|
||||||
|
|
||||||
noCompression := args.CompressionLevel == 0
|
noCompression := args.CompressionLevel == 0
|
||||||
|
@ -301,29 +311,44 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(globbed) == 0 {
|
if len(globbed) == 0 {
|
||||||
return &os.PathError{
|
err := &os.PathError{
|
||||||
Op: "stat",
|
Op: "lstat",
|
||||||
Path: s,
|
Path: s,
|
||||||
Err: os.ErrNotExist,
|
Err: os.ErrNotExist,
|
||||||
}
|
}
|
||||||
|
if args.IgnoreMissingFiles {
|
||||||
|
fmt.Fprintln(args.Stderr, "warning:", err)
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
srcs = append(srcs, globbed...)
|
srcs = append(srcs, globbed...)
|
||||||
}
|
}
|
||||||
if fa.GlobDir != "" {
|
if fa.GlobDir != "" {
|
||||||
if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil {
|
if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !exists {
|
} else if !exists && !args.IgnoreMissingFiles {
|
||||||
return &os.PathError{
|
err := &os.PathError{
|
||||||
Op: "stat",
|
Op: "lstat",
|
||||||
Path: fa.GlobDir,
|
Path: fa.GlobDir,
|
||||||
Err: os.ErrNotExist,
|
Err: os.ErrNotExist,
|
||||||
}
|
}
|
||||||
} else if !isDir {
|
if args.IgnoreMissingFiles {
|
||||||
return &os.PathError{
|
fmt.Fprintln(args.Stderr, "warning:", err)
|
||||||
Op: "stat",
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if !isDir && !args.IgnoreMissingFiles {
|
||||||
|
err := &os.PathError{
|
||||||
|
Op: "lstat",
|
||||||
Path: fa.GlobDir,
|
Path: fa.GlobDir,
|
||||||
Err: syscall.ENOTDIR,
|
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)
|
globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, followSymlinks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -576,6 +601,10 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) er
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) && z.ignoreMissingFiles {
|
||||||
|
fmt.Fprintln(z.stderr, "warning:", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
} else if s.IsDir() {
|
} else if s.IsDir() {
|
||||||
if z.directories {
|
if z.directories {
|
||||||
|
|
|
@ -106,6 +106,7 @@ func TestZip(t *testing.T) {
|
||||||
dirEntries bool
|
dirEntries bool
|
||||||
manifest string
|
manifest string
|
||||||
storeSymlinks bool
|
storeSymlinks bool
|
||||||
|
ignoreMissingFiles bool
|
||||||
|
|
||||||
files []zip.FileHeader
|
files []zip.FileHeader
|
||||||
err error
|
err error
|
||||||
|
@ -338,6 +339,20 @@ func TestZip(t *testing.T) {
|
||||||
fh("a/a/b", fileB, zip.Deflate),
|
fh("a/a/b", fileB, zip.Deflate),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ignore missing files",
|
||||||
|
args: fileArgsBuilder().
|
||||||
|
File("a/a/a").
|
||||||
|
File("a/a/b").
|
||||||
|
File("missing"),
|
||||||
|
compressionLevel: 9,
|
||||||
|
ignoreMissingFiles: true,
|
||||||
|
|
||||||
|
files: []zip.FileHeader{
|
||||||
|
fh("a/a/a", fileA, zip.Deflate),
|
||||||
|
fh("a/a/b", fileB, zip.Deflate),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// errors
|
// errors
|
||||||
{
|
{
|
||||||
|
@ -381,7 +396,9 @@ func TestZip(t *testing.T) {
|
||||||
args.NonDeflatedFiles = test.nonDeflatedFiles
|
args.NonDeflatedFiles = test.nonDeflatedFiles
|
||||||
args.ManifestSourcePath = test.manifest
|
args.ManifestSourcePath = test.manifest
|
||||||
args.StoreSymlinks = test.storeSymlinks
|
args.StoreSymlinks = test.storeSymlinks
|
||||||
|
args.IgnoreMissingFiles = test.ignoreMissingFiles
|
||||||
args.Filesystem = mockFs
|
args.Filesystem = mockFs
|
||||||
|
args.Stderr = &bytes.Buffer{}
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
err := ZipTo(args, buf)
|
err := ZipTo(args, buf)
|
||||||
|
|
Loading…
Reference in New Issue