improve error handling for SourceRootDirs

Previously, warnings about missing modules were printed directly to
stderr. Instead we can pass these messages along as errors using the
existing pathways.

Bug: 269457150
Test: m nothing
Test: add -external to PRODUCT_SOURCE_ROOT_DIRS and observe missing
  module errors
Change-Id: Ib6624b9edbd103247f7f6e6d4c3030f1959aa56c
This commit is contained in:
Sam Delmerico 2023-03-30 14:19:39 -04:00
parent 82aa0ffb51
commit 48020c8daa
2 changed files with 30 additions and 22 deletions

View file

@ -1492,7 +1492,7 @@ func TestSourceRootDirs(t *testing.T) {
"foo_dir1",
},
expectedErrs: []string{
"Android.bp:2:2: \"foo\" depends on undefined module \"foo_dir1\"",
`Android.bp:2:2: module "foo" depends on skipped module "foo_dir1"; "foo_dir1" was defined in files(s) [dir1/Android.bp], but was skipped for reason(s) ["dir1/Android.bp" is a descendant of "dir1", and that path prefix was not included in PRODUCT_SOURCE_ROOT_DIRS]`,
},
},
{
@ -1506,7 +1506,7 @@ func TestSourceRootDirs(t *testing.T) {
"foo_dir_ignored_special_case",
},
expectedErrs: []string{
"dir1/Android.bp:2:2: \"foo_dir1\" depends on undefined module \"foo_dir_ignored\"",
`dir1/Android.bp:2:2: module "foo_dir1" depends on skipped module "foo_dir_ignored"; "foo_dir_ignored" was defined in files(s) [dir_ignored/Android.bp], but was skipped for reason(s) ["dir_ignored/Android.bp" is a descendant of "", and that path prefix was not included in PRODUCT_SOURCE_ROOT_DIRS]`,
},
},
{
@ -1520,7 +1520,7 @@ func TestSourceRootDirs(t *testing.T) {
"foo_dir_ignored",
},
expectedErrs: []string{
"dir1/Android.bp:2:2: \"foo_dir1\" depends on undefined module \"foo_dir_ignored\"",
"dir1/Android.bp:2:2: module \"foo_dir1\" depends on skipped module \"foo_dir_ignored\"; \"foo_dir_ignored\" was defined in files(s) [dir_ignored/Android.bp], but was skipped for reason(s) [\"dir_ignored/Android.bp\" is a descendant of \"\", and that path prefix was not included in PRODUCT_SOURCE_ROOT_DIRS]",
},
},
}
@ -1536,8 +1536,8 @@ func TestSourceRootDirs(t *testing.T) {
_, actualErrs := ctx.ResolveDependencies(nil)
stringErrs := []string(nil)
for i := range actualErrs {
stringErrs = append(stringErrs, fmt.Sprint(actualErrs[i]))
for _, err := range actualErrs {
stringErrs = append(stringErrs, err.Error())
}
if !reflect.DeepEqual(tc.expectedErrs, stringErrs) {
t.Errorf("expected to find errors %v; got %v", tc.expectedErrs, stringErrs)

View file

@ -16,7 +16,6 @@ package blueprint
import (
"fmt"
"os"
"sort"
"strings"
)
@ -62,6 +61,9 @@ type NameInterface interface {
// Finds the module with the given name
ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool)
// Finds if the module with the given name was skipped
SkippedModuleFromName(moduleName string, namespace Namespace) (skipInfos []SkippedModuleInfo, skipped bool)
// Returns an error indicating that the given module could not be found.
// The error contains some diagnostic information about where the dependency can be found.
MissingDependencyError(depender string, dependerNamespace Namespace, depName string) (err error)
@ -143,25 +145,14 @@ func (s *SimpleNameInterface) NewSkippedModule(ctx NamespaceContext, name string
func (s *SimpleNameInterface) ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool) {
group, found = s.modules[moduleName]
skipInfos, skipped := s.skippedModules[moduleName]
if skipped {
filesFound := make([]string, 0, len(skipInfos))
reasons := make([]string, 0, len(skipInfos))
for _, info := range skipInfos {
filesFound = append(filesFound, info.filename)
reasons = append(reasons, info.reason)
}
fmt.Fprintf(
os.Stderr,
"module %q was defined in files(s) [%v], but was skipped for reason(s) [%v]\n",
moduleName,
strings.Join(filesFound, ", "),
strings.Join(reasons, "; "),
)
}
return group, found
}
func (s *SimpleNameInterface) SkippedModuleFromName(moduleName string, namespace Namespace) (skipInfos []SkippedModuleInfo, skipped bool) {
skipInfos, skipped = s.skippedModules[moduleName]
return
}
func (s *SimpleNameInterface) Rename(oldName string, newName string, namespace Namespace) (errs []error) {
existingGroup, exists := s.modules[newName]
if exists {
@ -207,6 +198,23 @@ func (s *SimpleNameInterface) AllModules() []ModuleGroup {
}
func (s *SimpleNameInterface) MissingDependencyError(depender string, dependerNamespace Namespace, dependency string) (err error) {
skipInfos, skipped := s.SkippedModuleFromName(dependency, dependerNamespace)
if skipped {
filesFound := make([]string, 0, len(skipInfos))
reasons := make([]string, 0, len(skipInfos))
for _, info := range skipInfos {
filesFound = append(filesFound, info.filename)
reasons = append(reasons, info.reason)
}
return fmt.Errorf(
"module %q depends on skipped module %q; %q was defined in files(s) [%v], but was skipped for reason(s) [%v]",
depender,
dependency,
dependency,
strings.Join(filesFound, ", "),
strings.Join(reasons, "; "),
)
}
return fmt.Errorf("%q depends on undefined module %q", depender, dependency)
}