Home | History | Annotate | Download | only in glob
      1 // 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 
     15 package glob
     16 
     17 import (
     18 	"io/ioutil"
     19 	"os"
     20 	"path/filepath"
     21 	"strings"
     22 
     23 	"github.com/google/blueprint/deptools"
     24 	"github.com/google/blueprint/pathtools"
     25 )
     26 
     27 func IsGlob(glob string) bool {
     28 	return strings.IndexAny(glob, "*?[") >= 0
     29 }
     30 
     31 // GlobWithDepFile finds all files that match glob.  It compares the list of files
     32 // against the contents of fileListFile, and rewrites fileListFile if it has changed.  It also
     33 // writes all of the the directories it traversed as a depenencies on fileListFile to depFile.
     34 //
     35 // The format of glob is either path/*.ext for a single directory glob, or path/**/*.ext
     36 // for a recursive glob.
     37 //
     38 // Returns a list of file paths, and an error.
     39 func GlobWithDepFile(glob, fileListFile, depFile string, excludes []string) (files []string, err error) {
     40 	files, dirs, err := pathtools.GlobWithExcludes(glob, excludes)
     41 	if err != nil {
     42 		return nil, err
     43 	}
     44 
     45 	fileList := strings.Join(files, "\n") + "\n"
     46 
     47 	writeFileIfChanged(fileListFile, []byte(fileList), 0666)
     48 	deptools.WriteDepFile(depFile, fileListFile, dirs)
     49 
     50 	return
     51 }
     52 
     53 func writeFileIfChanged(filename string, data []byte, perm os.FileMode) error {
     54 	var isChanged bool
     55 
     56 	dir := filepath.Dir(filename)
     57 	err := os.MkdirAll(dir, 0777)
     58 	if err != nil {
     59 		return err
     60 	}
     61 
     62 	info, err := os.Stat(filename)
     63 	if err != nil {
     64 		if os.IsNotExist(err) {
     65 			// The file does not exist yet.
     66 			isChanged = true
     67 		} else {
     68 			return err
     69 		}
     70 	} else {
     71 		if info.Size() != int64(len(data)) {
     72 			isChanged = true
     73 		} else {
     74 			oldData, err := ioutil.ReadFile(filename)
     75 			if err != nil {
     76 				return err
     77 			}
     78 
     79 			if len(oldData) != len(data) {
     80 				isChanged = true
     81 			} else {
     82 				for i := range data {
     83 					if oldData[i] != data[i] {
     84 						isChanged = true
     85 						break
     86 					}
     87 				}
     88 			}
     89 		}
     90 	}
     91 
     92 	if isChanged {
     93 		err = ioutil.WriteFile(filename, data, perm)
     94 		if err != nil {
     95 			return err
     96 		}
     97 	}
     98 
     99 	return nil
    100 }
    101