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_test.go b/zip/zip_test.go
index a08fb12..93c5f3d 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -98,14 +98,15 @@
 
 func TestZip(t *testing.T) {
 	testCases := []struct {
-		name             string
-		args             *FileArgsBuilder
-		compressionLevel int
-		emulateJar       bool
-		nonDeflatedFiles map[string]bool
-		dirEntries       bool
-		manifest         string
-		storeSymlinks    bool
+		name               string
+		args               *FileArgsBuilder
+		compressionLevel   int
+		emulateJar         bool
+		nonDeflatedFiles   map[string]bool
+		dirEntries         bool
+		manifest           string
+		storeSymlinks      bool
+		ignoreMissingFiles bool
 
 		files []zip.FileHeader
 		err   error
@@ -338,6 +339,20 @@
 				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
 		{
@@ -381,7 +396,9 @@
 			args.NonDeflatedFiles = test.nonDeflatedFiles
 			args.ManifestSourcePath = test.manifest
 			args.StoreSymlinks = test.storeSymlinks
+			args.IgnoreMissingFiles = test.ignoreMissingFiles
 			args.Filesystem = mockFs
+			args.Stderr = &bytes.Buffer{}
 
 			buf := &bytes.Buffer{}
 			err := ZipTo(args, buf)