blob: fba2e4b1e0f0d7ecd04aee221afa9e6fd26315b1 [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 (
Jeff Gaston11b5c512017-10-12 12:19:14 -070018 "flag"
19 "fmt"
Jeff Gaston11b5c512017-10-12 12:19:14 -070020 "io/ioutil"
21 "os"
Jeff Gaston11b5c512017-10-12 12:19:14 -070022 "runtime"
Colin Crossb051ab52018-09-27 15:04:24 -070023 "runtime/pprof"
24 "runtime/trace"
Colin Crossb7c69112018-09-18 16:51:43 -070025 "strconv"
Jeff Gaston11b5c512017-10-12 12:19:14 -070026 "strings"
27
28 "android/soong/zip"
29)
30
Jeff Gaston11b5c512017-10-12 12:19:14 -070031type uniqueSet map[string]bool
32
33func (u *uniqueSet) String() string {
34 return `""`
35}
36
37func (u *uniqueSet) Set(s string) error {
38 if _, found := (*u)[s]; found {
39 return fmt.Errorf("File %q was specified twice as a file to not deflate", s)
40 } else {
41 (*u)[s] = true
42 }
43
44 return nil
45}
46
47type file struct{}
48
Colin Crossfe945b42018-09-27 15:00:07 -070049func (file) String() string { return `""` }
50
51func (file) Set(s string) error {
52 fileArgsBuilder.File(s)
53 return nil
54}
55
Jeff Gaston11b5c512017-10-12 12:19:14 -070056type listFiles struct{}
57
Colin Crossfe945b42018-09-27 15:00:07 -070058func (listFiles) String() string { return `""` }
59
60func (listFiles) Set(s string) error {
61 fileArgsBuilder.List(s)
62 return nil
63}
64
Jeff Gaston11b5c512017-10-12 12:19:14 -070065type dir struct{}
66
Colin Crossfe945b42018-09-27 15:00:07 -070067func (dir) String() string { return `""` }
Jeff Gaston11b5c512017-10-12 12:19:14 -070068
Colin Crossfe945b42018-09-27 15:00:07 -070069func (dir) Set(s string) error {
70 fileArgsBuilder.Dir(s)
Jeff Gaston11b5c512017-10-12 12:19:14 -070071 return nil
72}
73
Colin Crossfe945b42018-09-27 15:00:07 -070074type relativeRoot struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070075
Colin Crossfe945b42018-09-27 15:00:07 -070076func (relativeRoot) String() string { return "" }
Jeff Gaston11b5c512017-10-12 12:19:14 -070077
Colin Crossfe945b42018-09-27 15:00:07 -070078func (relativeRoot) Set(s string) error {
79 fileArgsBuilder.SourcePrefixToStrip(s)
Jeff Gaston11b5c512017-10-12 12:19:14 -070080 return nil
81}
82
Colin Crossfe945b42018-09-27 15:00:07 -070083type junkPaths struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070084
Colin Crossfe945b42018-09-27 15:00:07 -070085func (junkPaths) IsBoolFlag() bool { return true }
86func (junkPaths) String() string { return "" }
Jeff Gaston11b5c512017-10-12 12:19:14 -070087
Colin Crossfe945b42018-09-27 15:00:07 -070088func (junkPaths) Set(s string) error {
89 v, err := strconv.ParseBool(s)
90 fileArgsBuilder.JunkPaths(v)
Colin Crossb7c69112018-09-18 16:51:43 -070091 return err
92}
93
Colin Crossfe945b42018-09-27 15:00:07 -070094type rootPrefix struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070095
Colin Crossfe945b42018-09-27 15:00:07 -070096func (rootPrefix) String() string { return "" }
97
98func (rootPrefix) Set(s string) error {
99 fileArgsBuilder.PathPrefixInZip(s)
100 return nil
101}
102
103var (
104 fileArgsBuilder = zip.NewFileArgsBuilder()
Jeff Gaston11b5c512017-10-12 12:19:14 -0700105 nonDeflatedFiles = make(uniqueSet)
Jeff Gaston11b5c512017-10-12 12:19:14 -0700106)
107
Jeff Gaston11b5c512017-10-12 12:19:14 -0700108func main() {
Nan Zhang674dd932018-01-26 18:30:36 -0800109 var expandedArgs []string
110 for _, arg := range os.Args {
111 if strings.HasPrefix(arg, "@") {
112 bytes, err := ioutil.ReadFile(strings.TrimPrefix(arg, "@"))
113 if err != nil {
114 fmt.Fprintln(os.Stderr, err.Error())
115 os.Exit(1)
116 }
117 respArgs := zip.ReadRespFile(bytes)
118 expandedArgs = append(expandedArgs, respArgs...)
119 } else {
120 expandedArgs = append(expandedArgs, arg)
121 }
122 }
123
124 flags := flag.NewFlagSet("flags", flag.ExitOnError)
Dan Willemsen7f276c62019-04-20 21:44:18 -0700125 flags.Usage = func() {
126 fmt.Fprintf(os.Stderr, "usage: soong_zip -o zipfile [-m manifest] [-C dir] [-f|-l file] [-D dir]...\n")
127 flags.PrintDefaults()
128 os.Exit(2)
129 }
Nan Zhang674dd932018-01-26 18:30:36 -0800130
131 out := flags.String("o", "", "file to write zip file to")
132 manifest := flags.String("m", "", "input jar manifest file name")
133 directories := flags.Bool("d", false, "include directories in zip")
Nan Zhang674dd932018-01-26 18:30:36 -0800134 compLevel := flags.Int("L", 5, "deflate compression level (0-9)")
135 emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
136 writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
Colin Cross4be8f9e2018-09-28 15:16:48 -0700137 ignoreMissingFiles := flags.Bool("ignore_missing_files", false, "continue if a requested file does not exist")
Colin Cross09f11052018-09-21 15:12:39 -0700138 symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
Colin Cross9cb51db2019-06-17 14:12:41 -0700139 srcJar := flags.Bool("srcjar", false, "move .java files to locations that match their package statement")
Colin Cross09f11052018-09-21 15:12:39 -0700140
Colin Crossdf3f4c82018-09-18 16:31:09 -0700141 parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
Nan Zhang674dd932018-01-26 18:30:36 -0800142 cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
143 traceFile := flags.String("trace", "", "write trace to file")
144
Colin Crossfe945b42018-09-27 15:00:07 -0700145 flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files")
Nan Zhang674dd932018-01-26 18:30:36 -0800146 flags.Var(&listFiles{}, "l", "file containing list of .class files")
147 flags.Var(&dir{}, "D", "directory to include in zip")
148 flags.Var(&file{}, "f", "file to include in zip")
149 flags.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
Colin Crossfe945b42018-09-27 15:00:07 -0700150 flags.Var(&relativeRoot{}, "C", "path to use as relative root of files in following -f, -l, or -D arguments")
151 flags.Var(&junkPaths{}, "j", "junk paths, zip files without directory names")
Nan Zhang674dd932018-01-26 18:30:36 -0800152
153 flags.Parse(expandedArgs[1:])
Jeff Gaston11b5c512017-10-12 12:19:14 -0700154
Colin Crossfe945b42018-09-27 15:00:07 -0700155 if flags.NArg() > 0 {
156 fmt.Fprintf(os.Stderr, "unexpected arguments %s\n", strings.Join(flags.Args(), " "))
157 flags.Usage()
158 }
159
Colin Crossb051ab52018-09-27 15:04:24 -0700160 if *cpuProfile != "" {
161 f, err := os.Create(*cpuProfile)
162 if err != nil {
163 fmt.Fprintln(os.Stderr, err.Error())
164 os.Exit(1)
165 }
166 defer f.Close()
167 pprof.StartCPUProfile(f)
168 defer pprof.StopCPUProfile()
169 }
170
171 if *traceFile != "" {
172 f, err := os.Create(*traceFile)
173 if err != nil {
174 fmt.Fprintln(os.Stderr, err.Error())
175 os.Exit(1)
176 }
177 defer f.Close()
178 err = trace.Start(f)
179 if err != nil {
180 fmt.Fprintln(os.Stderr, err.Error())
181 os.Exit(1)
182 }
183 defer trace.Stop()
184 }
185
Colin Crossfe945b42018-09-27 15:00:07 -0700186 if fileArgsBuilder.Error() != nil {
187 fmt.Fprintln(os.Stderr, fileArgsBuilder.Error())
188 os.Exit(1)
189 }
190
Colin Cross05518bc2018-09-27 15:06:19 -0700191 err := zip.Zip(zip.ZipArgs{
Colin Crossfe945b42018-09-27 15:00:07 -0700192 FileArgs: fileArgsBuilder.FileArgs(),
Jeff Gaston11b5c512017-10-12 12:19:14 -0700193 OutputFilePath: *out,
Jeff Gaston11b5c512017-10-12 12:19:14 -0700194 EmulateJar: *emulateJar,
Colin Cross9cb51db2019-06-17 14:12:41 -0700195 SrcJar: *srcJar,
Jeff Gaston11b5c512017-10-12 12:19:14 -0700196 AddDirectoryEntriesToZip: *directories,
197 CompressionLevel: *compLevel,
198 ManifestSourcePath: *manifest,
199 NumParallelJobs: *parallelJobs,
200 NonDeflatedFiles: nonDeflatedFiles,
Colin Crossf83c1502017-11-10 13:11:02 -0800201 WriteIfChanged: *writeIfChanged,
Colin Cross09f11052018-09-21 15:12:39 -0700202 StoreSymlinks: *symlinks,
Colin Cross4be8f9e2018-09-28 15:16:48 -0700203 IgnoreMissingFiles: *ignoreMissingFiles,
Jeff Gaston11b5c512017-10-12 12:19:14 -0700204 })
205 if err != nil {
Colin Cross09f11052018-09-21 15:12:39 -0700206 fmt.Fprintln(os.Stderr, "error:", err.Error())
Jeff Gaston11b5c512017-10-12 12:19:14 -0700207 os.Exit(1)
208 }
209}