Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: go/src/infra/tools/cipd/builder.go

Issue 1129043003: cipd: Refactor client to make it more readable. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « go/src/infra/tools/cipd/apps/cipd/main.go ('k') | go/src/infra/tools/cipd/builder_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: go/src/infra/tools/cipd/builder.go
diff --git a/go/src/infra/tools/cipd/builder.go b/go/src/infra/tools/cipd/builder.go
deleted file mode 100644
index f2ce0f0d07c9a95fcd9e29183416736d0381c3ee..0000000000000000000000000000000000000000
--- a/go/src/infra/tools/cipd/builder.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package cipd
-
-import (
- "archive/zip"
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strings"
- "time"
-)
-
-// BuildInstanceOptions defines options for BuildInstance function.
-type BuildInstanceOptions struct {
- // List of files to add to the package.
- Input []File
- // Where to write the package file to.
- Output io.Writer
- // Package name, e.g. 'infra/tools/cipd'.
- PackageName string
-}
-
-// BuildInstance builds a new package instance for package named opts.PackageName
-// by archiving input files (passed via opts.Input). The final binary is written
-// to opts.Output. Some output may be written even if BuildInstance eventually
-// returns an error.
-func BuildInstance(opts BuildInstanceOptions) error {
- err := ValidatePackageName(opts.PackageName)
- if err != nil {
- return err
- }
-
- // Make sure no files are written to package service directory.
- for _, f := range opts.Input {
- if strings.HasPrefix(f.Name(), packageServiceDir+"/") {
- return fmt.Errorf("Can't write to %s: %s", packageServiceDir, f.Name())
- }
- }
-
- // Generate the manifest file, add to the list of input files.
- manifestFile, err := makeManifestFile(opts)
- if err != nil {
- return err
- }
- files := append(opts.Input, manifestFile)
-
- // Make sure filenames are unique.
- seenNames := make(map[string]struct{}, len(files))
- for _, f := range files {
- _, seen := seenNames[f.Name()]
- if seen {
- return fmt.Errorf("File %s is provided twice", f.Name())
- }
- seenNames[f.Name()] = struct{}{}
- }
-
- // Write the final zip file.
- return zipInputFiles(files, opts.Output)
-}
-
-// zipInputFiles deterministically builds a zip archive out of input files and
-// writes it to the writer. Files are written in the order given.
-func zipInputFiles(files []File, w io.Writer) error {
- writer := zip.NewWriter(w)
- defer writer.Close()
-
- // Reports zipping progress to the log each second.
- lastReport := time.Time{}
- progress := func(count int) {
- if time.Since(lastReport) > time.Second {
- lastReport = time.Now()
- log.Infof("Zipping files: %d files left", len(files)-count)
- }
- }
-
- for i, in := range files {
- progress(i)
-
- // Intentionally do not add timestamp or file mode to make zip archive
- // deterministic. See also zip.FileInfoHeader() implementation.
- fh := zip.FileHeader{
- Name: in.Name(),
- Method: zip.Deflate,
- }
-
- mode := os.FileMode(0600)
- if in.Executable() {
- mode |= 0100
- }
- if in.Symlink() {
- mode |= os.ModeSymlink
- }
- fh.SetMode(mode)
-
- dst, err := writer.CreateHeader(&fh)
- if err != nil {
- return err
- }
- if in.Symlink() {
- err = zipSymlinkFile(dst, in)
- } else {
- err = zipRegularFile(dst, in)
- }
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func zipRegularFile(dst io.Writer, f File) error {
- src, err := f.Open()
- if err != nil {
- return err
- }
- defer src.Close()
- written, err := io.Copy(dst, src)
- if err != nil {
- return err
- }
- if uint64(written) != f.Size() {
- return fmt.Errorf("File %s changed midway", f.Name())
- }
- return nil
-}
-
-func zipSymlinkFile(dst io.Writer, f File) error {
- target, err := f.SymlinkTarget()
- if err != nil {
- return err
- }
- // Symlinks are zipped as text files with target path. os.ModeSymlink bit in
- // the header distinguishes them from regular files.
- _, err = dst.Write([]byte(target))
- return err
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-type manifestFile []byte
-
-func (m *manifestFile) Name() string { return manifestName }
-func (m *manifestFile) Size() uint64 { return uint64(len(*m)) }
-func (m *manifestFile) Executable() bool { return false }
-func (m *manifestFile) Symlink() bool { return false }
-
-func (m *manifestFile) SymlinkTarget() (string, error) {
- return "", fmt.Errorf("Not a symlink: %s", m.Name())
-}
-
-func (m *manifestFile) Open() (io.ReadCloser, error) {
- return ioutil.NopCloser(bytes.NewReader(*m)), nil
-}
-
-// makeManifestFile generates a package manifest file and returns it as
-// File interface.
-func makeManifestFile(opts BuildInstanceOptions) (File, error) {
- buf := &bytes.Buffer{}
- err := writeManifest(&Manifest{
- FormatVersion: manifestFormatVersion,
- PackageName: opts.PackageName,
- }, buf)
- if err != nil {
- return nil, err
- }
- out := manifestFile(buf.Bytes())
- return &out, nil
-}
« no previous file with comments | « go/src/infra/tools/cipd/apps/cipd/main.go ('k') | go/src/infra/tools/cipd/builder_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698