Add package for printing starlark formatted data
Bug: 216168792
Test: build/bazel/ci/bp2build.sh
Change-Id: I3a06b19396f7ffe1c638042cda7e731dd840f1d6
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 4bcfa61..b904c35 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -28,6 +28,7 @@
"soong-genrule",
"soong-python",
"soong-sh",
+ "soong-starlark-format",
"soong-ui-metrics",
],
testSrcs: [
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index b3bec65..1d3b105 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -27,6 +27,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/starlark_fmt"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -559,48 +560,27 @@
return "", nil
}
- var ret string
switch propertyValue.Kind() {
case reflect.String:
- ret = fmt.Sprintf("\"%v\"", escapeString(propertyValue.String()))
+ return fmt.Sprintf("\"%v\"", escapeString(propertyValue.String())), nil
case reflect.Bool:
- ret = strings.Title(fmt.Sprintf("%v", propertyValue.Interface()))
+ return starlark_fmt.PrintBool(propertyValue.Bool()), nil
case reflect.Int, reflect.Uint, reflect.Int64:
- ret = fmt.Sprintf("%v", propertyValue.Interface())
+ return fmt.Sprintf("%v", propertyValue.Interface()), nil
case reflect.Ptr:
return prettyPrint(propertyValue.Elem(), indent, emitZeroValues)
case reflect.Slice:
- if propertyValue.Len() == 0 {
- return "[]", nil
- }
-
- if propertyValue.Len() == 1 {
- // Single-line list for list with only 1 element
- ret += "["
- indexedValue, err := prettyPrint(propertyValue.Index(0), indent, emitZeroValues)
+ elements := make([]string, 0, propertyValue.Len())
+ for i := 0; i < propertyValue.Len(); i++ {
+ val, err := prettyPrint(propertyValue.Index(i), indent, emitZeroValues)
if err != nil {
return "", err
}
- ret += indexedValue
- ret += "]"
- } else {
- // otherwise, use a multiline list.
- ret += "[\n"
- for i := 0; i < propertyValue.Len(); i++ {
- indexedValue, err := prettyPrint(propertyValue.Index(i), indent+1, emitZeroValues)
- if err != nil {
- return "", err
- }
-
- if indexedValue != "" {
- ret += makeIndent(indent + 1)
- ret += indexedValue
- ret += ",\n"
- }
+ if val != "" {
+ elements = append(elements, val)
}
- ret += makeIndent(indent)
- ret += "]"
}
+ return starlark_fmt.PrintList(elements, indent, "%s"), nil
case reflect.Struct:
// Special cases where the bp2build sends additional information to the codegenerator
@@ -611,18 +591,12 @@
return fmt.Sprintf("%q", label.Label), nil
}
- ret = "{\n"
// Sort and print the struct props by the key.
structProps := extractStructProperties(propertyValue, indent)
if len(structProps) == 0 {
return "", nil
}
- for _, k := range android.SortedStringKeys(structProps) {
- ret += makeIndent(indent + 1)
- ret += fmt.Sprintf("%q: %s,\n", k, structProps[k])
- }
- ret += makeIndent(indent)
- ret += "}"
+ return starlark_fmt.PrintDict(structProps, indent), nil
case reflect.Interface:
// TODO(b/164227191): implement pretty print for interfaces.
// Interfaces are used for for arch, multilib and target properties.
@@ -631,7 +605,6 @@
return "", fmt.Errorf(
"unexpected kind for property struct field: %s", propertyValue.Kind())
}
- return ret, nil
}
// Converts a reflected property struct value into a map of property names and property values,
@@ -736,13 +709,6 @@
return strings.ReplaceAll(s, "\"", "\\\"")
}
-func makeIndent(indent int) string {
- if indent < 0 {
- panic(fmt.Errorf("indent column cannot be less than 0, but got %d", indent))
- }
- return strings.Repeat(" ", indent)
-}
-
func targetNameWithVariant(c bpToBuildContext, logicModule blueprint.Module) string {
name := ""
if c.ModuleSubDir(logicModule) != "" {
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index dfbb265..d37a523 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -6,6 +6,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/starlark_fmt"
)
// Configurability support for bp2build.
@@ -250,10 +251,10 @@
} else if defaultValue != nil {
// Print an explicit empty list (the default value) even if the value is
// empty, to avoid errors about not finding a configuration that matches.
- ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
+ ret += fmt.Sprintf("%s\"%s\": %s,\n", starlark_fmt.Indention(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
}
- ret += makeIndent(indent)
+ ret += starlark_fmt.Indention(indent)
ret += "})"
return ret, nil
@@ -262,7 +263,7 @@
// prettyPrintSelectEntry converts a reflect.Value into an entry in a select map
// with a provided key.
func prettyPrintSelectEntry(value reflect.Value, key string, indent int, emitZeroValues bool) (string, error) {
- s := makeIndent(indent + 1)
+ s := starlark_fmt.Indention(indent + 1)
v, err := prettyPrint(value, indent+1, emitZeroValues)
if err != nil {
return "", err