Merge "bp2build: Refactor metrics collection to use exported functions."

This commit is contained in:
Jingwen Chen
2021-09-22 14:16:12 +00:00
committed by Gerrit Code Review
2 changed files with 71 additions and 21 deletions

View File

@@ -261,7 +261,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
// Simple metrics tracking for bp2build // Simple metrics tracking for bp2build
metrics := CodegenMetrics{ metrics := CodegenMetrics{
RuleClassCount: make(map[string]int), ruleClassCount: make(map[string]int),
} }
dirs := make(map[string]bool) dirs := make(map[string]bool)
@@ -277,14 +277,28 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
switch ctx.Mode() { switch ctx.Mode() {
case Bp2Build: case Bp2Build:
// There are two main ways of converting a Soong module to Bazel:
// 1) Manually handcrafting a Bazel target and associating the module with its label
// 2) Automatically generating with bp2build converters
//
// bp2build converters are used for the majority of modules.
if b, ok := m.(android.Bazelable); ok && b.HasHandcraftedLabel() { if b, ok := m.(android.Bazelable); ok && b.HasHandcraftedLabel() {
metrics.handCraftedTargetCount += 1 // Handle modules converted to handcrafted targets.
metrics.TotalModuleCount += 1 //
metrics.AddConvertedModule(m.Name()) // Since these modules are associated with some handcrafted
// target in a BUILD file, we simply append the entire contents
// of that BUILD file to the generated BUILD file.
//
// The append operation is only done once, even if there are
// multiple modules from the same directory associated to
// targets in the same BUILD file (or package).
// Log the module.
metrics.AddConvertedModule(m.Name(), Handcrafted)
pathToBuildFile := getBazelPackagePath(b) pathToBuildFile := getBazelPackagePath(b)
// We are using the entire contents of handcrafted build file, so if multiple targets within
// a package have handcrafted targets, we only want to include the contents one time.
if _, exists := buildFileToAppend[pathToBuildFile]; exists { if _, exists := buildFileToAppend[pathToBuildFile]; exists {
// Append the BUILD file content once per package, at most.
return return
} }
t, err := getHandcraftedBuildContent(ctx, b, pathToBuildFile) t, err := getHandcraftedBuildContent(ctx, b, pathToBuildFile)
@@ -297,23 +311,29 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
// something more targeted based on the rule type and target // something more targeted based on the rule type and target
buildFileToAppend[pathToBuildFile] = true buildFileToAppend[pathToBuildFile] = true
} else if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() { } else if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
// Handle modules converted to generated targets.
// Log the module.
metrics.AddConvertedModule(m.Name(), Generated)
// Handle modules with unconverted deps. By default, emit a warning.
if unconvertedDeps := aModule.GetUnconvertedBp2buildDeps(); len(unconvertedDeps) > 0 { if unconvertedDeps := aModule.GetUnconvertedBp2buildDeps(); len(unconvertedDeps) > 0 {
msg := fmt.Sprintf("%q depends on unconverted modules: %s", m.Name(), strings.Join(unconvertedDeps, ", ")) msg := fmt.Sprintf("%q depends on unconverted modules: %s", m.Name(), strings.Join(unconvertedDeps, ", "))
if ctx.unconvertedDepMode == warnUnconvertedDeps { if ctx.unconvertedDepMode == warnUnconvertedDeps {
metrics.moduleWithUnconvertedDepsMsgs = append(metrics.moduleWithUnconvertedDepsMsgs, msg) metrics.moduleWithUnconvertedDepsMsgs = append(metrics.moduleWithUnconvertedDepsMsgs, msg)
} else if ctx.unconvertedDepMode == errorModulesUnconvertedDeps { } else if ctx.unconvertedDepMode == errorModulesUnconvertedDeps {
metrics.TotalModuleCount += 1
errs = append(errs, fmt.Errorf(msg)) errs = append(errs, fmt.Errorf(msg))
return return
} }
} }
targets = generateBazelTargets(bpCtx, aModule) targets = generateBazelTargets(bpCtx, aModule)
metrics.AddConvertedModule(m.Name())
for _, t := range targets { for _, t := range targets {
metrics.RuleClassCount[t.ruleClass] += 1 // A module can potentially generate more than 1 Bazel
// target, each of a different rule class.
metrics.IncrementRuleClassCount(t.ruleClass)
} }
} else { } else {
metrics.TotalModuleCount += 1 metrics.IncrementUnconvertedCount()
return return
} }
case QueryView: case QueryView:

View File

@@ -9,14 +9,17 @@ import (
// Simple metrics struct to collect information about a Blueprint to BUILD // Simple metrics struct to collect information about a Blueprint to BUILD
// conversion process. // conversion process.
type CodegenMetrics struct { type CodegenMetrics struct {
// Total number of Soong/Blueprint modules // Total number of Soong modules converted to generated targets
TotalModuleCount int generatedModuleCount int
// Total number of Soong modules converted to handcrafted targets
handCraftedModuleCount int
// Total number of unconverted Soong modules
unconvertedModuleCount int
// Counts of generated Bazel targets per Bazel rule class // Counts of generated Bazel targets per Bazel rule class
RuleClassCount map[string]int ruleClassCount map[string]int
// Total number of handcrafted targets
handCraftedTargetCount int
moduleWithUnconvertedDepsMsgs []string moduleWithUnconvertedDepsMsgs []string
@@ -26,22 +29,49 @@ type CodegenMetrics struct {
// Print the codegen metrics to stdout. // Print the codegen metrics to stdout.
func (metrics *CodegenMetrics) Print() { func (metrics *CodegenMetrics) Print() {
generatedTargetCount := 0 generatedTargetCount := 0
for _, ruleClass := range android.SortedStringKeys(metrics.RuleClassCount) { for _, ruleClass := range android.SortedStringKeys(metrics.ruleClassCount) {
count := metrics.RuleClassCount[ruleClass] count := metrics.ruleClassCount[ruleClass]
fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count) fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count)
generatedTargetCount += count generatedTargetCount += count
} }
fmt.Printf( fmt.Printf(
"[bp2build] Generated %d total BUILD targets and included %d handcrafted BUILD targets from %d Android.bp modules.\n With %d modules with unconverted deps \n\t%s", "[bp2build] Generated %d total BUILD targets and included %d handcrafted BUILD targets from %d Android.bp modules.\n With %d modules with unconverted deps \n\t%s",
generatedTargetCount, generatedTargetCount,
metrics.handCraftedTargetCount, metrics.handCraftedModuleCount,
metrics.TotalModuleCount, metrics.TotalModuleCount(),
len(metrics.moduleWithUnconvertedDepsMsgs), len(metrics.moduleWithUnconvertedDepsMsgs),
strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t")) strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"))
} }
func (metrics *CodegenMetrics) AddConvertedModule(moduleName string) { func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) {
metrics.ruleClassCount[ruleClass] += 1
}
func (metrics *CodegenMetrics) IncrementUnconvertedCount() {
metrics.unconvertedModuleCount += 1
}
func (metrics *CodegenMetrics) TotalModuleCount() int {
return metrics.handCraftedModuleCount +
metrics.generatedModuleCount +
metrics.unconvertedModuleCount
}
type ConversionType int
const (
Generated ConversionType = iota
Handcrafted
)
func (metrics *CodegenMetrics) AddConvertedModule(moduleName string, conversionType ConversionType) {
// Undo prebuilt_ module name prefix modifications // Undo prebuilt_ module name prefix modifications
moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName) moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
metrics.convertedModules = append(metrics.convertedModules, moduleName) metrics.convertedModules = append(metrics.convertedModules, moduleName)
if conversionType == Handcrafted {
metrics.handCraftedModuleCount += 1
} else if conversionType == Generated {
metrics.generatedModuleCount += 1
}
} }