summaryrefslogtreecommitdiff
path: root/zip
diff options
context:
space:
mode:
author Colin Cross <ccross@android.com> 2018-09-27 15:00:07 -0700
committer Colin Cross <ccross@android.com> 2018-09-28 13:56:06 -0700
commitfe945b4401a839cc7b177d4d745ab64c8347d93a (patch)
tree8d32f573d679c720cc4980c3c5c972104a796c0f /zip
parente9b16159d54bd4063bf317bfa19cf2463df27d46 (diff)
soong_zip: move args parsing into zip.FileArgsBuilder
Add a builder that can construct []FileArg for zip.Run to use. This will help writing tests that cover the command line parsing. Test: later cl Bug: 116751500 Change-Id: I15b5144f5094ab154f13de9c8a84b82db2da4e67
Diffstat (limited to 'zip')
-rw-r--r--zip/cmd/main.go130
-rw-r--r--zip/zip.go105
2 files changed, 134 insertions, 101 deletions
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index dfd56dc62..e379b07f2 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -15,10 +15,8 @@
package main
import (
- "bytes"
"flag"
"fmt"
- "io"
"io/ioutil"
"os"
"runtime"
@@ -28,16 +26,6 @@ import (
"android/soong/zip"
)
-type byteReaderCloser struct {
- *bytes.Reader
- io.Closer
-}
-
-type pathMapping struct {
- dest, src string
- zipMethod uint16
-}
-
type uniqueSet map[string]bool
func (u *uniqueSet) String() string {
@@ -56,106 +44,67 @@ func (u *uniqueSet) Set(s string) error {
type file struct{}
-type listFiles struct{}
-
-type dir struct{}
+func (file) String() string { return `""` }
-func (f *file) String() string {
- return `""`
+func (file) Set(s string) error {
+ fileArgsBuilder.File(s)
+ return nil
}
-func (f *file) Set(s string) error {
- if relativeRoot == "" && !junkPaths {
- return fmt.Errorf("must pass -C or -j before -f")
- }
+type listFiles struct{}
- fArgs = append(fArgs, zip.FileArg{
- PathPrefixInZip: *rootPrefix,
- SourcePrefixToStrip: relativeRoot,
- JunkPaths: junkPaths,
- SourceFiles: []string{s},
- })
+func (listFiles) String() string { return `""` }
+func (listFiles) Set(s string) error {
+ fileArgsBuilder.List(s)
return nil
}
-func (l *listFiles) String() string {
- return `""`
-}
-
-func (l *listFiles) Set(s string) error {
- if relativeRoot == "" && !junkPaths {
- return fmt.Errorf("must pass -C or -j before -l")
- }
-
- list, err := ioutil.ReadFile(s)
- if err != nil {
- return err
- }
+type dir struct{}
- fArgs = append(fArgs, zip.FileArg{
- PathPrefixInZip: *rootPrefix,
- SourcePrefixToStrip: relativeRoot,
- JunkPaths: junkPaths,
- SourceFiles: strings.Split(string(list), "\n"),
- })
+func (dir) String() string { return `""` }
+func (dir) Set(s string) error {
+ fileArgsBuilder.Dir(s)
return nil
}
-func (d *dir) String() string {
- return `""`
-}
+type relativeRoot struct{}
-func (d *dir) Set(s string) error {
- if relativeRoot == "" && !junkPaths {
- return fmt.Errorf("must pass -C or -j before -D")
- }
-
- fArgs = append(fArgs, zip.FileArg{
- PathPrefixInZip: *rootPrefix,
- SourcePrefixToStrip: relativeRoot,
- JunkPaths: junkPaths,
- GlobDir: s,
- })
+func (relativeRoot) String() string { return "" }
+func (relativeRoot) Set(s string) error {
+ fileArgsBuilder.SourcePrefixToStrip(s)
return nil
}
-type relativeRootImpl struct{}
+type junkPaths struct{}
-func (*relativeRootImpl) String() string { return relativeRoot }
+func (junkPaths) IsBoolFlag() bool { return true }
+func (junkPaths) String() string { return "" }
-func (*relativeRootImpl) Set(s string) error {
- relativeRoot = s
- junkPaths = false
- return nil
+func (junkPaths) Set(s string) error {
+ v, err := strconv.ParseBool(s)
+ fileArgsBuilder.JunkPaths(v)
+ return err
}
-type junkPathsImpl struct{}
+type rootPrefix struct{}
-func (*junkPathsImpl) IsBoolFlag() bool { return true }
+func (rootPrefix) String() string { return "" }
-func (*junkPathsImpl) String() string { return relativeRoot }
-
-func (*junkPathsImpl) Set(s string) error {
- var err error
- junkPaths, err = strconv.ParseBool(s)
- relativeRoot = ""
- return err
+func (rootPrefix) Set(s string) error {
+ fileArgsBuilder.PathPrefixInZip(s)
+ return nil
}
var (
- rootPrefix *string
- relativeRoot string
- junkPaths bool
-
- fArgs zip.FileArgs
+ fileArgsBuilder = zip.NewFileArgsBuilder()
nonDeflatedFiles = make(uniqueSet)
)
func usage() {
- fmt.Fprintf(os.Stderr, "usage: zip -o zipfile [-m manifest] -C dir [-f|-l file]...\n")
+ fmt.Fprintf(os.Stderr, "usage: soong_zip -o zipfile [-m manifest] [-C dir] [-f|-l file] [-D dir]...\n")
flag.PrintDefaults()
os.Exit(2)
}
@@ -177,11 +126,11 @@ func main() {
}
flags := flag.NewFlagSet("flags", flag.ExitOnError)
+ flags.Usage = usage
out := flags.String("o", "", "file to write zip file to")
manifest := flags.String("m", "", "input jar manifest file name")
directories := flags.Bool("d", false, "include directories in zip")
- rootPrefix = flags.String("P", "", "path prefix within the zip at which to place files")
compLevel := flags.Int("L", 5, "deflate compression level (0-9)")
emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
@@ -190,17 +139,28 @@ func main() {
cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
traceFile := flags.String("trace", "", "write trace to file")
+ flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files")
flags.Var(&listFiles{}, "l", "file containing list of .class files")
flags.Var(&dir{}, "D", "directory to include in zip")
flags.Var(&file{}, "f", "file to include in zip")
flags.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
- flags.Var(&relativeRootImpl{}, "C", "path to use as relative root of files in following -f, -l, or -D arguments")
- flags.Var(&junkPathsImpl{}, "j", "junk paths, zip files without directory names")
+ flags.Var(&relativeRoot{}, "C", "path to use as relative root of files in following -f, -l, or -D arguments")
+ flags.Var(&junkPaths{}, "j", "junk paths, zip files without directory names")
flags.Parse(expandedArgs[1:])
+ if flags.NArg() > 0 {
+ fmt.Fprintf(os.Stderr, "unexpected arguments %s\n", strings.Join(flags.Args(), " "))
+ flags.Usage()
+ }
+
+ if fileArgsBuilder.Error() != nil {
+ fmt.Fprintln(os.Stderr, fileArgsBuilder.Error())
+ os.Exit(1)
+ }
+
err := zip.Run(zip.ZipArgs{
- FileArgs: fArgs,
+ FileArgs: fileArgsBuilder.FileArgs(),
OutputFilePath: *out,
CpuProfileFilePath: *cpuProfile,
TraceFilePath: *traceFile,
diff --git a/zip/zip.go b/zip/zip.go
index 6b36e102c..80173f3d4 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -68,30 +68,103 @@ type pathMapping struct {
zipMethod uint16
}
-type uniqueSet map[string]bool
+type FileArg struct {
+ PathPrefixInZip, SourcePrefixToStrip string
+ SourceFiles []string
+ JunkPaths bool
+ GlobDir string
+}
-func (u *uniqueSet) String() string {
- return `""`
+type FileArgsBuilder struct {
+ state FileArg
+ err error
+ fs pathtools.FileSystem
+
+ fileArgs []FileArg
}
-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
+func NewFileArgsBuilder() *FileArgsBuilder {
+ return &FileArgsBuilder{
+ fs: pathtools.OsFs,
}
+}
- return nil
+func (b *FileArgsBuilder) JunkPaths(v bool) *FileArgsBuilder {
+ b.state.JunkPaths = v
+ b.state.SourcePrefixToStrip = ""
+ return b
}
-type FileArg struct {
- PathPrefixInZip, SourcePrefixToStrip string
- SourceFiles []string
- JunkPaths bool
- GlobDir string
+func (b *FileArgsBuilder) SourcePrefixToStrip(prefixToStrip string) *FileArgsBuilder {
+ b.state.JunkPaths = false
+ b.state.SourcePrefixToStrip = prefixToStrip
+ return b
+}
+
+func (b *FileArgsBuilder) PathPrefixInZip(rootPrefix string) *FileArgsBuilder {
+ b.state.PathPrefixInZip = rootPrefix
+ return b
+}
+
+func (b *FileArgsBuilder) File(name string) *FileArgsBuilder {
+ if b.err != nil {
+ return b
+ }
+
+ arg := b.state
+ arg.SourceFiles = []string{name}
+ b.fileArgs = append(b.fileArgs, arg)
+ return b
}
-type FileArgs []FileArg
+func (b *FileArgsBuilder) Dir(name string) *FileArgsBuilder {
+ if b.err != nil {
+ return b
+ }
+
+ arg := b.state
+ arg.GlobDir = name
+ b.fileArgs = append(b.fileArgs, arg)
+ return b
+}
+
+func (b *FileArgsBuilder) List(name string) *FileArgsBuilder {
+ if b.err != nil {
+ return b
+ }
+
+ f, err := b.fs.Open(name)
+ if err != nil {
+ b.err = err
+ return b
+ }
+ defer f.Close()
+
+ list, err := ioutil.ReadAll(f)
+ if err != nil {
+ b.err = err
+ return b
+ }
+
+ arg := b.state
+ arg.SourceFiles = strings.Split(string(list), "\n")
+ b.fileArgs = append(b.fileArgs, arg)
+ return b
+}
+
+func (b *FileArgsBuilder) Error() error {
+ if b == nil {
+ return nil
+ }
+ return b.err
+}
+
+func (b *FileArgsBuilder) FileArgs() []FileArg {
+ if b == nil {
+ return nil
+ }
+ return b.fileArgs
+}
type ZipWriter struct {
time time.Time
@@ -121,7 +194,7 @@ type zipEntry struct {
}
type ZipArgs struct {
- FileArgs FileArgs
+ FileArgs []FileArg
OutputFilePath string
CpuProfileFilePath string
TraceFilePath string