Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 1 | package bp2build |
| 2 | |
| 3 | import ( |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 4 | "fmt" |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 5 | "os" |
| 6 | "path/filepath" |
Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 7 | "strings" |
Chris Parsons | 91b81f0 | 2021-12-08 11:19:06 -0500 | [diff] [blame] | 8 | |
| 9 | "android/soong/android" |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 10 | "android/soong/shared" |
| 11 | "android/soong/ui/metrics/bp2build_metrics_proto" |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 12 | "github.com/google/blueprint" |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 13 | ) |
| 14 | |
| 15 | // Simple metrics struct to collect information about a Blueprint to BUILD |
| 16 | // conversion process. |
| 17 | type CodegenMetrics struct { |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 18 | // Total number of Soong modules converted to generated targets |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 19 | generatedModuleCount uint64 |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 20 | |
| 21 | // Total number of Soong modules converted to handcrafted targets |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 22 | handCraftedModuleCount uint64 |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 23 | |
| 24 | // Total number of unconverted Soong modules |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 25 | unconvertedModuleCount uint64 |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 26 | |
| 27 | // Counts of generated Bazel targets per Bazel rule class |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 28 | ruleClassCount map[string]uint64 |
Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 29 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 30 | // List of modules with unconverted deps |
| 31 | // NOTE: NOT in the .proto |
Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 32 | moduleWithUnconvertedDepsMsgs []string |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 33 | |
Liz Kammer | daa09ef | 2021-12-15 15:35:38 -0500 | [diff] [blame] | 34 | // List of modules with missing deps |
| 35 | // NOTE: NOT in the .proto |
| 36 | moduleWithMissingDepsMsgs []string |
| 37 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 38 | // List of converted modules |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 39 | convertedModules []string |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 40 | |
| 41 | // Counts of converted modules by module type. |
| 42 | convertedModuleTypeCount map[string]uint64 |
| 43 | |
| 44 | // Counts of total modules by module type. |
| 45 | totalModuleTypeCount map[string]uint64 |
Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 46 | |
| 47 | Events []*bp2build_metrics_proto.Event |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 48 | } |
| 49 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 50 | // Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics |
| 51 | func (metrics *CodegenMetrics) Serialize() bp2build_metrics_proto.Bp2BuildMetrics { |
| 52 | return bp2build_metrics_proto.Bp2BuildMetrics{ |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 53 | GeneratedModuleCount: metrics.generatedModuleCount, |
| 54 | HandCraftedModuleCount: metrics.handCraftedModuleCount, |
| 55 | UnconvertedModuleCount: metrics.unconvertedModuleCount, |
| 56 | RuleClassCount: metrics.ruleClassCount, |
| 57 | ConvertedModules: metrics.convertedModules, |
| 58 | ConvertedModuleTypeCount: metrics.convertedModuleTypeCount, |
| 59 | TotalModuleTypeCount: metrics.totalModuleTypeCount, |
Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 60 | Events: metrics.Events, |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 61 | } |
| 62 | } |
| 63 | |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 64 | // Print the codegen metrics to stdout. |
Jingwen Chen | afb84bd | 2021-09-20 10:31:46 +0000 | [diff] [blame] | 65 | func (metrics *CodegenMetrics) Print() { |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 66 | generatedTargetCount := uint64(0) |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 67 | for _, ruleClass := range android.SortedStringKeys(metrics.ruleClassCount) { |
| 68 | count := metrics.ruleClassCount[ruleClass] |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 69 | fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count) |
| 70 | generatedTargetCount += count |
| 71 | } |
| 72 | fmt.Printf( |
Liz Kammer | daa09ef | 2021-12-15 15:35:38 -0500 | [diff] [blame] | 73 | `[bp2build] Converted %d Android.bp modules to %d total generated BUILD targets. Included %d handcrafted BUILD targets. There are %d total Android.bp modules. |
| 74 | %d converted modules have unconverted deps: |
| 75 | %s |
| 76 | %d converted modules have missing deps: |
| 77 | %s |
| 78 | `, |
Chris Parsons | 91b81f0 | 2021-12-08 11:19:06 -0500 | [diff] [blame] | 79 | metrics.generatedModuleCount, |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 80 | generatedTargetCount, |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 81 | metrics.handCraftedModuleCount, |
| 82 | metrics.TotalModuleCount(), |
Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 83 | len(metrics.moduleWithUnconvertedDepsMsgs), |
Liz Kammer | daa09ef | 2021-12-15 15:35:38 -0500 | [diff] [blame] | 84 | strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"), |
| 85 | len(metrics.moduleWithMissingDepsMsgs), |
| 86 | strings.Join(metrics.moduleWithMissingDepsMsgs, "\n\t"), |
| 87 | ) |
Jingwen Chen | 164e086 | 2021-02-19 00:48:40 -0500 | [diff] [blame] | 88 | } |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 89 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 90 | const bp2buildMetricsFilename = "bp2build_metrics.pb" |
| 91 | |
| 92 | // fail prints $PWD to stderr, followed by the given printf string and args (vals), |
| 93 | // then the given alert, and then exits with 1 for failure |
| 94 | func fail(err error, alertFmt string, vals ...interface{}) { |
| 95 | cwd, wderr := os.Getwd() |
| 96 | if wderr != nil { |
| 97 | cwd = "FAILED TO GET $PWD: " + wderr.Error() |
| 98 | } |
| 99 | fmt.Fprintf(os.Stderr, "\nIn "+cwd+":\n"+alertFmt+"\n"+err.Error()+"\n", vals...) |
| 100 | os.Exit(1) |
| 101 | } |
| 102 | |
| 103 | // Write the bp2build-protoized codegen metrics into the given directory |
| 104 | func (metrics *CodegenMetrics) Write(dir string) { |
| 105 | if _, err := os.Stat(dir); os.IsNotExist(err) { |
| 106 | // The metrics dir doesn't already exist, so create it (and parents) |
| 107 | if err := os.MkdirAll(dir, 0755); err != nil { // rx for all; w for user |
| 108 | fail(err, "Failed to `mkdir -p` %s", dir) |
| 109 | } |
| 110 | } else if err != nil { |
| 111 | fail(err, "Failed to `stat` %s", dir) |
| 112 | } |
| 113 | metricsFile := filepath.Join(dir, bp2buildMetricsFilename) |
| 114 | if err := metrics.dump(metricsFile); err != nil { |
| 115 | fail(err, "Error outputting %s", metricsFile) |
| 116 | } |
| 117 | if _, err := os.Stat(metricsFile); err != nil { |
| 118 | fail(err, "MISSING BP2BUILD METRICS OUTPUT: Failed to `stat` %s", metricsFile) |
| 119 | } else { |
| 120 | fmt.Printf("\nWrote bp2build metrics to: %s\n", metricsFile) |
| 121 | } |
| 122 | } |
| 123 | |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 124 | func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) { |
| 125 | metrics.ruleClassCount[ruleClass] += 1 |
| 126 | } |
| 127 | |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 128 | func (metrics *CodegenMetrics) AddUnconvertedModule(moduleType string) { |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 129 | metrics.unconvertedModuleCount += 1 |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 130 | metrics.totalModuleTypeCount[moduleType] += 1 |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 131 | } |
| 132 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 133 | func (metrics *CodegenMetrics) TotalModuleCount() uint64 { |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 134 | return metrics.handCraftedModuleCount + |
| 135 | metrics.generatedModuleCount + |
| 136 | metrics.unconvertedModuleCount |
| 137 | } |
| 138 | |
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 947fdbf | 2021-11-10 09:55:20 -0500 | [diff] [blame] | 139 | // Dump serializes the metrics to the given filename |
| 140 | func (metrics *CodegenMetrics) dump(filename string) (err error) { |
| 141 | ser := metrics.Serialize() |
| 142 | return shared.Save(&ser, filename) |
| 143 | } |
| 144 | |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 145 | type ConversionType int |
| 146 | |
| 147 | const ( |
| 148 | Generated ConversionType = iota |
| 149 | Handcrafted |
| 150 | ) |
| 151 | |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 152 | func (metrics *CodegenMetrics) AddConvertedModule(m blueprint.Module, moduleType string, conversionType ConversionType) { |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 153 | // Undo prebuilt_ module name prefix modifications |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 154 | moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name()) |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 155 | metrics.convertedModules = append(metrics.convertedModules, moduleName) |
Chris Parsons | 492bd91 | 2022-01-20 12:55:05 -0500 | [diff] [blame] | 156 | metrics.convertedModuleTypeCount[moduleType] += 1 |
| 157 | metrics.totalModuleTypeCount[moduleType] += 1 |
Jingwen Chen | 310bc8f | 2021-09-20 10:54:27 +0000 | [diff] [blame] | 158 | |
| 159 | if conversionType == Handcrafted { |
| 160 | metrics.handCraftedModuleCount += 1 |
| 161 | } else if conversionType == Generated { |
| 162 | metrics.generatedModuleCount += 1 |
| 163 | } |
Jingwen Chen | 6117450 | 2021-09-17 08:40:45 +0000 | [diff] [blame] | 164 | } |