Merge "Add Path.RelativeToTop" am: 301deecd6c
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1652616 Change-Id: I194fc8c451e39d06bab40db3f0c12f1b1170776b
This commit is contained in:
133
android/paths.go
133
android/paths.go
@@ -174,8 +174,35 @@ 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 {
|
||||||
Path
|
Path
|
||||||
@@ -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 {
|
||||||
@@ -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 {
|
||||||
@@ -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 {
|
||||||
@@ -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))
|
||||||
}
|
}
|
||||||
@@ -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.
|
||||||
@@ -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))
|
||||||
@@ -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{}
|
||||||
|
|
||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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")
|
||||||
}
|
}
|
||||||
@@ -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 {
|
||||||
|
@@ -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
|
||||||
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user