blob: c0418f7b5188a9dd1815815a4f2650b1c36d4d8d [file] [log] [blame]
Jeff Gaston11b5c512017-10-12 12:19:14 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18 "bytes"
19 "flag"
20 "fmt"
21 "io"
22 "io/ioutil"
23 "os"
24 "path/filepath"
25 "runtime"
26 "strings"
27
28 "android/soong/zip"
29)
30
31type byteReaderCloser struct {
32 *bytes.Reader
33 io.Closer
34}
35
36type pathMapping struct {
37 dest, src string
38 zipMethod uint16
39}
40
41type uniqueSet map[string]bool
42
43func (u *uniqueSet) String() string {
44 return `""`
45}
46
47func (u *uniqueSet) Set(s string) error {
48 if _, found := (*u)[s]; found {
49 return fmt.Errorf("File %q was specified twice as a file to not deflate", s)
50 } else {
51 (*u)[s] = true
52 }
53
54 return nil
55}
56
57type file struct{}
58
59type listFiles struct{}
60
61type dir struct{}
62
63func (f *file) String() string {
64 return `""`
65}
66
67func (f *file) Set(s string) error {
68 if *relativeRoot == "" {
69 return fmt.Errorf("must pass -C before -f")
70 }
71
72 fArgs = append(fArgs, zip.FileArg{
73 PathPrefixInZip: filepath.Clean(*rootPrefix),
74 SourcePrefixToStrip: filepath.Clean(*relativeRoot),
75 SourceFiles: []string{s},
76 })
77
78 return nil
79}
80
81func (l *listFiles) String() string {
82 return `""`
83}
84
85func (l *listFiles) Set(s string) error {
86 if *relativeRoot == "" {
87 return fmt.Errorf("must pass -C before -l")
88 }
89
90 list, err := ioutil.ReadFile(s)
91 if err != nil {
92 return err
93 }
94
95 fArgs = append(fArgs, zip.FileArg{
96 PathPrefixInZip: filepath.Clean(*rootPrefix),
97 SourcePrefixToStrip: filepath.Clean(*relativeRoot),
98 SourceFiles: strings.Split(string(list), "\n"),
99 })
100
101 return nil
102}
103
104func (d *dir) String() string {
105 return `""`
106}
107
108func (d *dir) Set(s string) error {
109 if *relativeRoot == "" {
110 return fmt.Errorf("must pass -C before -D")
111 }
112
113 fArgs = append(fArgs, zip.FileArg{
114 PathPrefixInZip: filepath.Clean(*rootPrefix),
115 SourcePrefixToStrip: filepath.Clean(*relativeRoot),
116 GlobDir: filepath.Clean(s),
117 })
118
119 return nil
120}
121
122var (
Colin Crossf83c1502017-11-10 13:11:02 -0800123 out = flag.String("o", "", "file to write zip file to")
124 manifest = flag.String("m", "", "input jar manifest file name")
125 directories = flag.Bool("d", false, "include directories in zip")
126 rootPrefix = flag.String("P", "", "path prefix within the zip at which to place files")
127 relativeRoot = flag.String("C", "", "path to use as relative root of files in following -f, -l, or -D arguments")
128 parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
129 compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
130 emulateJar = flag.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
131 writeIfChanged = flag.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
Jeff Gaston11b5c512017-10-12 12:19:14 -0700132
133 fArgs zip.FileArgs
134 nonDeflatedFiles = make(uniqueSet)
135
136 cpuProfile = flag.String("cpuprofile", "", "write cpu profile to file")
137 traceFile = flag.String("trace", "", "write trace to file")
138)
139
140func init() {
141 flag.Var(&listFiles{}, "l", "file containing list of .class files")
142 flag.Var(&dir{}, "D", "directory to include in zip")
143 flag.Var(&file{}, "f", "file to include in zip")
144 flag.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
145}
146
147func usage() {
148 fmt.Fprintf(os.Stderr, "usage: zip -o zipfile [-m manifest] -C dir [-f|-l file]...\n")
149 flag.PrintDefaults()
150 os.Exit(2)
151}
152
153func main() {
154 flag.Parse()
155
156 err := zip.Run(zip.ZipArgs{
157 FileArgs: fArgs,
158 OutputFilePath: *out,
159 CpuProfileFilePath: *cpuProfile,
160 TraceFilePath: *traceFile,
161 EmulateJar: *emulateJar,
162 AddDirectoryEntriesToZip: *directories,
163 CompressionLevel: *compLevel,
164 ManifestSourcePath: *manifest,
165 NumParallelJobs: *parallelJobs,
166 NonDeflatedFiles: nonDeflatedFiles,
Colin Crossf83c1502017-11-10 13:11:02 -0800167 WriteIfChanged: *writeIfChanged,
Jeff Gaston11b5c512017-10-12 12:19:14 -0700168 })
169 if err != nil {
170 fmt.Fprintln(os.Stderr, err.Error())
171 os.Exit(1)
172 }
173}