Merge "Supported minor features in soong_zip"

This commit is contained in:
Treehugger Robot
2017-05-03 08:23:55 +00:00
committed by Gerrit Code Review

View File

@@ -55,33 +55,76 @@ func (nopCloser) Close() error {
} }
type fileArg struct { type fileArg struct {
rootPrefix, relativeRoot, file string pathPrefixInZip, sourcePrefixToStrip string
sourceFiles []string
} }
type pathMapping struct { type pathMapping struct {
dest, src string dest, src string
zipMethod uint16
}
type uniqueSet map[string]bool
func (u *uniqueSet) String() string {
return `""`
}
func (u *uniqueSet) Set(s string) error {
if _, found := (*u)[s]; found {
return fmt.Errorf("File %q was specified twice as a file to not deflate", s)
} else {
(*u)[s] = true
}
return nil
} }
type fileArgs []fileArg type fileArgs []fileArg
func (l *fileArgs) String() string { type file struct{}
type listFiles struct{}
func (f *file) String() string {
return `""` return `""`
} }
func (l *fileArgs) Set(s string) error { func (f *file) Set(s string) error {
if *relativeRoot == "" { if *relativeRoot == "" {
return fmt.Errorf("must pass -C before -f or -l") return fmt.Errorf("must pass -C before -f or -l")
} }
*l = append(*l, fArgs = append(fArgs, fileArg{
fileArg{rootPrefix: filepath.Clean(*rootPrefix), pathPrefixInZip: filepath.Clean(*rootPrefix),
relativeRoot: filepath.Clean(*relativeRoot), sourcePrefixToStrip: filepath.Clean(*relativeRoot),
file: s}) sourceFiles: []string{s},
})
return nil return nil
} }
func (l *fileArgs) Get() interface{} { func (l *listFiles) String() string {
return l return `""`
}
func (l *listFiles) Set(s string) error {
if *relativeRoot == "" {
return fmt.Errorf("must pass -C before -f or -l")
}
list, err := ioutil.ReadFile(s)
if err != nil {
return err
}
fArgs = append(fArgs, fileArg{
pathPrefixInZip: filepath.Clean(*rootPrefix),
sourcePrefixToStrip: filepath.Clean(*relativeRoot),
sourceFiles: strings.Split(string(list), "\n"),
})
return nil
} }
var ( var (
@@ -93,16 +136,17 @@ var (
parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use") parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
compLevel = flag.Int("L", 5, "deflate compression level (0-9)") compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
listFiles fileArgs fArgs fileArgs
files fileArgs nonDeflatedFiles = make(uniqueSet)
cpuProfile = flag.String("cpuprofile", "", "write cpu profile to file") cpuProfile = flag.String("cpuprofile", "", "write cpu profile to file")
traceFile = flag.String("trace", "", "write trace to file") traceFile = flag.String("trace", "", "write trace to file")
) )
func init() { func init() {
flag.Var(&listFiles, "l", "file containing list of .class files") flag.Var(&listFiles{}, "l", "file containing list of .class files")
flag.Var(&files, "f", "file to include in zip") flag.Var(&file{}, "f", "file to include in zip")
flag.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
} }
func usage() { func usage() {
@@ -176,30 +220,15 @@ func main() {
pathMappings := []pathMapping{} pathMappings := []pathMapping{}
set := make(map[string]string) set := make(map[string]string)
// load listFiles, which specify other files to include. for _, fa := range fArgs {
for _, l := range listFiles { for _, src := range fa.sourceFiles {
list, err := ioutil.ReadFile(l.file) if err := fillPathPairs(fa.pathPrefixInZip,
if err != nil { fa.sourcePrefixToStrip, src, set, &pathMappings); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
srcs := strings.Split(string(list), "\n")
for _, src := range srcs {
if err := fillPathPairs(l.rootPrefix, l.relativeRoot, src,
set, &pathMappings); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }
} }
// also include the usual files that are to be added directly.
for _, f := range files {
if err := fillPathPairs(f.rootPrefix, f.relativeRoot,
f.file, set, &pathMappings); err != nil {
log.Fatal(err)
}
}
err := w.write(*out, pathMappings, *manifest) err := w.write(*out, pathMappings, *manifest)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err.Error()) fmt.Fprintln(os.Stderr, err.Error())
@@ -227,7 +256,12 @@ func fillPathPairs(prefix, rel, src string, set map[string]string, pathMappings
set[dest] = src set[dest] = src
} }
*pathMappings = append(*pathMappings, pathMapping{dest: dest, src: src}) zipMethod := zip.Deflate
if _, found := nonDeflatedFiles[dest]; found {
zipMethod = zip.Store
}
*pathMappings = append(*pathMappings,
pathMapping{dest: dest, src: src, zipMethod: zipMethod})
return nil return nil
} }
@@ -269,7 +303,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
defer close(z.writeOps) defer close(z.writeOps)
for _, ele := range pathMappings { for _, ele := range pathMappings {
err = z.writeFile(ele.dest, ele.src) err = z.writeFile(ele.dest, ele.src, ele.zipMethod)
if err != nil { if err != nil {
z.errors <- err z.errors <- err
return return
@@ -277,7 +311,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
} }
if manifest != "" { if manifest != "" {
err = z.writeFile("META-INF/MANIFEST.MF", manifest) err = z.writeFile("META-INF/MANIFEST.MF", manifest, zip.Deflate)
if err != nil { if err != nil {
z.errors <- err z.errors <- err
return return
@@ -371,7 +405,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
} }
} }
func (z *zipWriter) writeFile(dest, src string) error { func (z *zipWriter) writeFile(dest, src string, method uint16) error {
var fileSize int64 var fileSize int64
var executable bool var executable bool
@@ -407,7 +441,7 @@ func (z *zipWriter) writeFile(dest, src string) error {
ze := &zipEntry{ ze := &zipEntry{
fh: &zip.FileHeader{ fh: &zip.FileHeader{
Name: dest, Name: dest,
Method: zip.Deflate, Method: method,
UncompressedSize64: uint64(fileSize), UncompressedSize64: uint64(fileSize),
}, },
@@ -424,7 +458,7 @@ func (z *zipWriter) writeFile(dest, src string) error {
exec := z.rateLimit.RequestExecution() exec := z.rateLimit.RequestExecution()
if fileSize >= minParallelFileSize { if method == zip.Deflate && fileSize >= minParallelFileSize {
wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)
// Allocate enough buffer to hold all readers. We'll limit // Allocate enough buffer to hold all readers. We'll limit
@@ -555,33 +589,55 @@ func (z *zipWriter) compressWholeFile(ze *zipEntry, r *os.File, exec Execution,
return return
} }
compressed, err := z.compressBlock(r, nil, true) readFile := func(r *os.File) ([]byte, error) {
_, err = r.Seek(0, 0)
if err != nil {
return nil, err
}
buf, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return buf, nil
}
ze.futureReaders = make(chan chan io.Reader, 1) ze.futureReaders = make(chan chan io.Reader, 1)
futureReader := make(chan io.Reader, 1) futureReader := make(chan io.Reader, 1)
ze.futureReaders <- futureReader ze.futureReaders <- futureReader
close(ze.futureReaders) close(ze.futureReaders)
if ze.fh.Method == zip.Deflate {
compressed, err := z.compressBlock(r, nil, true)
if err != nil {
z.errors <- err
return
}
if uint64(compressed.Len()) < ze.fh.UncompressedSize64 { if uint64(compressed.Len()) < ze.fh.UncompressedSize64 {
futureReader <- compressed futureReader <- compressed
bufSize = compressed.Len() bufSize = compressed.Len()
} else { } else {
_, err = r.Seek(0, 0) buf, err := readFile(r)
if err != nil { if err != nil {
z.errors <- err z.errors <- err
return return
} }
buf, err := ioutil.ReadAll(r)
if err != nil {
z.errors <- err
return
}
ze.fh.Method = zip.Store ze.fh.Method = zip.Store
futureReader <- bytes.NewReader(buf) futureReader <- bytes.NewReader(buf)
bufSize = int(ze.fh.UncompressedSize64) bufSize = int(ze.fh.UncompressedSize64)
} }
} else {
buf, err := readFile(r)
if err != nil {
z.errors <- err
return
}
ze.fh.Method = zip.Store
futureReader <- bytes.NewReader(buf)
bufSize = int(ze.fh.UncompressedSize64)
}
exec.Finish(bufSize) exec.Finish(bufSize)
close(futureReader) close(futureReader)