aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2018-11-01 13:27:58 -0700
committerColin Cross <ccross@android.com>2018-11-01 20:34:44 +0000
commit714614ced90e25c695031226352099ee1ebc754f (patch)
treed694739a69563c4ad7f62aa1cd0bb14836e64af2 /cmd
parentc29e55d43993c361ce608aff500347861075eab9 (diff)
downloadbuild_soong-714614ced90e25c695031226352099ee1ebc754f.tar.gz
build_soong-714614ced90e25c695031226352099ee1ebc754f.tar.bz2
build_soong-714614ced90e25c695031226352099ee1ebc754f.zip
Keep directories when moving glob results
Patterns containing multiple globs or a recurisve glob may match files with the same name in multiple directories. Keep the relative directories of matches after the path entry containing a glob. Bug: 117295826 Test: zip2zip_test.go Change-Id: I5d663e546953af374175837551d23f484d568377
Diffstat (limited to 'cmd')
-rw-r--r--cmd/zip2zip/zip2zip.go30
-rw-r--r--cmd/zip2zip/zip2zip_test.go96
2 files changed, 124 insertions, 2 deletions
diff --git a/cmd/zip2zip/zip2zip.go b/cmd/zip2zip/zip2zip.go
index c4fb3d6c..491267b0 100644
--- a/cmd/zip2zip/zip2zip.go
+++ b/cmd/zip2zip/zip2zip.go
@@ -148,8 +148,13 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi
} else {
if pathtools.IsGlob(input) {
// If the input is a glob then the output is a directory.
- _, name := filepath.Split(file.Name)
- newName = filepath.Join(output, name)
+ rel, err := filepath.Rel(constantPartOfPattern(input), file.Name)
+ if err != nil {
+ return err
+ } else if strings.HasPrefix("../", rel) {
+ return fmt.Errorf("globbed path %q was not in %q", file.Name, constantPartOfPattern(input))
+ }
+ newName = filepath.Join(output, rel)
} else {
// Otherwise it is a file.
newName = output
@@ -277,3 +282,24 @@ func (m *multiFlag) Match(s string) (bool, error) {
}
return false, nil
}
+
+func constantPartOfPattern(pattern string) string {
+ ret := ""
+ for pattern != "" {
+ var first string
+ first, pattern = splitFirst(pattern)
+ if pathtools.IsGlob(first) {
+ return ret
+ }
+ ret = filepath.Join(ret, first)
+ }
+ return ret
+}
+
+func splitFirst(path string) (string, string) {
+ i := strings.IndexRune(path, filepath.Separator)
+ if i < 0 {
+ return path, ""
+ }
+ return path[:i], path[i+1:]
+}
diff --git a/cmd/zip2zip/zip2zip_test.go b/cmd/zip2zip/zip2zip_test.go
index ae164944..2c4e0056 100644
--- a/cmd/zip2zip/zip2zip_test.go
+++ b/cmd/zip2zip/zip2zip_test.go
@@ -352,6 +352,60 @@ var testCases = []struct {
"a/b",
},
},
+ {
+ name: "recursive glob",
+
+ inputFiles: []string{
+ "a/a/a",
+ "a/a/b",
+ },
+ args: []string{"a/**/*:b"},
+ outputFiles: []string{
+ "b/a/a",
+ "b/a/b",
+ },
+ },
+ {
+ name: "glob",
+
+ inputFiles: []string{
+ "a/a/a",
+ "a/a/b",
+ "a/b",
+ "a/c",
+ },
+ args: []string{"a/*:b"},
+ outputFiles: []string{
+ "b/b",
+ "b/c",
+ },
+ },
+ {
+ name: "top level glob",
+
+ inputFiles: []string{
+ "a",
+ "b",
+ },
+ args: []string{"*:b"},
+ outputFiles: []string{
+ "b/a",
+ "b/b",
+ },
+ },
+ {
+ name: "multilple glob",
+
+ inputFiles: []string{
+ "a/a/a",
+ "a/a/b",
+ },
+ args: []string{"a/*/*:b"},
+ outputFiles: []string{
+ "b/a/a",
+ "b/a/b",
+ },
+ },
}
func errorString(e error) string {
@@ -416,3 +470,45 @@ func TestZip2Zip(t *testing.T) {
})
}
}
+
+func TestConstantPartOfPattern(t *testing.T) {
+ testCases := []struct{ in, out string }{
+ {
+ in: "",
+ out: "",
+ },
+ {
+ in: "a",
+ out: "a",
+ },
+ {
+ in: "*",
+ out: "",
+ },
+ {
+ in: "a/a",
+ out: "a/a",
+ },
+ {
+ in: "a/*",
+ out: "a",
+ },
+ {
+ in: "a/*/a",
+ out: "a",
+ },
+ {
+ in: "a/**/*",
+ out: "a",
+ },
+ }
+
+ for _, test := range testCases {
+ t.Run(test.in, func(t *testing.T) {
+ got := constantPartOfPattern(test.in)
+ if got != test.out {
+ t.Errorf("want %q, got %q", test.out, got)
+ }
+ })
+ }
+}