blob: e379b07f2066073d05f08021ea0f8c7cfb5044be [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 Crossb7c69112018-09-18 16:51:43 -070023 "strconv"
Jeff Gaston11b5c512017-10-12 12:19:14 -070024 "strings"
25
26 "android/soong/zip"
27)
28
Jeff Gaston11b5c512017-10-12 12:19:14 -070029type uniqueSet map[string]bool
30
31func (u *uniqueSet) String() string {
32 return `""`
33}
34
35func (u *uniqueSet) Set(s string) error {
36 if _, found := (*u)[s]; found {
37 return fmt.Errorf("File %q was specified twice as a file to not deflate", s)
38 } else {
39 (*u)[s] = true
40 }
41
42 return nil
43}
44
45type file struct{}
46
Colin Crossfe945b42018-09-27 15:00:07 -070047func (file) String() string { return `""` }
48
49func (file) Set(s string) error {
50 fileArgsBuilder.File(s)
51 return nil
52}
53
Jeff Gaston11b5c512017-10-12 12:19:14 -070054type listFiles struct{}
55
Colin Crossfe945b42018-09-27 15:00:07 -070056func (listFiles) String() string { return `""` }
57
58func (listFiles) Set(s string) error {
59 fileArgsBuilder.List(s)
60 return nil
61}
62
Jeff Gaston11b5c512017-10-12 12:19:14 -070063type dir struct{}
64
Colin Crossfe945b42018-09-27 15:00:07 -070065func (dir) String() string { return `""` }
Jeff Gaston11b5c512017-10-12 12:19:14 -070066
Colin Crossfe945b42018-09-27 15:00:07 -070067func (dir) Set(s string) error {
68 fileArgsBuilder.Dir(s)
Jeff Gaston11b5c512017-10-12 12:19:14 -070069 return nil
70}
71
Colin Crossfe945b42018-09-27 15:00:07 -070072type relativeRoot struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070073
Colin Crossfe945b42018-09-27 15:00:07 -070074func (relativeRoot) String() string { return "" }
Jeff Gaston11b5c512017-10-12 12:19:14 -070075
Colin Crossfe945b42018-09-27 15:00:07 -070076func (relativeRoot) Set(s string) error {
77 fileArgsBuilder.SourcePrefixToStrip(s)
Jeff Gaston11b5c512017-10-12 12:19:14 -070078 return nil
79}
80
Colin Crossfe945b42018-09-27 15:00:07 -070081type junkPaths struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070082
Colin Crossfe945b42018-09-27 15:00:07 -070083func (junkPaths) IsBoolFlag() bool { return true }
84func (junkPaths) String() string { return "" }
Jeff Gaston11b5c512017-10-12 12:19:14 -070085
Colin Crossfe945b42018-09-27 15:00:07 -070086func (junkPaths) Set(s string) error {
87 v, err := strconv.ParseBool(s)
88 fileArgsBuilder.JunkPaths(v)
Colin Crossb7c69112018-09-18 16:51:43 -070089 return err
90}
91
Colin Crossfe945b42018-09-27 15:00:07 -070092type rootPrefix struct{}
Jeff Gaston11b5c512017-10-12 12:19:14 -070093
Colin Crossfe945b42018-09-27 15:00:07 -070094func (rootPrefix) String() string { return "" }
95
96func (rootPrefix) Set(s string) error {
97 fileArgsBuilder.PathPrefixInZip(s)
98 return nil
99}
100
101var (
102 fileArgsBuilder = zip.NewFileArgsBuilder()
Jeff Gaston11b5c512017-10-12 12:19:14 -0700103 nonDeflatedFiles = make(uniqueSet)
Jeff Gaston11b5c512017-10-12 12:19:14 -0700104)
105
Jeff Gaston11b5c512017-10-12 12:19:14 -0700106func usage() {
Colin Crossfe945b42018-09-27 15:00:07 -0700107 fmt.Fprintf(os.Stderr, "usage: soong_zip -o zipfile [-m manifest] [-C dir] [-f|-l file] [-D dir]...\n")
Jeff Gaston11b5c512017-10-12 12:19:14 -0700108 flag.PrintDefaults()
109 os.Exit(2)
110}
111
112func main() {
Nan Zhang674dd932018-01-26 18:30:36 -0800113 var expandedArgs []string
114 for _, arg := range os.Args {
115 if strings.HasPrefix(arg, "@") {
116 bytes, err := ioutil.ReadFile(strings.TrimPrefix(arg, "@"))
117 if err != nil {
118 fmt.Fprintln(os.Stderr, err.Error())
119 os.Exit(1)
120 }
121 respArgs := zip.ReadRespFile(bytes)
122 expandedArgs = append(expandedArgs, respArgs...)
123 } else {
124 expandedArgs = append(expandedArgs, arg)
125 }
126 }
127
128 flags := flag.NewFlagSet("flags", flag.ExitOnError)
Colin Crossfe945b42018-09-27 15:00:07 -0700129 flags.Usage = usage
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")
137
Colin Crossdf3f4c82018-09-18 16:31:09 -0700138 parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
Nan Zhang674dd932018-01-26 18:30:36 -0800139 cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
140 traceFile := flags.String("trace", "", "write trace to file")
141
Colin Crossfe945b42018-09-27 15:00:07 -0700142 flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files")
Nan Zhang674dd932018-01-26 18:30:36 -0800143 flags.Var(&listFiles{}, "l", "file containing list of .class files")
144 flags.Var(&dir{}, "D", "directory to include in zip")
145 flags.Var(&file{}, "f", "file to include in zip")
146 flags.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
Colin Crossfe945b42018-09-27 15:00:07 -0700147 flags.Var(&relativeRoot{}, "C", "path to use as relative root of files in following -f, -l, or -D arguments")
148 flags.Var(&junkPaths{}, "j", "junk paths, zip files without directory names")
Nan Zhang674dd932018-01-26 18:30:36 -0800149
150 flags.Parse(expandedArgs[1:])
Jeff Gaston11b5c512017-10-12 12:19:14 -0700151
Colin Crossfe945b42018-09-27 15:00:07 -0700152 if flags.NArg() > 0 {
153 fmt.Fprintf(os.Stderr, "unexpected arguments %s\n", strings.Join(flags.Args(), " "))
154 flags.Usage()
155 }
156
157 if fileArgsBuilder.Error() != nil {
158 fmt.Fprintln(os.Stderr, fileArgsBuilder.Error())
159 os.Exit(1)
160 }
161
Jeff Gaston11b5c512017-10-12 12:19:14 -0700162 err := zip.Run(zip.ZipArgs{
Colin Crossfe945b42018-09-27 15:00:07 -0700163 FileArgs: fileArgsBuilder.FileArgs(),
Jeff Gaston11b5c512017-10-12 12:19:14 -0700164 OutputFilePath: *out,
165 CpuProfileFilePath: *cpuProfile,
166 TraceFilePath: *traceFile,
167 EmulateJar: *emulateJar,
168 AddDirectoryEntriesToZip: *directories,
169 CompressionLevel: *compLevel,
170 ManifestSourcePath: *manifest,
171 NumParallelJobs: *parallelJobs,
172 NonDeflatedFiles: nonDeflatedFiles,
Colin Crossf83c1502017-11-10 13:11:02 -0800173 WriteIfChanged: *writeIfChanged,
Jeff Gaston11b5c512017-10-12 12:19:14 -0700174 })
175 if err != nil {
Colin Crossc7feeff2018-09-26 21:36:44 +0000176 fmt.Fprintln(os.Stderr, err.Error())
Jeff Gaston11b5c512017-10-12 12:19:14 -0700177 os.Exit(1)
178 }
179}