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
This commit is contained in:
kgui 2022-01-25 16:19:25 +08:00
parent 00895de89a
commit a78b020089
2 changed files with 52 additions and 59 deletions

View file

@ -2297,26 +2297,6 @@ type JSONDataSupplier interface {
AddJSONData(d *map[string]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 { func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule {
result := &JsonModule{ result := &JsonModule{
jsonModuleName: *jsonModuleNameFromModuleInfo(m), jsonModuleName: *jsonModuleNameFromModuleInfo(m),
@ -2325,11 +2305,9 @@ func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule {
Blueprint: m.relBlueprintsFile, Blueprint: m.relBlueprintsFile,
Module: make(map[string]interface{}), Module: make(map[string]interface{}),
} }
if j, ok := m.logicModule.(JSONDataSupplier); ok { if j, ok := m.logicModule.(JSONDataSupplier); ok {
j.AddJSONData(&result.Module) j.AddJSONData(&result.Module)
} }
for _, p := range m.providers { for _, p := range m.providers {
if j, ok := p.(JSONDataSupplier); ok { if j, ok := p.(JSONDataSupplier); ok {
j.AddJSONData(&result.Module) j.AddJSONData(&result.Module)
@ -2338,20 +2316,68 @@ func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule {
return result return result
} }
func (c *Context) PrintJSONGraph(w io.Writer) { func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule {
modules := make([]*JsonModule, 0) 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 { for _, m := range c.modulesSorted {
jm := jsonModuleFromModuleInfo(m) jm := jsonModuleFromModuleInfo(m)
jmWithActions := jsonModuleWithActionsFromModuleInfo(m)
for _, d := range m.directDeps { for _, d := range m.directDeps {
jm.Deps = append(jm.Deps, jsonDep{ jm.Deps = append(jm.Deps, jsonDep{
jsonModuleName: *jsonModuleNameFromModuleInfo(d.module), jsonModuleName: *jsonModuleNameFromModuleInfo(d.module),
Tag: fmt.Sprintf("%T %+v", d.tag, d.tag), Tag: fmt.Sprintf("%T %+v", d.tag, d.tag),
}) })
jmWithActions.Deps = append(jmWithActions.Deps, jsonDep{
jsonModuleName: jsonModuleName{
Name: d.module.Name(),
},
})
} }
modulesToGraph = append(modulesToGraph, jm)
modules = append(modules, jm) modulesToActions = append(modulesToActions, jmWithActions)
} }
writeJson(wGraph, modulesToGraph)
writeJson(wActions, modulesToActions)
}
func writeJson(w io.Writer, modules []*JsonModule) {
e := json.NewEncoder(w) e := json.NewEncoder(w)
e.SetIndent("", "\t") e.SetIndent("", "\t")
e.Encode(modules) e.Encode(modules)

View file

@ -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) { func Test_findVariant(t *testing.T) {
module := &moduleInfo{ module := &moduleInfo{
variant: variant{ variant: variant{