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

Commit 1c7e9629 authored by Jiyong Park's avatar Jiyong Park
Browse files

Add GetPathString

The method is a thin wrapper around GetWalkPath and GetTagPath to make
it easy to construct a string representation of the current path.

It was originally inlined in the apex package. This change makes it a
function and moves it to the android package so make it more useful.

Bug: N/A
Test: m
Change-Id: I7e2bc2074baed759d67d9097151c9ac10e34ed31
parent 00789cc5
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import (
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strings"
	"text/scanner"

@@ -135,6 +136,13 @@ type BaseModuleContext interface {
	// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
	GetTagPath() []blueprint.DependencyTag

	// GetPathString is supposed to be called in visit function passed in WalkDeps()
	// and returns a multi-line string showing the modules and dependency tags
	// among them along the top-down dependency path from a start module to current child module.
	// skipFirst when set to true, the output doesn't include the start module,
	// which is already printed when this function is used along with ModuleErrorf().
	GetPathString(skipFirst bool) string

	AddMissingDependencies(missingDeps []string)

	Target() Target
@@ -1734,6 +1742,41 @@ func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
	return b.tagPath
}

// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
// a dependency tag.
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`)

// PrettyPrintTag returns string representation of the tag, but prefers
// custom String() method if available.
func PrettyPrintTag(tag blueprint.DependencyTag) string {
	// Use tag's custom String() method if available.
	if stringer, ok := tag.(fmt.Stringer); ok {
		return stringer.String()
	}

	// Otherwise, get a default string representation of the tag's struct.
	tagString := fmt.Sprintf("%#v", tag)

	// Remove the boilerplate from BaseDependencyTag as it adds no value.
	tagString = tagCleaner.ReplaceAllString(tagString, "")
	return tagString
}

func (b *baseModuleContext) GetPathString(skipFirst bool) string {
	sb := strings.Builder{}
	tagPath := b.GetTagPath()
	walkPath := b.GetWalkPath()
	if !skipFirst {
		sb.WriteString(walkPath[0].String())
	}
	for i, m := range walkPath[1:] {
		sb.WriteString("\n")
		sb.WriteString(fmt.Sprintf("           via tag %s\n", PrettyPrintTag(tagPath[i])))
		sb.WriteString(fmt.Sprintf("    -> %s", m.String()))
	}
	return sb.String()
}

func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
	m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
		visit(module.(Module))
+2 −28
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ import (
	"fmt"
	"path"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"
@@ -1809,24 +1808,6 @@ func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int {
	return intVer
}

// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
// a dependency tag.
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`)

func PrettyPrintTag(tag blueprint.DependencyTag) string {
	// Use tag's custom String() method if available.
	if stringer, ok := tag.(fmt.Stringer); ok {
		return stringer.String()
	}

	// Otherwise, get a default string representation of the tag's struct.
	tagString := fmt.Sprintf("%#v", tag)

	// Remove the boilerplate from BaseDependencyTag as it adds no value.
	tagString = tagCleaner.ReplaceAllString(tagString, "")
	return tagString
}

// Ensures that the dependencies are marked as available for this APEX
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
	// Let's be practical. Availability for test, host, and the VNDK apex isn't important
@@ -1861,14 +1842,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
		if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
			return true
		}
		message := ""
		tagPath := ctx.GetTagPath()
		// Skip the first module as that will be added at the start of the error message by ctx.ModuleErrorf().
		walkPath := ctx.GetWalkPath()[1:]
		for i, m := range walkPath {
			message = fmt.Sprintf("%s\n           via tag %s\n    -> %s", message, PrettyPrintTag(tagPath[i]), m.String())
		}
		ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
		ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, ctx.GetPathString(true))
		// Visit this module's dependencies to check and report any issues with their availability.
		return true
	})
@@ -2132,7 +2106,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
						filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
					}
				} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
					ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", PrettyPrintTag(depTag), depName)
					ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
				}
			}
		}