From a78b020089ca1c0381da33c1f9beb1c195987a5e Mon Sep 17 00:00:00 2001 From: kgui Date: Tue, 25 Jan 2022 16:19:25 +0800 Subject: [PATCH] Support writing inputs/outputs of actions of modules into a file from the moduleInfo.actionDefs. An example module variant in the module-actions.json: { "Name": "metalava-gradle-plugin-deps", "Variations": null, "DependencyVariations": null, "Deps": [ { "Name": "prebuilts_gradle-plugin_license", "Variations": null, "DependencyVariations": null, "Tag": "" } ], "Type": "", "Blueprint": "prebuilts/gradle-plugin/Android.bp", "Module": { "Actions": [ { "Inputs": [ "prebuilts/gradle-plugin/com/android/tools/lint/lint-api/30.1.0-alpha13/lint-api-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/lint/lint-checks/30.1.0-alpha13/lint-checks-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/lint/lint/30.1.0-alpha13/lint-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/lint/lint-gradle/30.1.0-alpha13/lint-gradle-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/lint/lint-model/30.1.0-alpha13/lint-model-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/common/30.1.0-alpha13/common-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/sdk-common/30.1.0-alpha13/sdk-common-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/sdklib/30.1.0-alpha13/sdklib-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/external/org-jetbrains/uast/30.1.0-alpha13/uast-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/external/com-intellij/intellij-core/30.1.0-alpha13/intellij-core-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/external/com-intellij/kotlin-compiler/30.1.0-alpha13/kotlin-compiler-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/repository/30.1.0-alpha13/repository-30.1.0-alpha13.jar", "prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/30.1.0-alpha13/manifest-merger-30.1.0-alpha13.jar" ], "Outputs": [ "out/soong/.intermediates/prebuilts/gradle-plugin/metalava-gradle-plugin-deps/linux_glibc_common/combined/metalava-gradle-plugin-deps.jar" ] }, { "Inputs": null, "Outputs": [ "out/soong/.intermediates/prebuilts/gradle-plugin/metalava-gradle-plugin-deps/linux_glibc_common/meta_lic" ] } ] } } Test: local Change-Id: Icbb7236507251e257f6773b110ae8a0788eef41e --- context.go | 78 ++++++++++++++++++++++++++++++++----------------- context_test.go | 33 --------------------- 2 files changed, 52 insertions(+), 59 deletions(-) diff --git a/context.go b/context.go index e0442ce..d93b957 100644 --- a/context.go +++ b/context.go @@ -2297,26 +2297,6 @@ type JSONDataSupplier interface { AddJSONData(d *map[string]interface{}) } -// A JSONDataAction contains the inputs and outputs of actions of a module. Which helps pass such -// data to be included in the JSON module graph. -type JSONDataAction struct { - Inputs []string - Outputs []string -} - -// FormatJSONDataActions puts the content of a list of JSONDataActions into a standard format to be -// appended into the JSON module graph. -func FormatJSONDataActions(jsonDataActions []JSONDataAction) []map[string]interface{} { - var actions []map[string]interface{} - for _, jsonDataAction := range jsonDataActions { - actions = append(actions, map[string]interface{}{ - "Inputs": jsonDataAction.Inputs, - "Outputs": jsonDataAction.Outputs, - }) - } - return actions -} - func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule { result := &JsonModule{ jsonModuleName: *jsonModuleNameFromModuleInfo(m), @@ -2325,11 +2305,9 @@ func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule { Blueprint: m.relBlueprintsFile, Module: make(map[string]interface{}), } - if j, ok := m.logicModule.(JSONDataSupplier); ok { j.AddJSONData(&result.Module) } - for _, p := range m.providers { if j, ok := p.(JSONDataSupplier); ok { j.AddJSONData(&result.Module) @@ -2338,20 +2316,68 @@ func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule { return result } -func (c *Context) PrintJSONGraph(w io.Writer) { - modules := make([]*JsonModule, 0) +func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule { + result := &JsonModule{ + jsonModuleName: jsonModuleName{ + Name: m.Name(), + }, + Deps: make([]jsonDep, 0), + Type: m.typeName, + Blueprint: m.relBlueprintsFile, + Module: make(map[string]interface{}), + } + var actions []map[string]interface{} + for _, bDef := range m.actionDefs.buildDefs { + actions = append(actions, map[string]interface{}{ + "Inputs": append( + getNinjaStringsWithNilPkgNames(bDef.Inputs), + getNinjaStringsWithNilPkgNames(bDef.Implicits)...), + "Outputs": append( + getNinjaStringsWithNilPkgNames(bDef.Outputs), + getNinjaStringsWithNilPkgNames(bDef.ImplicitOutputs)...), + }) + } + result.Module["Actions"] = actions + return result +} + +// Gets a list of strings from the given list of ninjaStrings by invoking ninjaString.Value with +// nil pkgNames on each of the input ninjaStrings. +func getNinjaStringsWithNilPkgNames(nStrs []ninjaString) []string { + var strs []string + for _, nstr := range nStrs { + strs = append(strs, nstr.Value(nil)) + } + return strs +} + +// PrintJSONGraph prints info of modules in a JSON file. +func (c *Context) PrintJSONGraphAndActions(wGraph io.Writer, wActions io.Writer) { + modulesToGraph := make([]*JsonModule, 0) + modulesToActions := make([]*JsonModule, 0) for _, m := range c.modulesSorted { jm := jsonModuleFromModuleInfo(m) + jmWithActions := jsonModuleWithActionsFromModuleInfo(m) for _, d := range m.directDeps { jm.Deps = append(jm.Deps, jsonDep{ jsonModuleName: *jsonModuleNameFromModuleInfo(d.module), Tag: fmt.Sprintf("%T %+v", d.tag, d.tag), }) + jmWithActions.Deps = append(jmWithActions.Deps, jsonDep{ + jsonModuleName: jsonModuleName{ + Name: d.module.Name(), + }, + }) + } - - modules = append(modules, jm) + modulesToGraph = append(modulesToGraph, jm) + modulesToActions = append(modulesToActions, jmWithActions) } + writeJson(wGraph, modulesToGraph) + writeJson(wActions, modulesToActions) +} +func writeJson(w io.Writer, modules []*JsonModule) { e := json.NewEncoder(w) e.SetIndent("", "\t") e.Encode(modules) diff --git a/context_test.go b/context_test.go index 915f273..6308ba9 100644 --- a/context_test.go +++ b/context_test.go @@ -607,39 +607,6 @@ func TestParseFailsForModuleWithoutName(t *testing.T) { } } -func TestFormatJSONDataActions(t *testing.T) { - inputs := []string{"fake/input/1", "fake/input/2"} - outputs := []string{"fake/output/1", "fake/output/2"} - jsonDataActionEmptyInputs := JSONDataAction{ - Outputs: outputs, - } - jsonDataActionEmptyOutputs := JSONDataAction{ - Inputs: inputs, - } - jsonDataAction := JSONDataAction{ - Inputs: inputs, - Outputs: outputs, - } - formatData := FormatJSONDataActions([]JSONDataAction{ - jsonDataActionEmptyInputs, jsonDataActionEmptyOutputs, jsonDataAction}) - if fmt.Sprint(formatData) != fmt.Sprint([]map[string]interface{}{ - map[string]interface{}{ - "Inputs": []string{}, - "Outputs": outputs, - }, - map[string]interface{}{ - "Inputs": inputs, - "Outputs": []string{}, - }, - map[string]interface{}{ - "Inputs": inputs, - "Outputs": outputs, - }, - }) { - t.Errorf("The formatted JSON data %s isn't expected.", formatData) - } -} - func Test_findVariant(t *testing.T) { module := &moduleInfo{ variant: variant{