diff options
author | Dan Willemsen <dwillemsen@google.com> | 2016-08-03 00:35:25 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2016-08-10 16:57:03 -0700 |
commit | 3bf1a085050c797f4af31353325c9ee69ca6c02f (patch) | |
tree | 6cc35038a938a8b195c45f8103152bf5c709ec8c /cmd/zip2zip | |
parent | 25a4e07df8d4c6f653d69baa16cd22d1f07e89a1 (diff) | |
download | build_soong-3bf1a085050c797f4af31353325c9ee69ca6c02f.tar.gz build_soong-3bf1a085050c797f4af31353325c9ee69ca6c02f.tar.bz2 build_soong-3bf1a085050c797f4af31353325c9ee69ca6c02f.zip |
Add zip2zip tool to copy zip entries from one file to another
This doesn't do any decompression / recompression, but just copies over
the already compressed contents. So it's similar to zip -U, but allows
rewriting of the paths.
The first expected usecase is to replace img_from_target_files during
the build, since it does the equivalent of this:
zip2zip -i <target-files.zip> -o <img.zip> OTA/android-info.txt:android-info.txt IMAGES/*:.
Except it decompresses and recompresses the images, which takes over a
minute instead of a few seconds.
Change-Id: I88d0df188635088783223873f78e193272dbdf1c
Diffstat (limited to 'cmd/zip2zip')
-rw-r--r-- | cmd/zip2zip/zip2zip.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/cmd/zip2zip/zip2zip.go b/cmd/zip2zip/zip2zip.go new file mode 100644 index 00000000..8e7523ff --- /dev/null +++ b/cmd/zip2zip/zip2zip.go @@ -0,0 +1,128 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "strings" + + "android/soong/third_party/zip" +) + +var ( + input = flag.String("i", "", "zip file to read from") + output = flag.String("o", "", "output file") +) + +func usage() { + fmt.Fprintln(os.Stderr, "usage: zip2zip -i zipfile -o zipfile [filespec]...") + flag.PrintDefaults() + fmt.Fprintln(os.Stderr, " filespec:") + fmt.Fprintln(os.Stderr, " <name>") + fmt.Fprintln(os.Stderr, " <in_name>:<out_name>") + fmt.Fprintln(os.Stderr, " <glob>:<out_dir>/") + fmt.Fprintln(os.Stderr, "") + fmt.Fprintln(os.Stderr, "Files will be copied with their existing compression from the input zipfile to") + fmt.Fprintln(os.Stderr, "the output zipfile, in the order of filespec arguments") + os.Exit(2) +} + +func main() { + flag.Parse() + + if flag.NArg() == 0 || *input == "" || *output == "" { + usage() + } + + reader, err := zip.OpenReader(*input) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(3) + } + defer reader.Close() + + output, err := os.Create(*output) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(4) + } + defer output.Close() + + writer := zip.NewWriter(output) + defer func() { + err := writer.Close() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(5) + } + }() + + for _, arg := range flag.Args() { + var input string + var output string + + // Reserve escaping for future implementation, so make sure no + // one is using \ and expecting a certain behavior. + if strings.Contains(arg, "\\") { + fmt.Fprintln(os.Stderr, "\\ characters are not currently supported") + os.Exit(6) + } + + args := strings.SplitN(arg, ":", 2) + input = args[0] + if len(args) == 2 { + output = args[1] + } + + if strings.IndexAny(input, "*?[") >= 0 { + for _, file := range reader.File { + if match, err := filepath.Match(input, file.Name); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(7) + } else if match { + var newFileName string + if output == "" { + newFileName = file.Name + } else { + _, name := filepath.Split(file.Name) + newFileName = filepath.Join(output, name) + } + err = writer.CopyFrom(file, newFileName) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(8) + } + } + } + } else { + if output == "" { + output = input + } + for _, file := range reader.File { + if input == file.Name { + err = writer.CopyFrom(file, output) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(8) + } + break + } + } + } + } +} |