| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package cipd | 5 package local |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "archive/zip" | 8 "archive/zip" |
| 9 "bytes" | 9 "bytes" |
| 10 "fmt" | 10 "fmt" |
| 11 "io" | 11 "io" |
| 12 "io/ioutil" | 12 "io/ioutil" |
| 13 "os" | 13 "os" |
| 14 "strings" | 14 "strings" |
| 15 "time" | 15 "time" |
| 16 |
| 17 "infra/libs/logging" |
| 18 "infra/tools/cipd/common" |
| 16 ) | 19 ) |
| 17 | 20 |
| 18 // BuildInstanceOptions defines options for BuildInstance function. | 21 // BuildInstanceOptions defines options for BuildInstance function. |
| 19 type BuildInstanceOptions struct { | 22 type BuildInstanceOptions struct { |
| 20 // List of files to add to the package. | 23 // List of files to add to the package. |
| 21 Input []File | 24 Input []File |
| 22 // Where to write the package file to. | 25 // Where to write the package file to. |
| 23 Output io.Writer | 26 Output io.Writer |
| 24 // Package name, e.g. 'infra/tools/cipd'. | 27 // Package name, e.g. 'infra/tools/cipd'. |
| 25 PackageName string | 28 PackageName string |
| 29 // Log defines logger to use. |
| 30 Log logging.Logger |
| 26 } | 31 } |
| 27 | 32 |
| 28 // BuildInstance builds a new package instance for package named opts.PackageNam
e | 33 // BuildInstance builds a new package instance for package named opts.PackageNam
e |
| 29 // by archiving input files (passed via opts.Input). The final binary is written | 34 // by archiving input files (passed via opts.Input). The final binary is written |
| 30 // to opts.Output. Some output may be written even if BuildInstance eventually | 35 // to opts.Output. Some output may be written even if BuildInstance eventually |
| 31 // returns an error. | 36 // returns an error. |
| 32 func BuildInstance(opts BuildInstanceOptions) error { | 37 func BuildInstance(opts BuildInstanceOptions) error { |
| 33 » err := ValidatePackageName(opts.PackageName) | 38 » if opts.Log == nil { |
| 39 » » opts.Log = logging.DefaultLogger |
| 40 » } |
| 41 » err := common.ValidatePackageName(opts.PackageName) |
| 34 if err != nil { | 42 if err != nil { |
| 35 return err | 43 return err |
| 36 } | 44 } |
| 37 | 45 |
| 38 // Make sure no files are written to package service directory. | 46 // Make sure no files are written to package service directory. |
| 39 for _, f := range opts.Input { | 47 for _, f := range opts.Input { |
| 40 if strings.HasPrefix(f.Name(), packageServiceDir+"/") { | 48 if strings.HasPrefix(f.Name(), packageServiceDir+"/") { |
| 41 return fmt.Errorf("Can't write to %s: %s", packageServic
eDir, f.Name()) | 49 return fmt.Errorf("Can't write to %s: %s", packageServic
eDir, f.Name()) |
| 42 } | 50 } |
| 43 } | 51 } |
| 44 | 52 |
| 45 // Generate the manifest file, add to the list of input files. | 53 // Generate the manifest file, add to the list of input files. |
| 46 manifestFile, err := makeManifestFile(opts) | 54 manifestFile, err := makeManifestFile(opts) |
| 47 if err != nil { | 55 if err != nil { |
| 48 return err | 56 return err |
| 49 } | 57 } |
| 50 files := append(opts.Input, manifestFile) | 58 files := append(opts.Input, manifestFile) |
| 51 | 59 |
| 52 // Make sure filenames are unique. | 60 // Make sure filenames are unique. |
| 53 seenNames := make(map[string]struct{}, len(files)) | 61 seenNames := make(map[string]struct{}, len(files)) |
| 54 for _, f := range files { | 62 for _, f := range files { |
| 55 _, seen := seenNames[f.Name()] | 63 _, seen := seenNames[f.Name()] |
| 56 if seen { | 64 if seen { |
| 57 return fmt.Errorf("File %s is provided twice", f.Name()) | 65 return fmt.Errorf("File %s is provided twice", f.Name()) |
| 58 } | 66 } |
| 59 seenNames[f.Name()] = struct{}{} | 67 seenNames[f.Name()] = struct{}{} |
| 60 } | 68 } |
| 61 | 69 |
| 62 // Write the final zip file. | 70 // Write the final zip file. |
| 63 » return zipInputFiles(files, opts.Output) | 71 » return zipInputFiles(files, opts.Output, opts.Log) |
| 64 } | 72 } |
| 65 | 73 |
| 66 // zipInputFiles deterministically builds a zip archive out of input files and | 74 // zipInputFiles deterministically builds a zip archive out of input files and |
| 67 // writes it to the writer. Files are written in the order given. | 75 // writes it to the writer. Files are written in the order given. |
| 68 func zipInputFiles(files []File, w io.Writer) error { | 76 func zipInputFiles(files []File, w io.Writer, log logging.Logger) error { |
| 69 writer := zip.NewWriter(w) | 77 writer := zip.NewWriter(w) |
| 70 defer writer.Close() | 78 defer writer.Close() |
| 71 | 79 |
| 72 // Reports zipping progress to the log each second. | 80 // Reports zipping progress to the log each second. |
| 73 lastReport := time.Time{} | 81 lastReport := time.Time{} |
| 74 progress := func(count int) { | 82 progress := func(count int) { |
| 75 if time.Since(lastReport) > time.Second { | 83 if time.Since(lastReport) > time.Second { |
| 76 lastReport = time.Now() | 84 lastReport = time.Now() |
| 77 log.Infof("Zipping files: %d files left", len(files)-cou
nt) | 85 log.Infof("Zipping files: %d files left", len(files)-cou
nt) |
| 78 } | 86 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 err := writeManifest(&Manifest{ | 173 err := writeManifest(&Manifest{ |
| 166 FormatVersion: manifestFormatVersion, | 174 FormatVersion: manifestFormatVersion, |
| 167 PackageName: opts.PackageName, | 175 PackageName: opts.PackageName, |
| 168 }, buf) | 176 }, buf) |
| 169 if err != nil { | 177 if err != nil { |
| 170 return nil, err | 178 return nil, err |
| 171 } | 179 } |
| 172 out := manifestFile(buf.Bytes()) | 180 out := manifestFile(buf.Bytes()) |
| 173 return &out, nil | 181 return &out, nil |
| 174 } | 182 } |
| OLD | NEW |