Loading android/paths.go +134 −1 Original line number Original line Diff line number Diff line Loading @@ -174,7 +174,34 @@ type Path interface { // example, Rel on a PathsForModuleSrc would return the path relative to the module source // example, Rel on a PathsForModuleSrc would return the path relative to the module source // directory, and OutputPath.Join("foo").Rel() would return "foo". // directory, and OutputPath.Join("foo").Rel() would return "foo". Rel() string Rel() string } // RelativeToTop returns a new path relative to the top, it is provided solely for use in tests. // // It is guaranteed to always return the same type as it is called on, e.g. if called on an // InstallPath then the returned value can be converted to an InstallPath. // // A standard build has the following structure: // ../top/ // out/ - make install files go here. // out/soong - this is the buildDir passed to NewTestConfig() // ... - the source files // // This function converts a path so that it appears relative to the ../top/ directory, i.e. // * Make install paths, which have the pattern "buildDir/../<path>" are converted into the top // relative path "out/<path>" // * Soong install paths and other writable paths, which have the pattern "buildDir/<path>" are // converted into the top relative path "out/soong/<path>". // * Source paths are already relative to the top. // * Phony paths are not relative to anything. // * toolDepPath have an absolute but known value in so don't need making relative to anything in // order to test. RelativeToTop() Path } const ( OutDir = "out" OutSoongDir = OutDir + "/soong" ) // WritablePath is a type of path that can be used as an output for build rules. // WritablePath is a type of path that can be used as an output for build rules. type WritablePath interface { type WritablePath interface { Loading Loading @@ -271,6 +298,20 @@ func (p OptionalPath) String() string { // Paths is a slice of Path objects, with helpers to operate on the collection. // Paths is a slice of Path objects, with helpers to operate on the collection. type Paths []Path type Paths []Path // RelativeToTop creates a new Paths containing the result of calling Path.RelativeToTop on each // item in this slice. func (p Paths) RelativeToTop() Paths { ensureTestOnly() if p == nil { return p } ret := make(Paths, len(p)) for i, path := range p { ret[i] = path.RelativeToTop() } return ret } func (paths Paths) containsPath(path Path) bool { func (paths Paths) containsPath(path Path) bool { for _, p := range paths { for _, p := range paths { if p == path { if p == path { Loading Loading @@ -910,6 +951,20 @@ func (p DirectorySortedPaths) PathsInDirectory(dir string) Paths { // WritablePaths is a slice of WritablePath, used for multiple outputs. // WritablePaths is a slice of WritablePath, used for multiple outputs. type WritablePaths []WritablePath type WritablePaths []WritablePath // RelativeToTop creates a new WritablePaths containing the result of calling Path.RelativeToTop on // each item in this slice. func (p WritablePaths) RelativeToTop() WritablePaths { ensureTestOnly() if p == nil { return p } ret := make(WritablePaths, len(p)) for i, path := range p { ret[i] = path.RelativeToTop().(WritablePath) } return ret } // Strings returns the string forms of the writable paths. // Strings returns the string forms of the writable paths. func (p WritablePaths) Strings() []string { func (p WritablePaths) Strings() []string { if p == nil { if p == nil { Loading Loading @@ -972,6 +1027,11 @@ type SourcePath struct { srcDir string srcDir string } } func (p SourcePath) RelativeToTop() Path { ensureTestOnly() return p } var _ Path = SourcePath{} var _ Path = SourcePath{} func (p SourcePath) withRel(rel string) SourcePath { func (p SourcePath) withRel(rel string) SourcePath { Loading Loading @@ -1167,6 +1227,16 @@ func (p OutputPath) getBuildDir() string { return p.buildDir return p.buildDir } } func (p OutputPath) RelativeToTop() Path { return p.outputPathRelativeToTop() } func (p OutputPath) outputPathRelativeToTop() OutputPath { p.fullPath = StringPathRelativeToTop(p.buildDir, p.fullPath) p.buildDir = OutSoongDir return p } func (p OutputPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { func (p OutputPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) } } Loading @@ -1180,6 +1250,11 @@ type toolDepPath struct { basePath basePath } } func (t toolDepPath) RelativeToTop() Path { ensureTestOnly() return t } var _ Path = toolDepPath{} var _ Path = toolDepPath{} // pathForBuildToolDep returns a toolDepPath representing the given path string. // pathForBuildToolDep returns a toolDepPath representing the given path string. Loading Loading @@ -1357,7 +1432,13 @@ type ModuleOutPath struct { OutputPath OutputPath } } func (p ModuleOutPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleOutPath{} var _ Path = ModuleOutPath{} var _ WritablePath = ModuleOutPath{} func (p ModuleOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { func (p ModuleOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) Loading Loading @@ -1462,7 +1543,13 @@ type ModuleGenPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleGenPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleGenPath{} var _ Path = ModuleGenPath{} var _ WritablePath = ModuleGenPath{} var _ genPathProvider = ModuleGenPath{} var _ genPathProvider = ModuleGenPath{} var _ objPathProvider = ModuleGenPath{} var _ objPathProvider = ModuleGenPath{} Loading Loading @@ -1495,7 +1582,13 @@ type ModuleObjPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleObjPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleObjPath{} var _ Path = ModuleObjPath{} var _ WritablePath = 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. Loading @@ -1513,7 +1606,13 @@ type ModuleResPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleResPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleResPath{} var _ Path = ModuleResPath{} var _ WritablePath = 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. Loading Loading @@ -1541,6 +1640,26 @@ type InstallPath struct { makePath bool makePath bool } } // Will panic if called from outside a test environment. func ensureTestOnly() { // Normal soong test environment if InList("-test.short", os.Args) { return } // IntelliJ test environment if InList("-test.v", os.Args) { return } panic(fmt.Errorf("Not in test\n%s", strings.Join(os.Args, "\n"))) } func (p InstallPath) RelativeToTop() Path { ensureTestOnly() p.buildDir = OutSoongDir return p } func (p InstallPath) getBuildDir() string { func (p InstallPath) getBuildDir() string { return p.buildDir return p.buildDir } } Loading Loading @@ -1814,6 +1933,13 @@ func (p PhonyPath) getBuildDir() string { return "" return "" } } func (p PhonyPath) RelativeToTop() Path { ensureTestOnly() // A phony path cannot contain any / so does not have a build directory so switching to a new // build directory has no effect so just return this path. return p } func (p PhonyPath) ReplaceExtension(ctx PathContext, ext string) OutputPath { func (p PhonyPath) ReplaceExtension(ctx PathContext, ext string) OutputPath { panic("Not implemented") panic("Not implemented") } } Loading @@ -1825,10 +1951,17 @@ type testPath struct { basePath basePath } } func (p testPath) RelativeToTop() Path { ensureTestOnly() return p } func (p testPath) String() string { func (p testPath) String() string { return p.path return p.path } } var _ Path = testPath{} // PathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be used from // PathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be used from // within tests. // within tests. func PathForTesting(paths ...string) Path { func PathForTesting(paths ...string) Path { Loading android/testing.go +6 −21 Original line number Original line Diff line number Diff line Loading @@ -935,19 +935,14 @@ func NormalizePathsForTesting(paths Paths) []string { // PathRelativeToTop returns a string representation of the path relative to a notional top // PathRelativeToTop returns a string representation of the path relative to a notional top // directory. // directory. // // // For a WritablePath it applies StringPathRelativeToTop to it, using the buildDir returned from the // It return "<nil path>" if the supplied path is nil, otherwise it returns the result of calling // WritablePath's buildDir() method. For all other paths, i.e. source paths, that are already // Path.RelativeToTop to obtain a relative Path and then calling Path.String on that to get the // relative to the top it just returns their string representation. // string representation. func PathRelativeToTop(path Path) string { func PathRelativeToTop(path Path) string { if path == nil { if path == nil { return "<nil path>" return "<nil path>" } } p := path.String() return path.RelativeToTop().String() if w, ok := path.(WritablePath); ok { buildDir := w.getBuildDir() return StringPathRelativeToTop(buildDir, p) } return p } } // PathsRelativeToTop creates a slice of strings where each string is the result of applying // PathsRelativeToTop creates a slice of strings where each string is the result of applying Loading @@ -964,23 +959,13 @@ func PathsRelativeToTop(paths Paths) []string { // StringPathRelativeToTop returns a string representation of the path relative to a notional top // StringPathRelativeToTop returns a string representation of the path relative to a notional top // directory. // directory. // // // A standard build has the following structure: // See Path.RelativeToTop for more details as to what `relative to top` means. // ../top/ // out/ - make install files go here. // out/soong - this is the buildDir passed to NewTestConfig() // ... - the source files // // This function converts a path so that it appears relative to the ../top/ directory, i.e. // * Make install paths, which have the pattern "buildDir/../<path>" are converted into the top // relative path "out/<path>" // * Soong install paths and other writable paths, which have the pattern "buildDir/<path>" are // converted into the top relative path "out/soong/<path>". // * Source paths are already relative to the top. // // // This is provided for processing paths that have already been converted into a string, e.g. paths // This is provided for processing paths that have already been converted into a string, e.g. paths // in AndroidMkEntries structures. As a result it needs to be supplied the soong output dir against // in AndroidMkEntries structures. As a result it needs to be supplied the soong output dir against // which it can try and relativize paths. PathRelativeToTop must be used for process Path objects. // which it can try and relativize paths. PathRelativeToTop must be used for process Path objects. func StringPathRelativeToTop(soongOutDir string, path string) string { func StringPathRelativeToTop(soongOutDir string, path string) string { ensureTestOnly() // A relative path must be a source path so leave it as it is. // A relative path must be a source path so leave it as it is. if !filepath.IsAbs(path) { if !filepath.IsAbs(path) { Loading Loading
android/paths.go +134 −1 Original line number Original line Diff line number Diff line Loading @@ -174,7 +174,34 @@ type Path interface { // example, Rel on a PathsForModuleSrc would return the path relative to the module source // example, Rel on a PathsForModuleSrc would return the path relative to the module source // directory, and OutputPath.Join("foo").Rel() would return "foo". // directory, and OutputPath.Join("foo").Rel() would return "foo". Rel() string Rel() string } // RelativeToTop returns a new path relative to the top, it is provided solely for use in tests. // // It is guaranteed to always return the same type as it is called on, e.g. if called on an // InstallPath then the returned value can be converted to an InstallPath. // // A standard build has the following structure: // ../top/ // out/ - make install files go here. // out/soong - this is the buildDir passed to NewTestConfig() // ... - the source files // // This function converts a path so that it appears relative to the ../top/ directory, i.e. // * Make install paths, which have the pattern "buildDir/../<path>" are converted into the top // relative path "out/<path>" // * Soong install paths and other writable paths, which have the pattern "buildDir/<path>" are // converted into the top relative path "out/soong/<path>". // * Source paths are already relative to the top. // * Phony paths are not relative to anything. // * toolDepPath have an absolute but known value in so don't need making relative to anything in // order to test. RelativeToTop() Path } const ( OutDir = "out" OutSoongDir = OutDir + "/soong" ) // WritablePath is a type of path that can be used as an output for build rules. // WritablePath is a type of path that can be used as an output for build rules. type WritablePath interface { type WritablePath interface { Loading Loading @@ -271,6 +298,20 @@ func (p OptionalPath) String() string { // Paths is a slice of Path objects, with helpers to operate on the collection. // Paths is a slice of Path objects, with helpers to operate on the collection. type Paths []Path type Paths []Path // RelativeToTop creates a new Paths containing the result of calling Path.RelativeToTop on each // item in this slice. func (p Paths) RelativeToTop() Paths { ensureTestOnly() if p == nil { return p } ret := make(Paths, len(p)) for i, path := range p { ret[i] = path.RelativeToTop() } return ret } func (paths Paths) containsPath(path Path) bool { func (paths Paths) containsPath(path Path) bool { for _, p := range paths { for _, p := range paths { if p == path { if p == path { Loading Loading @@ -910,6 +951,20 @@ func (p DirectorySortedPaths) PathsInDirectory(dir string) Paths { // WritablePaths is a slice of WritablePath, used for multiple outputs. // WritablePaths is a slice of WritablePath, used for multiple outputs. type WritablePaths []WritablePath type WritablePaths []WritablePath // RelativeToTop creates a new WritablePaths containing the result of calling Path.RelativeToTop on // each item in this slice. func (p WritablePaths) RelativeToTop() WritablePaths { ensureTestOnly() if p == nil { return p } ret := make(WritablePaths, len(p)) for i, path := range p { ret[i] = path.RelativeToTop().(WritablePath) } return ret } // Strings returns the string forms of the writable paths. // Strings returns the string forms of the writable paths. func (p WritablePaths) Strings() []string { func (p WritablePaths) Strings() []string { if p == nil { if p == nil { Loading Loading @@ -972,6 +1027,11 @@ type SourcePath struct { srcDir string srcDir string } } func (p SourcePath) RelativeToTop() Path { ensureTestOnly() return p } var _ Path = SourcePath{} var _ Path = SourcePath{} func (p SourcePath) withRel(rel string) SourcePath { func (p SourcePath) withRel(rel string) SourcePath { Loading Loading @@ -1167,6 +1227,16 @@ func (p OutputPath) getBuildDir() string { return p.buildDir return p.buildDir } } func (p OutputPath) RelativeToTop() Path { return p.outputPathRelativeToTop() } func (p OutputPath) outputPathRelativeToTop() OutputPath { p.fullPath = StringPathRelativeToTop(p.buildDir, p.fullPath) p.buildDir = OutSoongDir return p } func (p OutputPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { func (p OutputPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) } } Loading @@ -1180,6 +1250,11 @@ type toolDepPath struct { basePath basePath } } func (t toolDepPath) RelativeToTop() Path { ensureTestOnly() return t } var _ Path = toolDepPath{} var _ Path = toolDepPath{} // pathForBuildToolDep returns a toolDepPath representing the given path string. // pathForBuildToolDep returns a toolDepPath representing the given path string. Loading Loading @@ -1357,7 +1432,13 @@ type ModuleOutPath struct { OutputPath OutputPath } } func (p ModuleOutPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleOutPath{} var _ Path = ModuleOutPath{} var _ WritablePath = ModuleOutPath{} func (p ModuleOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { func (p ModuleOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath { return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext)) Loading Loading @@ -1462,7 +1543,13 @@ type ModuleGenPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleGenPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleGenPath{} var _ Path = ModuleGenPath{} var _ WritablePath = ModuleGenPath{} var _ genPathProvider = ModuleGenPath{} var _ genPathProvider = ModuleGenPath{} var _ objPathProvider = ModuleGenPath{} var _ objPathProvider = ModuleGenPath{} Loading Loading @@ -1495,7 +1582,13 @@ type ModuleObjPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleObjPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleObjPath{} var _ Path = ModuleObjPath{} var _ WritablePath = 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. Loading @@ -1513,7 +1606,13 @@ type ModuleResPath struct { ModuleOutPath ModuleOutPath } } func (p ModuleResPath) RelativeToTop() Path { p.OutputPath = p.outputPathRelativeToTop() return p } var _ Path = ModuleResPath{} var _ Path = ModuleResPath{} var _ WritablePath = 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. Loading Loading @@ -1541,6 +1640,26 @@ type InstallPath struct { makePath bool makePath bool } } // Will panic if called from outside a test environment. func ensureTestOnly() { // Normal soong test environment if InList("-test.short", os.Args) { return } // IntelliJ test environment if InList("-test.v", os.Args) { return } panic(fmt.Errorf("Not in test\n%s", strings.Join(os.Args, "\n"))) } func (p InstallPath) RelativeToTop() Path { ensureTestOnly() p.buildDir = OutSoongDir return p } func (p InstallPath) getBuildDir() string { func (p InstallPath) getBuildDir() string { return p.buildDir return p.buildDir } } Loading Loading @@ -1814,6 +1933,13 @@ func (p PhonyPath) getBuildDir() string { return "" return "" } } func (p PhonyPath) RelativeToTop() Path { ensureTestOnly() // A phony path cannot contain any / so does not have a build directory so switching to a new // build directory has no effect so just return this path. return p } func (p PhonyPath) ReplaceExtension(ctx PathContext, ext string) OutputPath { func (p PhonyPath) ReplaceExtension(ctx PathContext, ext string) OutputPath { panic("Not implemented") panic("Not implemented") } } Loading @@ -1825,10 +1951,17 @@ type testPath struct { basePath basePath } } func (p testPath) RelativeToTop() Path { ensureTestOnly() return p } func (p testPath) String() string { func (p testPath) String() string { return p.path return p.path } } var _ Path = testPath{} // PathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be used from // PathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be used from // within tests. // within tests. func PathForTesting(paths ...string) Path { func PathForTesting(paths ...string) Path { Loading
android/testing.go +6 −21 Original line number Original line Diff line number Diff line Loading @@ -935,19 +935,14 @@ func NormalizePathsForTesting(paths Paths) []string { // PathRelativeToTop returns a string representation of the path relative to a notional top // PathRelativeToTop returns a string representation of the path relative to a notional top // directory. // directory. // // // For a WritablePath it applies StringPathRelativeToTop to it, using the buildDir returned from the // It return "<nil path>" if the supplied path is nil, otherwise it returns the result of calling // WritablePath's buildDir() method. For all other paths, i.e. source paths, that are already // Path.RelativeToTop to obtain a relative Path and then calling Path.String on that to get the // relative to the top it just returns their string representation. // string representation. func PathRelativeToTop(path Path) string { func PathRelativeToTop(path Path) string { if path == nil { if path == nil { return "<nil path>" return "<nil path>" } } p := path.String() return path.RelativeToTop().String() if w, ok := path.(WritablePath); ok { buildDir := w.getBuildDir() return StringPathRelativeToTop(buildDir, p) } return p } } // PathsRelativeToTop creates a slice of strings where each string is the result of applying // PathsRelativeToTop creates a slice of strings where each string is the result of applying Loading @@ -964,23 +959,13 @@ func PathsRelativeToTop(paths Paths) []string { // StringPathRelativeToTop returns a string representation of the path relative to a notional top // StringPathRelativeToTop returns a string representation of the path relative to a notional top // directory. // directory. // // // A standard build has the following structure: // See Path.RelativeToTop for more details as to what `relative to top` means. // ../top/ // out/ - make install files go here. // out/soong - this is the buildDir passed to NewTestConfig() // ... - the source files // // This function converts a path so that it appears relative to the ../top/ directory, i.e. // * Make install paths, which have the pattern "buildDir/../<path>" are converted into the top // relative path "out/<path>" // * Soong install paths and other writable paths, which have the pattern "buildDir/<path>" are // converted into the top relative path "out/soong/<path>". // * Source paths are already relative to the top. // // // This is provided for processing paths that have already been converted into a string, e.g. paths // This is provided for processing paths that have already been converted into a string, e.g. paths // in AndroidMkEntries structures. As a result it needs to be supplied the soong output dir against // in AndroidMkEntries structures. As a result it needs to be supplied the soong output dir against // which it can try and relativize paths. PathRelativeToTop must be used for process Path objects. // which it can try and relativize paths. PathRelativeToTop must be used for process Path objects. func StringPathRelativeToTop(soongOutDir string, path string) string { func StringPathRelativeToTop(soongOutDir string, path string) string { ensureTestOnly() // A relative path must be a source path so leave it as it is. // A relative path must be a source path so leave it as it is. if !filepath.IsAbs(path) { if !filepath.IsAbs(path) { Loading