123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // Copyright 2017 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package build
- import (
- "compress/gzip"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- )
- func absPath(ctx Context, p string) string {
- ret, err := filepath.Abs(p)
- if err != nil {
- ctx.Fatalf("Failed to get absolute path: %v", err)
- }
- return ret
- }
- // indexList finds the index of a string in a []string
- func indexList(s string, list []string) int {
- for i, l := range list {
- if l == s {
- return i
- }
- }
- return -1
- }
- // inList determines whether a string is in a []string
- func inList(s string, list []string) bool {
- return indexList(s, list) != -1
- }
- // removeFromlist removes all occurrences of the string in list.
- func removeFromList(s string, list []string) []string {
- filteredList := make([]string, 0, len(list))
- for _, ls := range list {
- if s != ls {
- filteredList = append(filteredList, ls)
- }
- }
- return filteredList
- }
- // ensureDirectoriesExist is a shortcut to os.MkdirAll, sending errors to the ctx logger.
- func ensureDirectoriesExist(ctx Context, dirs ...string) {
- for _, dir := range dirs {
- err := os.MkdirAll(dir, 0777)
- if err != nil {
- ctx.Fatalf("Error creating %s: %q\n", dir, err)
- }
- }
- }
- // ensureEmptyDirectoriesExist ensures that the given directories exist and are empty
- func ensureEmptyDirectoriesExist(ctx Context, dirs ...string) {
- // remove all the directories
- for _, dir := range dirs {
- seenErr := map[string]bool{}
- for {
- err := os.RemoveAll(dir)
- if err == nil {
- break
- }
- if pathErr, ok := err.(*os.PathError); !ok ||
- dir == pathErr.Path || seenErr[pathErr.Path] {
- ctx.Fatalf("Error removing %s: %q\n", dir, err)
- } else {
- seenErr[pathErr.Path] = true
- err = os.Chmod(filepath.Dir(pathErr.Path), 0700)
- if err != nil {
- ctx.Fatal(err)
- }
- }
- }
- }
- // recreate all the directories
- ensureDirectoriesExist(ctx, dirs...)
- }
- // ensureEmptyFileExists ensures that the containing directory exists, and the
- // specified file exists. If it doesn't exist, it will write an empty file.
- func ensureEmptyFileExists(ctx Context, file string) {
- ensureDirectoriesExist(ctx, filepath.Dir(file))
- if _, err := os.Stat(file); os.IsNotExist(err) {
- f, err := os.Create(file)
- if err != nil {
- ctx.Fatalf("Error creating %s: %q\n", file, err)
- }
- f.Close()
- } else if err != nil {
- ctx.Fatalf("Error checking %s: %q\n", file, err)
- }
- }
- // singleUnquote is similar to strconv.Unquote, but can handle multi-character strings inside single quotes.
- func singleUnquote(str string) (string, bool) {
- if len(str) < 2 || str[0] != '\'' || str[len(str)-1] != '\'' {
- return "", false
- }
- return str[1 : len(str)-1], true
- }
- // decodeKeyValue decodes a key=value string
- func decodeKeyValue(str string) (string, string, bool) {
- idx := strings.IndexRune(str, '=')
- if idx == -1 {
- return "", "", false
- }
- return str[:idx], str[idx+1:], true
- }
- // copyFile copies a file from src to dst. filepath.Dir(dst) must exist.
- func copyFile(src, dst string) (int64, error) {
- source, err := os.Open(src)
- if err != nil {
- return 0, err
- }
- defer source.Close()
- destination, err := os.Create(dst)
- if err != nil {
- return 0, err
- }
- defer destination.Close()
- return io.Copy(destination, source)
- }
- // gzipFileToDir writes a compressed copy of src to destDir with the suffix ".gz".
- func gzipFileToDir(src, destDir string) error {
- in, err := os.Open(src)
- if err != nil {
- return fmt.Errorf("failed to open %s: %s", src, err.Error())
- }
- defer in.Close()
- dest := filepath.Join(destDir, filepath.Base(src)+".gz")
- out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 0666)
- if err != nil {
- return fmt.Errorf("failed to open %s: %s", dest, err.Error())
- }
- defer out.Close()
- gz := gzip.NewWriter(out)
- defer gz.Close()
- _, err = io.Copy(gz, in)
- if err != nil {
- return fmt.Errorf("failed to gzip %s: %s", dest, err.Error())
- }
- return nil
- }
|