zip2zip: add flag to uncompress files
Add -0 flag to convert files in a zip to stored instead of deflated. Bug: 69500920 Test: zip2zip_test.go Change-Id: I6c2b10f3b200a53a3339e3c97a78f65192b309ca
This commit is contained in:
@@ -17,6 +17,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -39,11 +40,13 @@ var (
|
|||||||
|
|
||||||
staticTime = time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
|
staticTime = time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
excludes excludeArgs
|
excludes multiFlag
|
||||||
|
uncompress multiFlag
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.Var(&excludes, "x", "exclude a filespec from the output")
|
flag.Var(&excludes, "x", "exclude a filespec from the output")
|
||||||
|
flag.Var(&uncompress, "0", "convert a filespec to uncompressed in the output")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -93,7 +96,7 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if err := zip2zip(&reader.Reader, writer, *sortGlobs, *sortJava, *setTime,
|
if err := zip2zip(&reader.Reader, writer, *sortGlobs, *sortJava, *setTime,
|
||||||
flag.Args(), excludes); err != nil {
|
flag.Args(), excludes, uncompress); err != nil {
|
||||||
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -102,10 +105,11 @@ func main() {
|
|||||||
type pair struct {
|
type pair struct {
|
||||||
*zip.File
|
*zip.File
|
||||||
newName string
|
newName string
|
||||||
|
uncompress bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTime bool,
|
func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTime bool,
|
||||||
includes []string, excludes []string) error {
|
includes, excludes, uncompresses []string) error {
|
||||||
|
|
||||||
matches := []pair{}
|
matches := []pair{}
|
||||||
|
|
||||||
@@ -149,7 +153,7 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi
|
|||||||
newName = output
|
newName = output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
includeMatches = append(includeMatches, pair{file, newName})
|
includeMatches = append(includeMatches, pair{file, newName, false})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +164,7 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi
|
|||||||
if len(includes) == 0 {
|
if len(includes) == 0 {
|
||||||
// implicitly match everything
|
// implicitly match everything
|
||||||
for _, file := range reader.File {
|
for _, file := range reader.File {
|
||||||
matches = append(matches, pair{file, file.Name})
|
matches = append(matches, pair{file, file.Name, false})
|
||||||
}
|
}
|
||||||
sortMatches(matches)
|
sortMatches(matches)
|
||||||
}
|
}
|
||||||
@@ -193,6 +197,15 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi
|
|||||||
}
|
}
|
||||||
seen[match.newName] = match.File
|
seen[match.newName] = match.File
|
||||||
|
|
||||||
|
for _, u := range uncompresses {
|
||||||
|
if uncompressMatch, err := pathtools.Match(u, match.newName); err != nil {
|
||||||
|
return err
|
||||||
|
} else if uncompressMatch {
|
||||||
|
match.uncompress = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
matchesAfterExcludes = append(matchesAfterExcludes, match)
|
matchesAfterExcludes = append(matchesAfterExcludes, match)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,9 +213,33 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi
|
|||||||
if setTime {
|
if setTime {
|
||||||
match.File.SetModTime(staticTime)
|
match.File.SetModTime(staticTime)
|
||||||
}
|
}
|
||||||
if err := writer.CopyFrom(match.File, match.newName); err != nil {
|
if match.uncompress && match.File.FileHeader.Method != zip.Store {
|
||||||
|
fh := match.File.FileHeader
|
||||||
|
fh.Name = match.newName
|
||||||
|
fh.Method = zip.Store
|
||||||
|
fh.CompressedSize64 = fh.UncompressedSize64
|
||||||
|
|
||||||
|
zw, err := writer.CreateHeaderAndroid(&fh)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zr, err := match.File.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(zw, zr)
|
||||||
|
zr.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := writer.CopyFrom(match.File, match.newName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -217,13 +254,13 @@ func includeSplit(s string) (string, string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type excludeArgs []string
|
type multiFlag []string
|
||||||
|
|
||||||
func (e *excludeArgs) String() string {
|
func (e *multiFlag) String() string {
|
||||||
return strings.Join(*e, " ")
|
return strings.Join(*e, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *excludeArgs) Set(s string) error {
|
func (e *multiFlag) Set(s string) error {
|
||||||
*e = append(*e, s)
|
*e = append(*e, s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -31,8 +31,10 @@ var testCases = []struct {
|
|||||||
sortJava bool
|
sortJava bool
|
||||||
args []string
|
args []string
|
||||||
excludes []string
|
excludes []string
|
||||||
|
uncompresses []string
|
||||||
|
|
||||||
outputFiles []string
|
outputFiles []string
|
||||||
|
storedFiles []string
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -251,6 +253,79 @@ var testCases = []struct {
|
|||||||
|
|
||||||
outputFiles: nil,
|
outputFiles: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "uncompress one",
|
||||||
|
|
||||||
|
inputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
uncompresses: []string{"a/a"},
|
||||||
|
|
||||||
|
outputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
storedFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uncompress two",
|
||||||
|
|
||||||
|
inputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
uncompresses: []string{"a/a", "a/b"},
|
||||||
|
|
||||||
|
outputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
storedFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uncompress glob",
|
||||||
|
|
||||||
|
inputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
"a/c.so",
|
||||||
|
"a/d.so",
|
||||||
|
},
|
||||||
|
uncompresses: []string{"a/*.so"},
|
||||||
|
|
||||||
|
outputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
"a/b",
|
||||||
|
"a/c.so",
|
||||||
|
"a/d.so",
|
||||||
|
},
|
||||||
|
storedFiles: []string{
|
||||||
|
"a/c.so",
|
||||||
|
"a/d.so",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uncompress rename",
|
||||||
|
|
||||||
|
inputFiles: []string{
|
||||||
|
"a/a",
|
||||||
|
},
|
||||||
|
args: []string{"a/a:a/b"},
|
||||||
|
uncompresses: []string{"a/b"},
|
||||||
|
|
||||||
|
outputFiles: []string{
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
storedFiles: []string{
|
||||||
|
"a/b",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorString(e error) string {
|
func errorString(e error) string {
|
||||||
@@ -282,7 +357,8 @@ func TestZip2Zip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
outputWriter := zip.NewWriter(outputBuf)
|
outputWriter := zip.NewWriter(outputBuf)
|
||||||
err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false, testCase.args, testCase.excludes)
|
err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false,
|
||||||
|
testCase.args, testCase.excludes, testCase.uncompresses)
|
||||||
if errorString(testCase.err) != errorString(err) {
|
if errorString(testCase.err) != errorString(err) {
|
||||||
t.Fatalf("Unexpected error:\n got: %q\nwant: %q", errorString(err), errorString(testCase.err))
|
t.Fatalf("Unexpected error:\n got: %q\nwant: %q", errorString(err), errorString(testCase.err))
|
||||||
}
|
}
|
||||||
@@ -294,15 +370,22 @@ func TestZip2Zip(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
var outputFiles []string
|
var outputFiles []string
|
||||||
|
var storedFiles []string
|
||||||
if len(outputReader.File) > 0 {
|
if len(outputReader.File) > 0 {
|
||||||
outputFiles = make([]string, len(outputReader.File))
|
outputFiles = make([]string, len(outputReader.File))
|
||||||
for i, file := range outputReader.File {
|
for i, file := range outputReader.File {
|
||||||
outputFiles[i] = file.Name
|
outputFiles[i] = file.Name
|
||||||
|
if file.Method == zip.Store {
|
||||||
|
storedFiles = append(storedFiles, file.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(testCase.outputFiles, outputFiles) {
|
if !reflect.DeepEqual(testCase.outputFiles, outputFiles) {
|
||||||
t.Fatalf("Output file list does not match:\n got: %v\nwant: %v", outputFiles, testCase.outputFiles)
|
t.Fatalf("Output file list does not match:\nwant: %v\n got: %v", testCase.outputFiles, outputFiles)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(testCase.storedFiles, storedFiles) {
|
||||||
|
t.Fatalf("Stored file list does not match:\nwant: %v\n got: %v", testCase.storedFiles, storedFiles)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user