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
This commit is contained in:
parent
e9b16159d5
commit
fe945b4401
2 changed files with 144 additions and 111 deletions
146
zip/cmd/main.go
146
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{}
|
||||
|
||||
func (file) String() string { return `""` }
|
||||
|
||||
func (file) Set(s string) error {
|
||||
fileArgsBuilder.File(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
type listFiles struct{}
|
||||
|
||||
func (listFiles) String() string { return `""` }
|
||||
|
||||
func (listFiles) Set(s string) error {
|
||||
fileArgsBuilder.List(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
type dir struct{}
|
||||
|
||||
func (f *file) String() string {
|
||||
return `""`
|
||||
}
|
||||
|
||||
func (f *file) Set(s string) error {
|
||||
if relativeRoot == "" && !junkPaths {
|
||||
return fmt.Errorf("must pass -C or -j before -f")
|
||||
}
|
||||
|
||||
fArgs = append(fArgs, zip.FileArg{
|
||||
PathPrefixInZip: *rootPrefix,
|
||||
SourcePrefixToStrip: relativeRoot,
|
||||
JunkPaths: junkPaths,
|
||||
SourceFiles: []string{s},
|
||||
})
|
||||
func (dir) String() string { return `""` }
|
||||
|
||||
func (dir) Set(s string) error {
|
||||
fileArgsBuilder.Dir(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *listFiles) String() string {
|
||||
return `""`
|
||||
}
|
||||
type relativeRoot struct{}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fArgs = append(fArgs, zip.FileArg{
|
||||
PathPrefixInZip: *rootPrefix,
|
||||
SourcePrefixToStrip: relativeRoot,
|
||||
JunkPaths: junkPaths,
|
||||
SourceFiles: strings.Split(string(list), "\n"),
|
||||
})
|
||||
func (relativeRoot) String() string { return "" }
|
||||
|
||||
func (relativeRoot) Set(s string) error {
|
||||
fileArgsBuilder.SourcePrefixToStrip(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dir) String() string {
|
||||
return `""`
|
||||
}
|
||||
type junkPaths struct{}
|
||||
|
||||
func (d *dir) Set(s string) error {
|
||||
if relativeRoot == "" && !junkPaths {
|
||||
return fmt.Errorf("must pass -C or -j before -D")
|
||||
}
|
||||
func (junkPaths) IsBoolFlag() bool { return true }
|
||||
func (junkPaths) String() string { return "" }
|
||||
|
||||
fArgs = append(fArgs, zip.FileArg{
|
||||
PathPrefixInZip: *rootPrefix,
|
||||
SourcePrefixToStrip: relativeRoot,
|
||||
JunkPaths: junkPaths,
|
||||
GlobDir: s,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type relativeRootImpl struct{}
|
||||
|
||||
func (*relativeRootImpl) String() string { return relativeRoot }
|
||||
|
||||
func (*relativeRootImpl) Set(s string) error {
|
||||
relativeRoot = s
|
||||
junkPaths = false
|
||||
return nil
|
||||
}
|
||||
|
||||
type junkPathsImpl struct{}
|
||||
|
||||
func (*junkPathsImpl) IsBoolFlag() bool { return true }
|
||||
|
||||
func (*junkPathsImpl) String() string { return relativeRoot }
|
||||
|
||||
func (*junkPathsImpl) Set(s string) error {
|
||||
var err error
|
||||
junkPaths, err = strconv.ParseBool(s)
|
||||
relativeRoot = ""
|
||||
func (junkPaths) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
fileArgsBuilder.JunkPaths(v)
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
rootPrefix *string
|
||||
relativeRoot string
|
||||
junkPaths bool
|
||||
type rootPrefix struct{}
|
||||
|
||||
fArgs zip.FileArgs
|
||||
func (rootPrefix) String() string { return "" }
|
||||
|
||||
func (rootPrefix) Set(s string) error {
|
||||
fileArgsBuilder.PathPrefixInZip(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
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,
|
||||
|
|
109
zip/zip.go
109
zip/zip.go
|
@ -68,22 +68,6 @@ type pathMapping struct {
|
|||
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 FileArg struct {
|
||||
PathPrefixInZip, SourcePrefixToStrip string
|
||||
SourceFiles []string
|
||||
|
@ -91,7 +75,96 @@ type FileArg struct {
|
|||
GlobDir string
|
||||
}
|
||||
|
||||
type FileArgs []FileArg
|
||||
type FileArgsBuilder struct {
|
||||
state FileArg
|
||||
err error
|
||||
fs pathtools.FileSystem
|
||||
|
||||
fileArgs []FileArg
|
||||
}
|
||||
|
||||
func NewFileArgsBuilder() *FileArgsBuilder {
|
||||
return &FileArgsBuilder{
|
||||
fs: pathtools.OsFs,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *FileArgsBuilder) JunkPaths(v bool) *FileArgsBuilder {
|
||||
b.state.JunkPaths = v
|
||||
b.state.SourcePrefixToStrip = ""
|
||||
return b
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue