diff options
author | Colin Cross <ccross@android.com> | 2018-11-01 13:27:58 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2018-11-01 20:34:44 +0000 |
commit | 714614ced90e25c695031226352099ee1ebc754f (patch) | |
tree | d694739a69563c4ad7f62aa1cd0bb14836e64af2 /cmd | |
parent | c29e55d43993c361ce608aff500347861075eab9 (diff) | |
download | build_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.go | 30 | ||||
-rw-r--r-- | cmd/zip2zip/zip2zip_test.go | 96 |
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) + } + }) + } +} |