soong_zip: support globs in -f and -D arguments
-f and -D arguments can now take globs in the Soong format. Also update the use of soong_zip that jars resources to escape the globs in the arguments, and then shell-escape them when writing to the rsp file so the glob escape are not intepreted by ReadRespFile. Also remove an unused argument to the buildAAR rule that could have contained values that needed escaping. Relands I7f20bb169dc01f952d2a7681ec6ee9c05737ed37 with a fix for trailing "\n" in list files, which causes a call to pathtools.Glob("") that returns "./", which could then get incorrectly translated to "../../../" in the zip file. Also adds tests. Test: m checkbuild Test: zip_test.go Change-Id: I54b8eef9231875e6042a32c9f8bcc5c2f779922a
This commit is contained in:
parent
05518bc13b
commit
1d98ee23a3
5 changed files with 109 additions and 24 deletions
|
@ -103,10 +103,10 @@ var buildAAR = pctx.AndroidStaticRule("buildAAR",
|
|||
`cp ${manifest} ${outDir}/AndroidManifest.xml && ` +
|
||||
`cp ${classesJar} ${outDir}/classes.jar && ` +
|
||||
`cp ${rTxt} ${outDir}/R.txt && ` +
|
||||
`${config.SoongZipCmd} -jar -o $out -C ${outDir} -D ${outDir} ${resArgs}`,
|
||||
`${config.SoongZipCmd} -jar -o $out -C ${outDir} -D ${outDir}`,
|
||||
CommandDeps: []string{"${config.SoongZipCmd}"},
|
||||
},
|
||||
"manifest", "classesJar", "rTxt", "resArgs", "outDir")
|
||||
"manifest", "classesJar", "rTxt", "outDir")
|
||||
|
||||
func BuildAAR(ctx android.ModuleContext, outputFile android.WritablePath,
|
||||
classesJar, manifest, rTxt android.Path, res android.Paths) {
|
||||
|
|
|
@ -321,7 +321,7 @@ func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.Writa
|
|||
Output: outputFile,
|
||||
Implicits: deps,
|
||||
Args: map[string]string{
|
||||
"jarArgs": strings.Join(proptools.NinjaEscape(jarArgs), " "),
|
||||
"jarArgs": strings.Join(proptools.NinjaAndShellEscape(jarArgs), " "),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
|
@ -64,7 +66,7 @@ func ResourceDirsToJarArgs(ctx android.ModuleContext,
|
|||
if !strings.HasPrefix(path, dir.String()) {
|
||||
panic(fmt.Errorf("path %q does not start with %q", path, dir))
|
||||
}
|
||||
args = append(args, "-f", path)
|
||||
args = append(args, "-f", pathtools.MatchEscape(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +109,7 @@ func resourceFilesToJarArgs(ctx android.ModuleContext,
|
|||
if i == 0 || dir != lastDir {
|
||||
args = append(args, "-C", dir)
|
||||
}
|
||||
args = append(args, "-f", path)
|
||||
args = append(args, "-f", pathtools.MatchEscape(path))
|
||||
lastDir = dir
|
||||
}
|
||||
|
||||
|
|
76
zip/zip.go
76
zip/zip.go
|
@ -27,6 +27,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
|
@ -163,6 +164,15 @@ func (b *FileArgsBuilder) FileArgs() []FileArg {
|
|||
return b.fileArgs
|
||||
}
|
||||
|
||||
type IncorrectRelativeRootError struct {
|
||||
RelativeRoot string
|
||||
Path string
|
||||
}
|
||||
|
||||
func (x IncorrectRelativeRootError) Error() string {
|
||||
return fmt.Sprintf("path %q is outside relative root %q", x.Path, x.RelativeRoot)
|
||||
}
|
||||
|
||||
type ZipWriter struct {
|
||||
time time.Time
|
||||
createdFiles map[string]string
|
||||
|
@ -271,9 +281,47 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
|||
noCompression := args.CompressionLevel == 0
|
||||
|
||||
for _, fa := range args.FileArgs {
|
||||
srcs := fa.SourceFiles
|
||||
var srcs []string
|
||||
for _, s := range fa.SourceFiles {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
globbed, _, err := z.fs.Glob(s, nil, pathtools.DontFollowSymlinks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(globbed) == 0 {
|
||||
return &os.PathError{
|
||||
Op: "stat",
|
||||
Path: s,
|
||||
Err: os.ErrNotExist,
|
||||
}
|
||||
}
|
||||
srcs = append(srcs, globbed...)
|
||||
}
|
||||
if fa.GlobDir != "" {
|
||||
srcs = append(srcs, recursiveGlobFiles(fa.GlobDir)...)
|
||||
if exists, isDir, err := z.fs.Exists(fa.GlobDir); err != nil {
|
||||
return err
|
||||
} else if !exists {
|
||||
return &os.PathError{
|
||||
Op: "stat",
|
||||
Path: fa.GlobDir,
|
||||
Err: os.ErrNotExist,
|
||||
}
|
||||
} else if !isDir {
|
||||
return &os.PathError{
|
||||
Op: "stat",
|
||||
Path: fa.GlobDir,
|
||||
Err: syscall.ENOTDIR,
|
||||
}
|
||||
}
|
||||
globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, pathtools.DontFollowSymlinks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srcs = append(srcs, globbed...)
|
||||
}
|
||||
for _, src := range srcs {
|
||||
err := fillPathPairs(fa, src, &pathMappings, args.NonDeflatedFiles, noCompression)
|
||||
|
@ -328,11 +376,6 @@ func Zip(args ZipArgs) error {
|
|||
func fillPathPairs(fa FileArg, src string, pathMappings *[]pathMapping,
|
||||
nonDeflatedFiles map[string]bool, noCompression bool) error {
|
||||
|
||||
src = strings.TrimSpace(src)
|
||||
if src == "" {
|
||||
return nil
|
||||
}
|
||||
src = filepath.Clean(src)
|
||||
var dest string
|
||||
|
||||
if fa.JunkPaths {
|
||||
|
@ -343,6 +386,13 @@ func fillPathPairs(fa FileArg, src string, pathMappings *[]pathMapping,
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasPrefix(dest, "../") {
|
||||
return IncorrectRelativeRootError{
|
||||
Path: src,
|
||||
RelativeRoot: fa.SourcePrefixToStrip,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
dest = filepath.Join(fa.PathPrefixInZip, dest)
|
||||
|
||||
|
@ -889,15 +939,3 @@ func (z *ZipWriter) writeSymlink(rel, file string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func recursiveGlobFiles(path string) []string {
|
||||
var files []string
|
||||
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
files = append(files, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return files
|
||||
}
|
||||
|
|
|
@ -129,6 +129,34 @@ func TestZip(t *testing.T) {
|
|||
fh("c", fileC, zip.Deflate),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "files glob",
|
||||
args: fileArgsBuilder().
|
||||
SourcePrefixToStrip("a").
|
||||
File("a/**/*"),
|
||||
compressionLevel: 9,
|
||||
|
||||
files: []zip.FileHeader{
|
||||
fh("a/a", fileA, zip.Deflate),
|
||||
fh("a/b", fileB, zip.Deflate),
|
||||
fhLink("a/c", "../../c"),
|
||||
fhLink("a/d", "b"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dir",
|
||||
args: fileArgsBuilder().
|
||||
SourcePrefixToStrip("a").
|
||||
Dir("a"),
|
||||
compressionLevel: 9,
|
||||
|
||||
files: []zip.FileHeader{
|
||||
fh("a/a", fileA, zip.Deflate),
|
||||
fh("a/b", fileB, zip.Deflate),
|
||||
fhLink("a/c", "../../c"),
|
||||
fhLink("a/d", "b"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "stored files",
|
||||
args: fileArgsBuilder().
|
||||
|
@ -297,12 +325,25 @@ func TestZip(t *testing.T) {
|
|||
File("missing"),
|
||||
err: os.ErrNotExist,
|
||||
},
|
||||
{
|
||||
name: "error missing dir",
|
||||
args: fileArgsBuilder().
|
||||
Dir("missing"),
|
||||
err: os.ErrNotExist,
|
||||
},
|
||||
{
|
||||
name: "error missing file in list",
|
||||
args: fileArgsBuilder().
|
||||
List("l2"),
|
||||
err: os.ErrNotExist,
|
||||
},
|
||||
{
|
||||
name: "error incorrect relative root",
|
||||
args: fileArgsBuilder().
|
||||
SourcePrefixToStrip("b").
|
||||
File("a/a/a"),
|
||||
err: IncorrectRelativeRootError{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
@ -330,6 +371,10 @@ func TestZip(t *testing.T) {
|
|||
if !os.IsNotExist(test.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 {
|
||||
t.Fatalf("want error %v, got %v", test.err, err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue