Allow duplicate files inputs in soong_zip
Accept duplicate file inputs in soong_zip when they are the same source file. This came up when trying to zip lint srcs, as some java modules have duplicate source files that seem to be ignored by javac. Test: TestZip Bug: 216456886 Change-Id: I8c43df9aded8cf094afaed79cca2b9eb091cc861
This commit is contained in:
52
zip/zip.go
52
zip/zip.go
@@ -201,6 +201,16 @@ func (x IncorrectRelativeRootError) Error() string {
|
||||
return fmt.Sprintf("path %q is outside relative root %q", x.Path, x.RelativeRoot)
|
||||
}
|
||||
|
||||
type ConflictingFileError struct {
|
||||
Dest string
|
||||
Prev string
|
||||
Src string
|
||||
}
|
||||
|
||||
func (x ConflictingFileError) Error() string {
|
||||
return fmt.Sprintf("destination %q has two files %q and %q", x.Dest, x.Prev, x.Src)
|
||||
}
|
||||
|
||||
type ZipWriter struct {
|
||||
time time.Time
|
||||
createdFiles map[string]string
|
||||
@@ -605,13 +615,24 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar
|
||||
if prev, exists := z.createdDirs[dest]; exists {
|
||||
return fmt.Errorf("destination %q is both a directory %q and a file %q", dest, prev, src)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
checkDuplicateFiles := func(dest, src string) (bool, error) {
|
||||
if prev, exists := z.createdFiles[dest]; exists {
|
||||
return fmt.Errorf("destination %q has two files %q and %q", dest, prev, src)
|
||||
if prev != src {
|
||||
return true, ConflictingFileError{
|
||||
Dest: dest,
|
||||
Prev: prev,
|
||||
Src: src,
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
z.createdFiles[dest] = src
|
||||
|
||||
return nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if s.IsDir() {
|
||||
@@ -625,6 +646,14 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar
|
||||
return err
|
||||
}
|
||||
|
||||
duplicate, err := checkDuplicateFiles(dest, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if duplicate {
|
||||
return nil
|
||||
}
|
||||
|
||||
return z.writeSymlink(dest, src)
|
||||
} else if s.Mode().IsRegular() {
|
||||
r, err := z.fs.Open(src)
|
||||
@@ -667,6 +696,14 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar
|
||||
return err
|
||||
}
|
||||
|
||||
duplicate, err := checkDuplicateFiles(dest, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if duplicate {
|
||||
return nil
|
||||
}
|
||||
|
||||
return z.writeFileContents(header, r)
|
||||
} else {
|
||||
return fmt.Errorf("%s is not a file, directory, or symlink", src)
|
||||
@@ -678,7 +715,14 @@ func (z *ZipWriter) addManifest(dest string, src string, _ uint16) error {
|
||||
return fmt.Errorf("destination %q is both a directory %q and a file %q", dest, prev, src)
|
||||
}
|
||||
if prev, exists := z.createdFiles[dest]; exists {
|
||||
return fmt.Errorf("destination %q has two files %q and %q", dest, prev, src)
|
||||
if prev != src {
|
||||
return ConflictingFileError{
|
||||
Dest: dest,
|
||||
Prev: prev,
|
||||
Src: src,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := z.writeDirectory(filepath.Dir(dest), src, true); err != nil {
|
||||
|
@@ -46,6 +46,7 @@ var mockFs = pathtools.MockFs(map[string][]byte{
|
||||
"dangling -> missing": nil,
|
||||
"a/a/d -> b": nil,
|
||||
"c": fileC,
|
||||
"d/a/a": nil,
|
||||
"l_nl": []byte("a/a/a\na/a/b\nc\n\\[\n"),
|
||||
"l_sp": []byte("a/a/a a/a/b c \\["),
|
||||
"l2": []byte("missing\n"),
|
||||
@@ -400,6 +401,17 @@ func TestZip(t *testing.T) {
|
||||
fh("a/a/b", fileB, zip.Deflate),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "duplicate sources",
|
||||
args: fileArgsBuilder().
|
||||
File("a/a/a").
|
||||
File("a/a/a"),
|
||||
compressionLevel: 9,
|
||||
|
||||
files: []zip.FileHeader{
|
||||
fh("a/a/a", fileA, zip.Deflate),
|
||||
},
|
||||
},
|
||||
|
||||
// errors
|
||||
{
|
||||
@@ -427,6 +439,15 @@ func TestZip(t *testing.T) {
|
||||
File("a/a/a"),
|
||||
err: IncorrectRelativeRootError{},
|
||||
},
|
||||
{
|
||||
name: "error conflicting file",
|
||||
args: fileArgsBuilder().
|
||||
SourcePrefixToStrip("a").
|
||||
File("a/a/a").
|
||||
SourcePrefixToStrip("d").
|
||||
File("d/a/a"),
|
||||
err: ConflictingFileError{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
@@ -454,13 +475,17 @@ func TestZip(t *testing.T) {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
} else if test.err != nil {
|
||||
if os.IsNotExist(test.err) {
|
||||
if !os.IsNotExist(test.err) {
|
||||
if !os.IsNotExist(err) {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
}
|
||||
} else if _, wantRelativeRootErr := test.err.(IncorrectRelativeRootError); wantRelativeRootErr {
|
||||
if _, gotRelativeRootErr := err.(IncorrectRelativeRootError); !gotRelativeRootErr {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
}
|
||||
} else if _, wantConflictingFileError := test.err.(ConflictingFileError); wantConflictingFileError {
|
||||
if _, gotConflictingFileError := err.(ConflictingFileError); !gotConflictingFileError {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
}
|
||||
} else {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user