1// Copyright 2022 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package starlark_fmt 16 17import ( 18 "fmt" 19 "sort" 20 "strings" 21) 22 23const ( 24 indent = 4 25) 26 27// Indention returns an indent string of the specified level. 28func Indention(level int) string { 29 if level < 0 { 30 panic(fmt.Errorf("indent level cannot be less than 0, but got %d", level)) 31 } 32 return strings.Repeat(" ", level*indent) 33} 34 35// PrintBool returns a Starlark compatible bool string. 36func PrintBool(item bool) string { 37 return strings.Title(fmt.Sprintf("%t", item)) 38} 39 40// PrintsStringList returns a Starlark-compatible string of a list of Strings/Labels. 41func PrintStringList(items []string, indentLevel int) string { 42 return PrintList(items, indentLevel, func(s string) string { 43 if strings.Contains(s, "\"") { 44 return `'''%s'''` 45 } 46 return `"%s"` 47 }) 48} 49 50// PrintList returns a Starlark-compatible string of list formmated as requested. 51func PrintList(items []string, indentLevel int, formatString func(string) string) string { 52 if len(items) == 0 { 53 return "[]" 54 } else if len(items) == 1 { 55 return fmt.Sprintf("["+formatString(items[0])+"]", items[0]) 56 } 57 list := make([]string, 0, len(items)+2) 58 list = append(list, "[") 59 innerIndent := Indention(indentLevel + 1) 60 for _, item := range items { 61 list = append(list, fmt.Sprintf(`%s`+formatString(item)+`,`, innerIndent, item)) 62 } 63 list = append(list, Indention(indentLevel)+"]") 64 return strings.Join(list, "\n") 65} 66 67// PrintStringListDict returns a Starlark-compatible string formatted as dictionary with 68// string keys and list of string values. 69func PrintStringListDict(dict map[string][]string, indentLevel int) string { 70 formattedValueDict := make(map[string]string, len(dict)) 71 for k, v := range dict { 72 formattedValueDict[k] = PrintStringList(v, indentLevel+1) 73 } 74 return PrintDict(formattedValueDict, indentLevel) 75} 76 77// PrintBoolDict returns a starlark-compatible string containing a dictionary with string keys and 78// values printed with no additional formatting. 79func PrintBoolDict(dict map[string]bool, indentLevel int) string { 80 formattedValueDict := make(map[string]string, len(dict)) 81 for k, v := range dict { 82 formattedValueDict[k] = PrintBool(v) 83 } 84 return PrintDict(formattedValueDict, indentLevel) 85} 86 87// PrintDict returns a starlark-compatible string containing a dictionary with string keys and 88// values printed with no additional formatting. 89func PrintDict(dict map[string]string, indentLevel int) string { 90 if len(dict) == 0 { 91 return "{}" 92 } 93 items := make([]string, 0, len(dict)) 94 for k, v := range dict { 95 items = append(items, fmt.Sprintf(`%s"%s": %s,`, Indention(indentLevel+1), k, v)) 96 } 97 sort.Strings(items) 98 return fmt.Sprintf(`{ 99%s 100%s}`, strings.Join(items, "\n"), Indention(indentLevel)) 101} 102