Support moving sources in srcjars in soong_zip
Add a -srcjar argument to soong_zip that causes it to read the package statement of each .java file and use that to place the source file at a path that matches the package. Test: jar_test.go, zip_test.go Change-Id: I36017e42445ba3b0a82a10a8d81e8ac0cca096f2
This commit is contained in:
@@ -136,6 +136,7 @@ func main() {
|
||||
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
|
||||
ignoreMissingFiles := flags.Bool("ignore_missing_files", false, "continue if a requested file does not exist")
|
||||
symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
|
||||
srcJar := flags.Bool("srcjar", false, "move .java files to locations that match their package statement")
|
||||
|
||||
parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
|
||||
cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
|
||||
@@ -191,6 +192,7 @@ func main() {
|
||||
FileArgs: fileArgsBuilder.FileArgs(),
|
||||
OutputFilePath: *out,
|
||||
EmulateJar: *emulateJar,
|
||||
SrcJar: *srcJar,
|
||||
AddDirectoryEntriesToZip: *directories,
|
||||
CompressionLevel: *compLevel,
|
||||
ManifestSourcePath: *manifest,
|
||||
|
88
zip/zip.go
88
zip/zip.go
@@ -210,6 +210,7 @@ type ZipArgs struct {
|
||||
FileArgs []FileArg
|
||||
OutputFilePath string
|
||||
EmulateJar bool
|
||||
SrcJar bool
|
||||
AddDirectoryEntriesToZip bool
|
||||
CompressionLevel int
|
||||
ManifestSourcePath string
|
||||
@@ -364,7 +365,7 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
return z.write(w, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.NumParallelJobs)
|
||||
return z.write(w, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.SrcJar, args.NumParallelJobs)
|
||||
}
|
||||
|
||||
func Zip(args ZipArgs) error {
|
||||
@@ -446,7 +447,9 @@ func jarSort(mappings []pathMapping) {
|
||||
sort.SliceStable(mappings, less)
|
||||
}
|
||||
|
||||
func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, emulateJar bool, parallelJobs int) error {
|
||||
func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, emulateJar, srcJar bool,
|
||||
parallelJobs int) error {
|
||||
|
||||
z.errors = make(chan error)
|
||||
defer close(z.errors)
|
||||
|
||||
@@ -489,7 +492,7 @@ func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest stri
|
||||
if emulateJar && ele.dest == jar.ManifestFile {
|
||||
err = z.addManifest(ele.dest, ele.src, ele.zipMethod)
|
||||
} else {
|
||||
err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar)
|
||||
err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar, srcJar)
|
||||
}
|
||||
if err != nil {
|
||||
z.errors <- err
|
||||
@@ -588,7 +591,7 @@ func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest stri
|
||||
}
|
||||
|
||||
// imports (possibly with compression) <src> into the zip at sub-path <dest>
|
||||
func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) error {
|
||||
func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar bool) error {
|
||||
var fileSize int64
|
||||
var executable bool
|
||||
|
||||
@@ -606,12 +609,9 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) er
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
} else if s.IsDir() {
|
||||
if z.directories {
|
||||
return z.writeDirectory(dest, src, emulateJar)
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
}
|
||||
|
||||
createParentDirs := func(dest, src string) error {
|
||||
if err := z.writeDirectory(filepath.Dir(dest), src, emulateJar); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -625,32 +625,64 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) er
|
||||
|
||||
z.createdFiles[dest] = src
|
||||
|
||||
if s.Mode()&os.ModeSymlink != 0 {
|
||||
return z.writeSymlink(dest, src)
|
||||
} else if !s.Mode().IsRegular() {
|
||||
return fmt.Errorf("%s is not a file, directory, or symlink", src)
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.IsDir() {
|
||||
if z.directories {
|
||||
return z.writeDirectory(dest, src, emulateJar)
|
||||
}
|
||||
return nil
|
||||
} else if s.Mode()&os.ModeSymlink != 0 {
|
||||
err = createParentDirs(dest, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return z.writeSymlink(dest, src)
|
||||
} else if s.Mode().IsRegular() {
|
||||
r, err := z.fs.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if srcJar && filepath.Ext(src) == ".java" {
|
||||
// rewrite the destination using the package path if it can be determined
|
||||
pkg, err := jar.JavaPackage(r, src)
|
||||
if err != nil {
|
||||
// ignore errors for now, leaving the file at in its original location in the zip
|
||||
} else {
|
||||
dest = filepath.Join(filepath.Join(strings.Split(pkg, ".")...), filepath.Base(src))
|
||||
}
|
||||
|
||||
_, err = r.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fileSize = s.Size()
|
||||
executable = s.Mode()&0100 != 0
|
||||
}
|
||||
|
||||
r, err := z.fs.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header := &zip.FileHeader{
|
||||
Name: dest,
|
||||
Method: method,
|
||||
UncompressedSize64: uint64(fileSize),
|
||||
}
|
||||
|
||||
header := &zip.FileHeader{
|
||||
Name: dest,
|
||||
Method: method,
|
||||
UncompressedSize64: uint64(fileSize),
|
||||
}
|
||||
if executable {
|
||||
header.SetMode(0700)
|
||||
}
|
||||
|
||||
if executable {
|
||||
header.SetMode(0700)
|
||||
}
|
||||
err = createParentDirs(dest, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return z.writeFileContents(header, r)
|
||||
return z.writeFileContents(header, r)
|
||||
} else {
|
||||
return fmt.Errorf("%s is not a file, directory, or symlink", src)
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZipWriter) addManifest(dest string, src string, method uint16) error {
|
||||
|
@@ -40,14 +40,15 @@ var (
|
||||
)
|
||||
|
||||
var mockFs = pathtools.MockFs(map[string][]byte{
|
||||
"a/a/a": fileA,
|
||||
"a/a/b": fileB,
|
||||
"a/a/c -> ../../c": nil,
|
||||
"a/a/d -> b": nil,
|
||||
"c": fileC,
|
||||
"l": []byte("a/a/a\na/a/b\nc\n"),
|
||||
"l2": []byte("missing\n"),
|
||||
"manifest.txt": fileCustomManifest,
|
||||
"a/a/a": fileA,
|
||||
"a/a/b": fileB,
|
||||
"a/a/c -> ../../c": nil,
|
||||
"dangling -> missing": nil,
|
||||
"a/a/d -> b": nil,
|
||||
"c": fileC,
|
||||
"l": []byte("a/a/a\na/a/b\nc\n"),
|
||||
"l2": []byte("missing\n"),
|
||||
"manifest.txt": fileCustomManifest,
|
||||
})
|
||||
|
||||
func fh(name string, contents []byte, method uint16) zip.FileHeader {
|
||||
@@ -209,6 +210,17 @@ func TestZip(t *testing.T) {
|
||||
fh("a/a/d", fileB, zip.Deflate),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dangling symlinks",
|
||||
args: fileArgsBuilder().
|
||||
File("dangling"),
|
||||
compressionLevel: 9,
|
||||
storeSymlinks: true,
|
||||
|
||||
files: []zip.FileHeader{
|
||||
fhLink("dangling", "missing"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list",
|
||||
args: fileArgsBuilder().
|
||||
@@ -554,3 +566,70 @@ func TestReadRespFile(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSrcJar(t *testing.T) {
|
||||
mockFs := pathtools.MockFs(map[string][]byte{
|
||||
"wrong_package.java": []byte("package foo;"),
|
||||
"foo/correct_package.java": []byte("package foo;"),
|
||||
"src/no_package.java": nil,
|
||||
"src2/parse_error.java": []byte("error"),
|
||||
})
|
||||
|
||||
want := []string{
|
||||
"foo/",
|
||||
"foo/wrong_package.java",
|
||||
"foo/correct_package.java",
|
||||
"no_package.java",
|
||||
"src2/",
|
||||
"src2/parse_error.java",
|
||||
}
|
||||
|
||||
args := ZipArgs{}
|
||||
args.FileArgs = NewFileArgsBuilder().File("**/*.java").FileArgs()
|
||||
|
||||
args.SrcJar = true
|
||||
args.AddDirectoryEntriesToZip = true
|
||||
args.Filesystem = mockFs
|
||||
args.Stderr = &bytes.Buffer{}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err := ZipTo(args, buf)
|
||||
if err != nil {
|
||||
t.Fatalf("got error %v", err)
|
||||
}
|
||||
|
||||
br := bytes.NewReader(buf.Bytes())
|
||||
zr, err := zip.NewReader(br, int64(br.Len()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var got []string
|
||||
for _, f := range zr.File {
|
||||
r, err := f.Open()
|
||||
if err != nil {
|
||||
t.Fatalf("error when opening %s: %s", f.Name, err)
|
||||
}
|
||||
|
||||
crc := crc32.NewIEEE()
|
||||
len, err := io.Copy(crc, r)
|
||||
r.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("error when reading %s: %s", f.Name, err)
|
||||
}
|
||||
|
||||
if uint64(len) != f.UncompressedSize64 {
|
||||
t.Errorf("incorrect length for %s, want %d got %d", f.Name, f.UncompressedSize64, len)
|
||||
}
|
||||
|
||||
if crc.Sum32() != f.CRC32 {
|
||||
t.Errorf("incorrect crc for %s, want %x got %x", f.Name, f.CRC32, crc)
|
||||
}
|
||||
|
||||
got = append(got, f.Name)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(want, got) {
|
||||
t.Errorf("want files %q, got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user