Support excludes in globs

Java resource support requires globbing directories while ignoring
specific filenames.  Add support for multiple -e options to
soong_glob to specify filenames to exclude, and split out Glob
into GlobRule to insert a rule to generate a glob file list.

Change-Id: Ia911dd68bd1638452881d18378572d015fd4e31a
This commit is contained in:
Colin Cross 2015-03-31 16:40:23 -07:00
parent c77f9d1404
commit 3e8ec07787
3 changed files with 56 additions and 12 deletions

View file

@ -28,8 +28,29 @@ import (
var ( var (
out = flag.String("o", "", "file to write list of files that match glob") out = flag.String("o", "", "file to write list of files that match glob")
excludes multiArg
) )
func init() {
flag.Var(&excludes, "e", "pattern to exclude from results")
}
type multiArg []string
func (m *multiArg) String() string {
return `""`
}
func (m *multiArg) Set(s string) error {
*m = append(*m, s)
return nil
}
func (m *multiArg) Get() interface{} {
return m
}
func usage() { func usage() {
fmt.Fprintf(os.Stderr, "usage: soong_glob -o out glob\n") fmt.Fprintf(os.Stderr, "usage: soong_glob -o out glob\n")
flag.PrintDefaults() flag.PrintDefaults()
@ -48,7 +69,7 @@ func main() {
usage() usage()
} }
_, err := glob.GlobWithDepFile(flag.Arg(0), *out, *out+".d") _, err := glob.GlobWithDepFile(flag.Arg(0), *out, *out+".d", excludes)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err.Error()) fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
os.Exit(1) os.Exit(1)

View file

@ -17,6 +17,7 @@ package common
import ( import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/bootstrap" "github.com/google/blueprint/bootstrap"
@ -46,7 +47,7 @@ var (
// and writes it to $out if it has changed, and writes the directories to $out.d // and writes it to $out if it has changed, and writes the directories to $out.d
globRule = pctx.StaticRule("globRule", globRule = pctx.StaticRule("globRule",
blueprint.RuleParams{ blueprint.RuleParams{
Command: fmt.Sprintf(`%s -o $out "$glob"`, globCmd), Command: fmt.Sprintf(`%s -o $out $excludes "$glob"`, globCmd),
Description: "glob $glob", Description: "glob $glob",
Restat: true, Restat: true,
@ -54,7 +55,7 @@ var (
Deps: blueprint.DepsGCC, Deps: blueprint.DepsGCC,
Depfile: "$out.d", Depfile: "$out.d",
}, },
"glob") "glob", "excludes")
) )
func hasGlob(in []string) bool { func hasGlob(in []string) bool {
@ -88,13 +89,30 @@ func Glob(ctx AndroidModuleContext, globPattern string) []string {
fileListFile := filepath.Join(ModuleOutDir(ctx), "glob", globToString(globPattern)) fileListFile := filepath.Join(ModuleOutDir(ctx), "glob", globToString(globPattern))
depFile := fileListFile + ".d" depFile := fileListFile + ".d"
var excludes []string
// Get a globbed file list, and write out fileListFile and depFile // Get a globbed file list, and write out fileListFile and depFile
files, err := glob.GlobWithDepFile(globPattern, fileListFile, depFile) files, err := glob.GlobWithDepFile(globPattern, fileListFile, depFile, excludes)
if err != nil { if err != nil {
ctx.ModuleErrorf("glob: %s", err.Error()) ctx.ModuleErrorf("glob: %s", err.Error())
return []string{globPattern} return []string{globPattern}
} }
GlobRule(ctx, globPattern, excludes, fileListFile, depFile)
// Make build.ninja depend on the fileListFile
ctx.AddNinjaFileDeps(fileListFile)
return files
}
func GlobRule(ctx AndroidModuleContext, globPattern string, excludes []string,
fileListFile, depFile string) {
var excludeArgs []string
for _, e := range excludes {
excludeArgs = append(excludeArgs, "-e "+e)
}
// Create a rule to rebuild fileListFile if a directory in depFile changes. fileListFile // Create a rule to rebuild fileListFile if a directory in depFile changes. fileListFile
// will only be rewritten if it has changed, preventing unnecesary build.ninja regenerations. // will only be rewritten if it has changed, preventing unnecesary build.ninja regenerations.
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, blueprint.BuildParams{
@ -102,7 +120,8 @@ func Glob(ctx AndroidModuleContext, globPattern string) []string {
Outputs: []string{fileListFile}, Outputs: []string{fileListFile},
Implicits: []string{globCmd}, Implicits: []string{globCmd},
Args: map[string]string{ Args: map[string]string{
"glob": globPattern, "glob": globPattern,
"excludes": strings.Join(excludeArgs, " "),
}, },
}) })
@ -111,11 +130,6 @@ func Glob(ctx AndroidModuleContext, globPattern string) []string {
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{depFile}, Outputs: []string{depFile},
}) })
// Make build.ninja depend on the fileListFile
ctx.AddNinjaFileDeps(fileListFile)
return files
} }
func globToString(glob string) string { func globToString(glob string) string {

View file

@ -35,7 +35,7 @@ func IsGlob(glob string) bool {
// for a recursive glob. // for a recursive glob.
// //
// Returns a list of file paths, and an error. // Returns a list of file paths, and an error.
func GlobWithDepFile(glob, fileListFile, depFile string) (files []string, err error) { func GlobWithDepFile(glob, fileListFile, depFile string, excludes []string) (files []string, err error) {
globPattern := filepath.Base(glob) globPattern := filepath.Base(glob)
globDir := filepath.Dir(glob) globDir := filepath.Dir(glob)
recursive := false recursive := false
@ -64,6 +64,15 @@ func GlobWithDepFile(glob, fileListFile, depFile string) (files []string, err er
return err return err
} }
if match { if match {
for _, e := range excludes {
excludeMatch, err := filepath.Match(e, info.Name())
if err != nil {
return err
}
if excludeMatch {
return nil
}
}
files = append(files, path) files = append(files, path)
} }
} }
@ -71,7 +80,7 @@ func GlobWithDepFile(glob, fileListFile, depFile string) (files []string, err er
return nil return nil
}) })
fileList := strings.Join(files, "\n") fileList := strings.Join(files, "\n") + "\n"
writeFileIfChanged(fileListFile, []byte(fileList), 0666) writeFileIfChanged(fileListFile, []byte(fileList), 0666)
deptools.WriteDepFile(depFile, fileListFile, dirs) deptools.WriteDepFile(depFile, fileListFile, dirs)