github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/cmd/zipsync/zipsync.go (about) 1 // Copyright 2018 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 15 package main 16 17 import ( 18 "archive/zip" 19 "flag" 20 "fmt" 21 "io" 22 "io/ioutil" 23 "log" 24 "os" 25 "path/filepath" 26 "strings" 27 ) 28 29 var ( 30 outputDir = flag.String("d", "", "output dir") 31 outputFile = flag.String("l", "", "output list file") 32 filter = flag.String("f", "", "optional filter pattern") 33 ) 34 35 func must(err error) { 36 if err != nil { 37 log.Fatal(err) 38 } 39 } 40 41 func writeFile(filename string, in io.Reader, perm os.FileMode) error { 42 out, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 43 if err != nil { 44 return err 45 } 46 _, err = io.Copy(out, in) 47 if err != nil { 48 out.Close() 49 return err 50 } 51 52 return out.Close() 53 } 54 55 func main() { 56 flag.Usage = func() { 57 fmt.Fprintln(os.Stderr, "usage: zipsync -d <output dir> [-l <output file>] [-f <pattern>] [zip]...") 58 flag.PrintDefaults() 59 } 60 61 flag.Parse() 62 63 if *outputDir == "" { 64 flag.Usage() 65 os.Exit(1) 66 } 67 68 inputs := flag.Args() 69 70 // For now, just wipe the output directory and replace its contents with the zip files 71 // Eventually this could only modify the directory contents as necessary to bring it up 72 // to date with the zip files. 73 must(os.RemoveAll(*outputDir)) 74 75 must(os.MkdirAll(*outputDir, 0777)) 76 77 var files []string 78 seen := make(map[string]string) 79 80 for _, input := range inputs { 81 reader, err := zip.OpenReader(input) 82 if err != nil { 83 log.Fatal(err) 84 } 85 defer reader.Close() 86 87 for _, f := range reader.File { 88 if *filter != "" { 89 if match, err := filepath.Match(*filter, filepath.Base(f.Name)); err != nil { 90 log.Fatal(err) 91 } else if !match { 92 continue 93 } 94 } 95 if filepath.IsAbs(f.Name) { 96 log.Fatalf("%q in %q is an absolute path", f.Name, input) 97 } 98 99 if prev, exists := seen[f.Name]; exists { 100 log.Fatalf("%q found in both %q and %q", f.Name, prev, input) 101 } 102 seen[f.Name] = input 103 104 filename := filepath.Join(*outputDir, f.Name) 105 if f.FileInfo().IsDir() { 106 must(os.MkdirAll(filename, f.FileInfo().Mode())) 107 } else { 108 must(os.MkdirAll(filepath.Dir(filename), 0777)) 109 in, err := f.Open() 110 if err != nil { 111 log.Fatal(err) 112 } 113 must(writeFile(filename, in, f.FileInfo().Mode())) 114 in.Close() 115 files = append(files, filename) 116 } 117 } 118 } 119 120 if *outputFile != "" { 121 data := strings.Join(files, "\n") + "\n" 122 must(ioutil.WriteFile(*outputFile, []byte(data), 0666)) 123 } 124 }