Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 301deecd authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Add Path.RelativeToTop"

parents 4c0b11a1 85d8f0dc
Loading
Loading
Loading
Loading
+134 −1
Original line number Original line Diff line number Diff line
@@ -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 {
@@ -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 {
+6 −21
Original line number Original line Diff line number Diff line
@@ -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) {