Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5974423b authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add package for printing starlark formatted data"

parents def9bf2c 72beb346
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@ bootstrap_go_package {
        "soong-remoteexec",
        "soong-response",
        "soong-shared",
        "soong-starlark-format",
        "soong-ui-metrics_proto",

        "golang-protobuf-proto",
        "golang-protobuf-encoding-prototext",

+3 −4
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import (
	"android/soong/android/soongconfig"
	"android/soong/bazel"
	"android/soong/remoteexec"
	"android/soong/starlark_fmt"
)

// Bool re-exports proptools.Bool for the android package.
@@ -286,14 +287,12 @@ func saveToBazelConfigFile(config *productVariables, outDir string) error {
		}
	}

	//TODO(b/216168792) should use common function to print Starlark code
	nonArchVariantProductVariablesJson, err := json.MarshalIndent(&nonArchVariantProductVariables, "", "    ")
	nonArchVariantProductVariablesJson := starlark_fmt.PrintStringList(nonArchVariantProductVariables, 0)
	if err != nil {
		return fmt.Errorf("cannot marshal product variable data: %s", err.Error())
	}

	//TODO(b/216168792) should use common function to print Starlark code
	archVariantProductVariablesJson, err := json.MarshalIndent(&archVariantProductVariables, "", "    ")
	archVariantProductVariablesJson := starlark_fmt.PrintStringList(archVariantProductVariables, 0)
	if err != nil {
		return fmt.Errorf("cannot marshal arch variant product variable data: %s", err.Error())
	}
+40 −0
Original line number Diff line number Diff line
@@ -386,6 +386,46 @@ func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
	})).RunTest(t)
}

func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
	bp := `
		soong_config_string_variable {
			name: "board",
			values: ["soc_a", "soc_b", "soc_c", "soc_a"],
		}

		soong_config_module_type {
			name: "acme_test",
			module_type: "test",
			config_namespace: "acme",
			variables: ["board"],
			properties: ["cflags", "srcs", "defaults"],
		}
    `

	fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
		return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
			variables.VendorVars = vars
		})
	}

	GroupFixturePreparers(
		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
		PrepareForTestWithDefaults,
		FixtureRegisterWithContext(func(ctx RegistrationContext) {
			ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
			ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
			ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
			ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
			ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
		}),
		FixtureWithRootAndroidBp(bp),
	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
		// TODO(b/171232169): improve the error message for non-existent properties
		`Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
	})).RunTest(t)
}

func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
	config := TestConfig(buildDir, nil, bp, fs)

+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ bootstrap_go_package {
        "blueprint-parser",
        "blueprint-proptools",
        "soong-bazel",
        "soong-starlark-format",
    ],
    srcs: [
        "config.go",
+34 −27
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import (
	"github.com/google/blueprint"
	"github.com/google/blueprint/parser"
	"github.com/google/blueprint/proptools"

	"android/soong/starlark_fmt"
)

const conditionsDefault = "conditions_default"
@@ -177,10 +179,14 @@ func processStringVariableDef(v *SoongConfigDefinition, def *parser.Module) (err
		return []error{fmt.Errorf("values property must be set")}
	}

	vals := make(map[string]bool, len(stringProps.Values))
	for _, name := range stringProps.Values {
		if err := checkVariableName(name); err != nil {
			return []error{fmt.Errorf("soong_config_string_variable: values property error %s", err)}
		} else if _, ok := vals[name]; ok {
			return []error{fmt.Errorf("soong_config_string_variable: values property error: duplicate value: %q", name)}
		}
		vals[name] = true
	}

	v.variables[base.variable] = &stringVariable{
@@ -235,7 +241,12 @@ type SoongConfigDefinition struct {
// string vars, bool vars and value vars created by every
// soong_config_module_type in this build.
type Bp2BuildSoongConfigDefinitions struct {
	StringVars map[string]map[string]bool
	// varCache contains a cache of string variables namespace + property
	// The same variable may be used in multiple module types (for example, if need support
	// for cc_default and java_default), only need to process once
	varCache map[string]bool

	StringVars map[string][]string
	BoolVars   map[string]bool
	ValueVars  map[string]bool
}
@@ -253,7 +264,7 @@ func (defs *Bp2BuildSoongConfigDefinitions) AddVars(mtDef SoongConfigDefinition)
	defer bp2buildSoongConfigVarsLock.Unlock()

	if defs.StringVars == nil {
		defs.StringVars = make(map[string]map[string]bool)
		defs.StringVars = make(map[string][]string)
	}
	if defs.BoolVars == nil {
		defs.BoolVars = make(map[string]bool)
@@ -261,15 +272,24 @@ func (defs *Bp2BuildSoongConfigDefinitions) AddVars(mtDef SoongConfigDefinition)
	if defs.ValueVars == nil {
		defs.ValueVars = make(map[string]bool)
	}
	if defs.varCache == nil {
		defs.varCache = make(map[string]bool)
	}
	for _, moduleType := range mtDef.ModuleTypes {
		for _, v := range moduleType.Variables {
			key := strings.Join([]string{moduleType.ConfigNamespace, v.variableProperty()}, "__")
			if strVar, ok := v.(*stringVariable); ok {
				if _, ok := defs.StringVars[key]; !ok {
					defs.StringVars[key] = make(map[string]bool, 0)

			// The same variable may be used in multiple module types (for example, if need support
			// for cc_default and java_default), only need to process once
			if _, keyInCache := defs.varCache[key]; keyInCache {
				continue
			} else {
				defs.varCache[key] = true
			}

			if strVar, ok := v.(*stringVariable); ok {
				for _, value := range strVar.values {
					defs.StringVars[key][value] = true
					defs.StringVars[key] = append(defs.StringVars[key], value)
				}
			} else if _, ok := v.(*boolVariable); ok {
				defs.BoolVars[key] = true
@@ -302,29 +322,16 @@ func sortedStringKeys(m interface{}) []string {
// String emits the Soong config variable definitions as Starlark dictionaries.
func (defs Bp2BuildSoongConfigDefinitions) String() string {
	ret := ""
	ret += "soong_config_bool_variables = {\n"
	for _, boolVar := range sortedStringKeys(defs.BoolVars) {
		ret += fmt.Sprintf("    \"%s\": True,\n", boolVar)
	}
	ret += "}\n"
	ret += "\n"
	ret += "soong_config_bool_variables = "
	ret += starlark_fmt.PrintBoolDict(defs.BoolVars, 0)
	ret += "\n\n"

	ret += "soong_config_value_variables = {\n"
	for _, valueVar := range sortedStringKeys(defs.ValueVars) {
		ret += fmt.Sprintf("    \"%s\": True,\n", valueVar)
	}
	ret += "}\n"
	ret += "\n"
	ret += "soong_config_value_variables = "
	ret += starlark_fmt.PrintBoolDict(defs.ValueVars, 0)
	ret += "\n\n"

	ret += "soong_config_string_variables = {\n"
	for _, stringVar := range sortedStringKeys(defs.StringVars) {
		ret += fmt.Sprintf("    \"%s\": [\n", stringVar)
		for _, choice := range sortedStringKeys(defs.StringVars[stringVar]) {
			ret += fmt.Sprintf("        \"%s\",\n", choice)
		}
		ret += fmt.Sprintf("    ],\n")
	}
	ret += "}"
	ret += "soong_config_string_variables = "
	ret += starlark_fmt.PrintStringListDict(defs.StringVars, 0)

	return ret
}
Loading