Merge changes If1894fd9,Id7925999,I4fe11c3f,Iea2b0781,Id2c0a503

* changes:
  Use PathForSource instead of PathsForSource
  Move AllowMissingDependencies check from PathsForSource to PathForSource
  Propagate errors out of validatePath
  Add t.Run and t.Helper to paths_test.go
  Remove unused intermediates parameter from ExistentPathForSource
This commit is contained in:
Treehugger Robot 2018-02-23 02:28:35 +00:00 committed by Gerrit Code Review
commit 1b5599e462
6 changed files with 173 additions and 135 deletions

View File

@ -240,7 +240,7 @@ func (p PackageContext) PrefixedExistentPathsForSourcesVariable(
return p.VariableFunc(name, func(config Config) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}} ctx := &configErrorWrapper{p, config, []error{}}
paths := ExistentPathsForSources(ctx, "", paths) paths := ExistentPathsForSources(ctx, paths)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
} }

View File

@ -70,7 +70,14 @@ var _ moduleErrorf = blueprint.ModuleContext(nil)
// reportPathError will register an error with the attached context. It // reportPathError will register an error with the attached context. It
// attempts ctx.ModuleErrorf for a better error message first, then falls // attempts ctx.ModuleErrorf for a better error message first, then falls
// back to ctx.Errorf. // back to ctx.Errorf.
func reportPathError(ctx PathContext, format string, args ...interface{}) { func reportPathError(ctx PathContext, err error) {
reportPathErrorf(ctx, "%s", err.Error())
}
// reportPathErrorf will register an error with the attached context. It
// attempts ctx.ModuleErrorf for a better error message first, then falls
// back to ctx.Errorf.
func reportPathErrorf(ctx PathContext, format string, args ...interface{}) {
if mctx, ok := ctx.(moduleErrorf); ok { if mctx, ok := ctx.(moduleErrorf); ok {
mctx.ModuleErrorf(format, args...) mctx.ModuleErrorf(format, args...)
} else if ectx, ok := ctx.(errorfContext); ok { } else if ectx, ok := ctx.(errorfContext); ok {
@ -121,7 +128,7 @@ func GenPathWithExt(ctx ModuleContext, subdir string, p Path, ext string) Module
if path, ok := p.(genPathProvider); ok { if path, ok := p.(genPathProvider); ok {
return path.genPathWithExt(ctx, subdir, ext) return path.genPathWithExt(ctx, subdir, ext)
} }
reportPathError(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p) reportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleGen(ctx) return PathForModuleGen(ctx)
} }
@ -131,7 +138,7 @@ func ObjPathWithExt(ctx ModuleContext, subdir string, p Path, ext string) Module
if path, ok := p.(objPathProvider); ok { if path, ok := p.(objPathProvider); ok {
return path.objPathWithExt(ctx, subdir, ext) return path.objPathWithExt(ctx, subdir, ext)
} }
reportPathError(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p) reportPathErrorf(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleObj(ctx) return PathForModuleObj(ctx)
} }
@ -142,7 +149,7 @@ func ResPathWithName(ctx ModuleContext, p Path, name string) ModuleResPath {
if path, ok := p.(resPathProvider); ok { if path, ok := p.(resPathProvider); ok {
return path.resPathWithName(ctx, name) return path.resPathWithName(ctx, name)
} }
reportPathError(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p) reportPathErrorf(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleRes(ctx) return PathForModuleRes(ctx)
} }
@ -188,21 +195,6 @@ type Paths []Path
// PathsForSource returns Paths rooted from SrcDir // PathsForSource returns Paths rooted from SrcDir
func PathsForSource(ctx PathContext, paths []string) Paths { func PathsForSource(ctx PathContext, paths []string) Paths {
if ctx.Config().AllowMissingDependencies() {
if modCtx, ok := ctx.(ModuleContext); ok {
ret := make(Paths, 0, len(paths))
intermediates := pathForModule(modCtx).withRel("missing")
for _, path := range paths {
p := ExistentPathForSource(ctx, intermediates.String(), path)
if p.Valid() {
ret = append(ret, p.Path())
} else {
modCtx.AddMissingDependencies([]string{path})
}
}
return ret
}
}
ret := make(Paths, len(paths)) ret := make(Paths, len(paths))
for i, path := range paths { for i, path := range paths {
ret[i] = PathForSource(ctx, path) ret[i] = PathForSource(ctx, path)
@ -213,10 +205,10 @@ func PathsForSource(ctx PathContext, paths []string) Paths {
// ExistentPathsForSources returns a list of Paths rooted from SrcDir that are // ExistentPathsForSources returns a list of Paths rooted from SrcDir that are
// found in the tree. If any are not found, they are omitted from the list, // found in the tree. If any are not found, they are omitted from the list,
// and dependencies are added so that we're re-run when they are added. // and dependencies are added so that we're re-run when they are added.
func ExistentPathsForSources(ctx PathContext, intermediates string, paths []string) Paths { func ExistentPathsForSources(ctx PathContext, paths []string) Paths {
ret := make(Paths, 0, len(paths)) ret := make(Paths, 0, len(paths))
for _, path := range paths { for _, path := range paths {
p := ExistentPathForSource(ctx, intermediates, path) p := ExistentPathForSource(ctx, path)
if p.Valid() { if p.Valid() {
ret = append(ret, p.Path()) ret = append(ret, p.Path())
} }
@ -246,7 +238,7 @@ func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string) Paths {
for _, p := range paths { for _, p := range paths {
path := filepath.Clean(p) path := filepath.Clean(p)
if !strings.HasPrefix(path, prefix) { if !strings.HasPrefix(path, prefix) {
reportPathError(ctx, "Path '%s' is not in module source directory '%s'", p, prefix) reportPathErrorf(ctx, "Path '%s' is not in module source directory '%s'", p, prefix)
continue continue
} }
ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):])) ret = append(ret, PathForModuleSrc(ctx, path[len(prefix):]))
@ -477,118 +469,124 @@ func (p SourcePath) withRel(rel string) SourcePath {
// safePathForSource is for paths that we expect are safe -- only for use by go // safePathForSource is for paths that we expect are safe -- only for use by go
// code that is embedding ninja variables in paths // code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, path string) SourcePath { func safePathForSource(ctx PathContext, path string) SourcePath {
p := validateSafePath(ctx, path) p, err := validateSafePath(path)
if err != nil {
reportPathError(ctx, err)
}
ret := SourcePath{basePath{p, ctx.Config(), ""}} ret := SourcePath{basePath{p, ctx.Config(), ""}}
abs, err := filepath.Abs(ret.String()) abs, err := filepath.Abs(ret.String())
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return ret return ret
} }
buildroot, err := filepath.Abs(ctx.Config().buildDir) buildroot, err := filepath.Abs(ctx.Config().buildDir)
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return ret return ret
} }
if strings.HasPrefix(abs, buildroot) { if strings.HasPrefix(abs, buildroot) {
reportPathError(ctx, "source path %s is in output", abs) reportPathErrorf(ctx, "source path %s is in output", abs)
return ret return ret
} }
return ret return ret
} }
// pathForSource creates a SourcePath from pathComponents, but does not check that it exists.
func pathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
p, err := validatePath(pathComponents...)
ret := SourcePath{basePath{p, ctx.Config(), ""}}
if err != nil {
return ret, err
}
abs, err := filepath.Abs(ret.String())
if err != nil {
return ret, err
}
buildroot, err := filepath.Abs(ctx.Config().buildDir)
if err != nil {
return ret, err
}
if strings.HasPrefix(abs, buildroot) {
return ret, fmt.Errorf("source path %s is in output", abs)
}
if pathtools.IsGlob(ret.String()) {
return ret, fmt.Errorf("path may not contain a glob: %s", ret.String())
}
return ret, nil
}
// existsWithDependencies returns true if the path exists, and adds appropriate dependencies to rerun if the
// path does not exist.
func existsWithDependencies(ctx PathContext, path SourcePath) (exists bool, err error) {
var files []string
if gctx, ok := ctx.(PathGlobContext); ok {
// Use glob to produce proper dependencies, even though we only want
// a single file.
files, err = gctx.GlobWithDeps(path.String(), nil)
} else {
var deps []string
// We cannot add build statements in this context, so we fall back to
// AddNinjaFileDeps
files, deps, err = pathtools.Glob(path.String(), nil)
ctx.AddNinjaFileDeps(deps...)
}
if err != nil {
return false, fmt.Errorf("glob: %s", err.Error())
}
return len(files) > 0, nil
}
// PathForSource joins the provided path components and validates that the result // PathForSource joins the provided path components and validates that the result
// neither escapes the source dir nor is in the out dir. // neither escapes the source dir nor is in the out dir.
// On error, it will return a usable, but invalid SourcePath, and report a ModuleError. // On error, it will return a usable, but invalid SourcePath, and report a ModuleError.
func PathForSource(ctx PathContext, pathComponents ...string) SourcePath { func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
p := validatePath(ctx, pathComponents...) path, err := pathForSource(ctx, pathComponents...)
ret := SourcePath{basePath{p, ctx.Config(), ""}}
abs, err := filepath.Abs(ret.String())
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return ret
}
buildroot, err := filepath.Abs(ctx.Config().buildDir)
if err != nil {
reportPathError(ctx, "%s", err.Error())
return ret
}
if strings.HasPrefix(abs, buildroot) {
reportPathError(ctx, "source path %s is in output", abs)
return ret
} }
if exists, _, err := ctx.Fs().Exists(ret.String()); err != nil { if modCtx, ok := ctx.(ModuleContext); ok && ctx.Config().AllowMissingDependencies() {
reportPathError(ctx, "%s: %s", ret, err.Error()) exists, err := existsWithDependencies(ctx, path)
if err != nil {
reportPathError(ctx, err)
}
if !exists {
modCtx.AddMissingDependencies([]string{path.String()})
}
} else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
reportPathErrorf(ctx, "%s: %s", path, err.Error())
} else if !exists { } else if !exists {
reportPathError(ctx, "source path %s does not exist", ret) reportPathErrorf(ctx, "source path %s does not exist", path)
} }
return ret return path
} }
// ExistentPathForSource returns an OptionalPath with the SourcePath if the // ExistentPathForSource returns an OptionalPath with the SourcePath if the
// path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added // path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added
// so that the ninja file will be regenerated if the state of the path changes. // so that the ninja file will be regenerated if the state of the path changes.
func ExistentPathForSource(ctx PathContext, intermediates string, pathComponents ...string) OptionalPath { func ExistentPathForSource(ctx PathContext, pathComponents ...string) OptionalPath {
if len(pathComponents) == 0 { path, err := pathForSource(ctx, pathComponents...)
// For when someone forgets the 'intermediates' argument
panic("Missing path(s)")
}
p := validatePath(ctx, pathComponents...)
path := SourcePath{basePath{p, ctx.Config(), ""}}
abs, err := filepath.Abs(path.String())
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return OptionalPath{} return OptionalPath{}
} }
buildroot, err := filepath.Abs(ctx.Config().buildDir)
exists, err := existsWithDependencies(ctx, path)
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return OptionalPath{} return OptionalPath{}
} }
if strings.HasPrefix(abs, buildroot) { if !exists {
reportPathError(ctx, "source path %s is in output", abs)
return OptionalPath{} return OptionalPath{}
} }
if pathtools.IsGlob(path.String()) {
reportPathError(ctx, "path may not contain a glob: %s", path.String())
return OptionalPath{}
}
if gctx, ok := ctx.(PathGlobContext); ok {
// Use glob to produce proper dependencies, even though we only want
// a single file.
files, err := gctx.GlobWithDeps(path.String(), nil)
if err != nil {
reportPathError(ctx, "glob: %s", err.Error())
return OptionalPath{}
}
if len(files) == 0 {
return OptionalPath{}
}
} else {
// We cannot add build statements in this context, so we fall back to
// AddNinjaFileDeps
files, dirs, err := pathtools.Glob(path.String(), nil)
if err != nil {
reportPathError(ctx, "glob: %s", err.Error())
return OptionalPath{}
}
ctx.AddNinjaFileDeps(dirs...)
if len(files) == 0 {
return OptionalPath{}
}
ctx.AddNinjaFileDeps(path.String())
}
return OptionalPathForPath(path) return OptionalPathForPath(path)
} }
@ -599,7 +597,10 @@ func (p SourcePath) String() string {
// Join creates a new SourcePath with paths... joined with the current path. The // Join creates a new SourcePath with paths... joined with the current path. The
// provided paths... may not use '..' to escape from the current path. // provided paths... may not use '..' to escape from the current path.
func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath { func (p SourcePath) Join(ctx PathContext, paths ...string) SourcePath {
path := validatePath(ctx, paths...) path, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
return p.withRel(path) return p.withRel(path)
} }
@ -612,17 +613,17 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
} else if srcPath, ok := path.(SourcePath); ok { } else if srcPath, ok := path.(SourcePath); ok {
relDir = srcPath.path relDir = srcPath.path
} else { } else {
reportPathError(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path) reportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
return OptionalPath{} return OptionalPath{}
} }
dir := filepath.Join(p.config.srcDir, p.path, relDir) dir := filepath.Join(p.config.srcDir, p.path, relDir)
// Use Glob so that we are run again if the directory is added. // Use Glob so that we are run again if the directory is added.
if pathtools.IsGlob(dir) { if pathtools.IsGlob(dir) {
reportPathError(ctx, "Path may not contain a glob: %s", dir) reportPathErrorf(ctx, "Path may not contain a glob: %s", dir)
} }
paths, err := ctx.GlobWithDeps(dir, []string{}) paths, err := ctx.GlobWithDeps(dir, []string{})
if err != nil { if err != nil {
reportPathError(ctx, "glob: %s", err.Error()) reportPathErrorf(ctx, "glob: %s", err.Error())
return OptionalPath{} return OptionalPath{}
} }
if len(paths) == 0 { if len(paths) == 0 {
@ -630,7 +631,7 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
} }
relPath, err := filepath.Rel(p.config.srcDir, paths[0]) relPath, err := filepath.Rel(p.config.srcDir, paths[0])
if err != nil { if err != nil {
reportPathError(ctx, "%s", err.Error()) reportPathError(ctx, err)
return OptionalPath{} return OptionalPath{}
} }
return OptionalPathForPath(PathForSource(ctx, relPath)) return OptionalPathForPath(PathForSource(ctx, relPath))
@ -652,7 +653,10 @@ var _ Path = OutputPath{}
// validated to not escape the build dir. // validated to not escape the build dir.
// On error, it will return a usable, but invalid OutputPath, and report a ModuleError. // On error, it will return a usable, but invalid OutputPath, and report a ModuleError.
func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath { func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath {
path := validatePath(ctx, pathComponents...) path, err := validatePath(pathComponents...)
if err != nil {
reportPathError(ctx, err)
}
return OutputPath{basePath{path, ctx.Config(), ""}} return OutputPath{basePath{path, ctx.Config(), ""}}
} }
@ -669,14 +673,20 @@ func (p OutputPath) RelPathString() string {
// Join creates a new OutputPath with paths... joined with the current path. The // Join creates a new OutputPath with paths... joined with the current path. The
// provided paths... may not use '..' to escape from the current path. // provided paths... may not use '..' to escape from the current path.
func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath { func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
path := validatePath(ctx, paths...) path, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
return p.withRel(path) return p.withRel(path)
} }
// PathForIntermediates returns an OutputPath representing the top-level // PathForIntermediates returns an OutputPath representing the top-level
// intermediates directory. // intermediates directory.
func PathForIntermediates(ctx PathContext, paths ...string) OutputPath { func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
path := validatePath(ctx, paths...) path, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
return PathForOutput(ctx, ".intermediates", path) return PathForOutput(ctx, ".intermediates", path)
} }
@ -693,7 +703,10 @@ var _ resPathProvider = ModuleSrcPath{}
// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the // PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
// module's local source directory. // module's local source directory.
func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath { func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath {
p := validatePath(ctx, paths...) p, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
path := ModuleSrcPath{PathForSource(ctx, ctx.ModuleDir(), p)} path := ModuleSrcPath{PathForSource(ctx, ctx.ModuleDir(), p)}
path.basePath.rel = p path.basePath.rel = p
return path return path
@ -765,13 +778,16 @@ func PathForVndkRefAbiDump(ctx ModuleContext, version, fileName string, vndkOrNd
} }
refDumpFileStr := "prebuilts/abi-dumps/" + vndkOrNdkDir + "/" + version + "/" + refDumpFileStr := "prebuilts/abi-dumps/" + vndkOrNdkDir + "/" + version + "/" +
archName + "/" + sourceOrBinaryDir + "/" + fileName + ext archName + "/" + sourceOrBinaryDir + "/" + fileName + ext
return ExistentPathForSource(ctx, "", refDumpFileStr) return ExistentPathForSource(ctx, refDumpFileStr)
} }
// PathForModuleOut returns a Path representing the paths... under the module's // PathForModuleOut returns a Path representing the paths... under the module's
// output directory. // output directory.
func PathForModuleOut(ctx ModuleContext, paths ...string) ModuleOutPath { func PathForModuleOut(ctx ModuleContext, paths ...string) ModuleOutPath {
p := validatePath(ctx, paths...) p, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
return ModuleOutPath{ return ModuleOutPath{
OutputPath: pathForModule(ctx).withRel(p), OutputPath: pathForModule(ctx).withRel(p),
} }
@ -790,7 +806,10 @@ var _ objPathProvider = ModuleGenPath{}
// PathForModuleGen returns a Path representing the paths... under the module's // PathForModuleGen returns a Path representing the paths... under the module's
// `gen' directory. // `gen' directory.
func PathForModuleGen(ctx ModuleContext, paths ...string) ModuleGenPath { func PathForModuleGen(ctx ModuleContext, paths ...string) ModuleGenPath {
p := validatePath(ctx, paths...) p, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
return ModuleGenPath{ return ModuleGenPath{
ModuleOutPath: ModuleOutPath{ ModuleOutPath: ModuleOutPath{
OutputPath: pathForModule(ctx).withRel("gen").withRel(p), OutputPath: pathForModule(ctx).withRel("gen").withRel(p),
@ -818,7 +837,10 @@ var _ Path = ModuleObjPath{}
// PathForModuleObj returns a Path representing the paths... under the module's // PathForModuleObj returns a Path representing the paths... under the module's
// 'obj' directory. // 'obj' directory.
func PathForModuleObj(ctx ModuleContext, pathComponents ...string) ModuleObjPath { func PathForModuleObj(ctx ModuleContext, pathComponents ...string) ModuleObjPath {
p := validatePath(ctx, pathComponents...) p, err := validatePath(pathComponents...)
if err != nil {
reportPathError(ctx, err)
}
return ModuleObjPath{PathForModuleOut(ctx, "obj", p)} return ModuleObjPath{PathForModuleOut(ctx, "obj", p)}
} }
@ -833,7 +855,11 @@ var _ Path = ModuleResPath{}
// PathForModuleRes returns a Path representing the paths... under the module's // PathForModuleRes returns a Path representing the paths... under the module's
// 'res' directory. // 'res' directory.
func PathForModuleRes(ctx ModuleContext, pathComponents ...string) ModuleResPath { func PathForModuleRes(ctx ModuleContext, pathComponents ...string) ModuleResPath {
p := validatePath(ctx, pathComponents...) p, err := validatePath(pathComponents...)
if err != nil {
reportPathError(ctx, err)
}
return ModuleResPath{PathForModuleOut(ctx, "res", p)} return ModuleResPath{PathForModuleOut(ctx, "res", p)}
} }
@ -879,36 +905,34 @@ func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string
// validateSafePath validates a path that we trust (may contain ninja variables). // validateSafePath validates a path that we trust (may contain ninja variables).
// Ensures that each path component does not attempt to leave its component. // Ensures that each path component does not attempt to leave its component.
func validateSafePath(ctx PathContext, pathComponents ...string) string { func validateSafePath(pathComponents ...string) (string, error) {
for _, path := range pathComponents { for _, path := range pathComponents {
path := filepath.Clean(path) path := filepath.Clean(path)
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") { if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
reportPathError(ctx, "Path is outside directory: %s", path) return "", fmt.Errorf("Path is outside directory: %s", path)
return ""
} }
} }
// TODO: filepath.Join isn't necessarily correct with embedded ninja // TODO: filepath.Join isn't necessarily correct with embedded ninja
// variables. '..' may remove the entire ninja variable, even if it // variables. '..' may remove the entire ninja variable, even if it
// will be expanded to multiple nested directories. // will be expanded to multiple nested directories.
return filepath.Join(pathComponents...) return filepath.Join(pathComponents...), nil
} }
// validatePath validates that a path does not include ninja variables, and that // validatePath validates that a path does not include ninja variables, and that
// each path component does not attempt to leave its component. Returns a joined // each path component does not attempt to leave its component. Returns a joined
// version of each path component. // version of each path component.
func validatePath(ctx PathContext, pathComponents ...string) string { func validatePath(pathComponents ...string) (string, error) {
for _, path := range pathComponents { for _, path := range pathComponents {
if strings.Contains(path, "$") { if strings.Contains(path, "$") {
reportPathError(ctx, "Path contains invalid character($): %s", path) return "", fmt.Errorf("Path contains invalid character($): %s", path)
return ""
} }
} }
return validateSafePath(ctx, pathComponents...) return validateSafePath(pathComponents...)
} }
func PathForPhony(ctx PathContext, phony string) WritablePath { func PathForPhony(ctx PathContext, phony string) WritablePath {
if strings.ContainsAny(phony, "$/") { if strings.ContainsAny(phony, "$/") {
reportPathError(ctx, "Phony target contains invalid character ($ or /): %s", phony) reportPathErrorf(ctx, "Phony target contains invalid character ($ or /): %s", phony)
} }
return PhonyPath{basePath{phony, ctx.Config(), ""}} return PhonyPath{basePath{phony, ctx.Config(), ""}}
} }
@ -931,7 +955,10 @@ func (p testPath) String() string {
} }
func PathForTesting(paths ...string) Path { func PathForTesting(paths ...string) Path {
p := validateSafePath(nil, paths...) p, err := validateSafePath(paths...)
if err != nil {
panic(err)
}
return testPath{basePath{path: p, rel: p}} return testPath{basePath{path: p, rel: p}}
} }

View File

@ -110,17 +110,27 @@ var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
func TestValidateSafePath(t *testing.T) { func TestValidateSafePath(t *testing.T) {
for _, testCase := range validateSafePathTestCases { for _, testCase := range validateSafePathTestCases {
ctx := &configErrorWrapper{} t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
out := validateSafePath(ctx, testCase.in...) ctx := &configErrorWrapper{}
check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err) out, err := validateSafePath(testCase.in...)
if err != nil {
reportPathError(ctx, err)
}
check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
})
} }
} }
func TestValidatePath(t *testing.T) { func TestValidatePath(t *testing.T) {
for _, testCase := range validatePathTestCases { for _, testCase := range validatePathTestCases {
ctx := &configErrorWrapper{} t.Run(strings.Join(testCase.in, ","), func(t *testing.T) {
out := validatePath(ctx, testCase.in...) ctx := &configErrorWrapper{}
check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err) out, err := validatePath(testCase.in...)
if err != nil {
reportPathError(ctx, err)
}
check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
})
} }
} }
@ -133,6 +143,7 @@ func TestOptionalPath(t *testing.T) {
} }
func checkInvalidOptionalPath(t *testing.T, path OptionalPath) { func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
t.Helper()
if path.Valid() { if path.Valid() {
t.Errorf("Uninitialized OptionalPath should not be valid") t.Errorf("Uninitialized OptionalPath should not be valid")
} }
@ -150,9 +161,11 @@ func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
func check(t *testing.T, testType, testString string, func check(t *testing.T, testType, testString string,
got interface{}, err []error, got interface{}, err []error,
expected interface{}, expectedErr []error) { expected interface{}, expectedErr []error) {
t.Helper()
printedTestCase := false printedTestCase := false
e := func(s string, expected, got interface{}) { e := func(s string, expected, got interface{}) {
t.Helper()
if !printedTestCase { if !printedTestCase {
t.Errorf("test case %s: %s", testType, testString) t.Errorf("test case %s: %s", testType, testString)
printedTestCase = true printedTestCase = true

View File

@ -102,7 +102,7 @@ func (props *PgoProperties) addProfileGatherFlags(ctx ModuleContext, flags Flags
func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath { func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath {
// Test if the profile_file is present in any of the PGO profile projects // Test if the profile_file is present in any of the PGO profile projects
for _, profileProject := range getPgoProfileProjects(ctx.DeviceConfig()) { for _, profileProject := range getPgoProfileProjects(ctx.DeviceConfig()) {
path := android.ExistentPathForSource(ctx, "", profileProject, *props.Pgo.Profile_file) path := android.ExistentPathForSource(ctx, profileProject, *props.Pgo.Profile_file)
if path.Valid() { if path.Valid() {
return path return path
} }

View File

@ -374,10 +374,8 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
// templateDir (maybe missing) is relative to top of the source tree instead of current module. // templateDir (maybe missing) is relative to top of the source tree instead of current module.
templateDir := android.PathsForSource(ctx, []string{String(d.properties.Custom_template_dir)}) templateDir := android.PathForSource(ctx, String(d.properties.Custom_template_dir)).String()
if len(templateDir) > 0 { implicits = append(implicits, ctx.GlobFiles(filepath.Join(templateDir, "**/*"), nil)...)
implicits = append(implicits, ctx.GlobFiles(filepath.Join(templateDir[0].String(), "**/*"), nil)...)
}
var htmlDirArgs string var htmlDirArgs string
if len(d.properties.Html_dirs) > 0 { if len(d.properties.Html_dirs) > 0 {
@ -420,7 +418,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
opts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " + opts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
"-doclet com.google.doclava.Doclava -docletpath ${config.JsilverJar}:${config.DoclavaJar} " + "-doclet com.google.doclava.Doclava -docletpath ${config.JsilverJar}:${config.DoclavaJar} " +
"-templatedir " + String(d.properties.Custom_template_dir) + " " + htmlDirArgs + " " + htmlDir2Args + " " + "-templatedir " + templateDir + " " + htmlDirArgs + " " + htmlDir2Args + " " +
"-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " + "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
"-hdf page.now " + `"$$(date -d @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")"` + " " + "-hdf page.now " + `"$$(date -d @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")"` + " " +
args + " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String() args + " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String()

View File

@ -371,8 +371,8 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
jar = filepath.Join(dir, "core.jar") jar = filepath.Join(dir, "core.jar")
} }
aidl := filepath.Join(dir, "framework.aidl") aidl := filepath.Join(dir, "framework.aidl")
jarPath := android.ExistentPathForSource(ctx, "sdkdir", jar) jarPath := android.ExistentPathForSource(ctx, jar)
aidlPath := android.ExistentPathForSource(ctx, "sdkdir", aidl) aidlPath := android.ExistentPathForSource(ctx, aidl)
if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() { if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
return sdkDep{ return sdkDep{
@ -530,7 +530,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I")) flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I")) flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String()) flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
if src := android.ExistentPathForSource(ctx, "", ctx.ModuleDir(), "src"); src.Valid() { if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
flags = append(flags, "-I"+src.String()) flags = append(flags, "-I"+src.String())
} }