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