blob: 060c9dd681b7b3605b99f605f4132347697e7f2d [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// 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
15package glob
16
17import (
18 "io/ioutil"
19 "os"
20 "path/filepath"
21 "strings"
22
Colin Cross70b40592015-03-23 12:57:34 -070023 "github.com/google/blueprint/deptools"
Colin Cross6f23ef62015-04-24 15:12:39 -070024 "github.com/google/blueprint/pathtools"
Colin Cross3f40fa42015-01-30 17:27:36 -080025)
26
27func 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.
Colin Cross3e8ec072015-03-31 16:40:23 -070039func GlobWithDepFile(glob, fileListFile, depFile string, excludes []string) (files []string, err error) {
Colin Cross6f23ef62015-04-24 15:12:39 -070040 files, dirs, err := pathtools.GlobWithExcludes(glob, excludes)
41 if err != nil {
42 return nil, err
Colin Cross3f40fa42015-01-30 17:27:36 -080043 }
44
Colin Cross3e8ec072015-03-31 16:40:23 -070045 fileList := strings.Join(files, "\n") + "\n"
Colin Cross3f40fa42015-01-30 17:27:36 -080046
47 writeFileIfChanged(fileListFile, []byte(fileList), 0666)
48 deptools.WriteDepFile(depFile, fileListFile, dirs)
49
50 return
51}
52
53func 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}