diff --git a/.ci/containers/downstream-builder/generate_downstream.sh b/.ci/containers/downstream-builder/generate_downstream.sh index 6f9c7503fe69..8e0f424d8a81 100755 --- a/.ci/containers/downstream-builder/generate_downstream.sh +++ b/.ci/containers/downstream-builder/generate_downstream.sh @@ -155,6 +155,11 @@ else fi pushd ../ make tpgtools OUTPUT_PATH=$LOCAL_PATH VERSION=$VERSION + + # Only generate TeamCity-related file for TPG and TPGB + if [ "$VERSION" == "ga" ] || [ "$VERSION" == "beta" ]; then + make teamcity-servicemap-generate OUTPUT_PATH=$LOCAL_PATH VERSION=$VERSION + fi popd fi fi diff --git a/GNUmakefile b/GNUmakefile index aa68253ad701..d0aba519508b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -59,6 +59,7 @@ terraform build provider: @make validate_environment; make mmv1 make tpgtools + make teamcity-servicemap-generate mmv1: cd mmv1;\ @@ -70,6 +71,12 @@ tpgtools: cd tpgtools;\ go run . --output $(OUTPUT_PATH) --version $(VERSION) $(tpgtools_compile) +# This should be removed when all DCL resources are migrated to MMv1; service map generation should be +# controlled inside MMv1, like originally implemented in this PR: https://github.com/GoogleCloudPlatform/magic-modules/pull/8254 +teamcity-servicemap-generate: + cd tools/teamcity-generator;\ + go run . --output $(OUTPUT_PATH) --version $(VERSION) + tgc: cd mmv1;\ bundle;\ diff --git a/tools/teamcity-generator/go.mod b/tools/teamcity-generator/go.mod new file mode 100644 index 000000000000..e0b2073fc3a3 --- /dev/null +++ b/tools/teamcity-generator/go.mod @@ -0,0 +1,5 @@ +module github.com/GoogleCloudPlatform/magic-modules/tools/teamcity-generator + +go 1.19 + +require golang.org/x/text v0.11.0 diff --git a/tools/teamcity-generator/go.sum b/tools/teamcity-generator/go.sum new file mode 100644 index 000000000000..5f53cd09023b --- /dev/null +++ b/tools/teamcity-generator/go.sum @@ -0,0 +1,2 @@ +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= diff --git a/tools/teamcity-generator/main.go b/tools/teamcity-generator/main.go new file mode 100644 index 000000000000..17e10969d12f --- /dev/null +++ b/tools/teamcity-generator/main.go @@ -0,0 +1,126 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +var GA_VERSION = "ga" +var BETA_VERSION = "beta" + +var oPath = flag.String("output", "", "path to output generated files to") +var ver = flag.String("version", "", "version name, value must be `ga` or `beta`") + +func main() { + var version string + var outputPath string + + flag.Parse() + outputPath = *oPath + version = *ver + if outputPath == "" { + log.Fatalf("missing output flag: provide `--output ` to set the path to output generated files to") + } + if version == "" { + log.Fatalf("missing version flag: provide `--version ` to set the path to output generated files to") + } + if version != GA_VERSION && version != BETA_VERSION { + log.Fatalf("invalid version flag value: value must be `%s` or `%s`", GA_VERSION, BETA_VERSION) + } + + var terraformResourceDirectory string + switch version { + case GA_VERSION: + terraformResourceDirectory = "google" + case BETA_VERSION: + terraformResourceDirectory = "google-beta" + default: + log.Fatalf("invalid version flag value: value must be `%s` or `%s`", GA_VERSION, BETA_VERSION) + } + + log.Printf("Generating TeamCity configuration service package map for `%s` provider", terraformResourceDirectory) + + // Get a list of the service packages found in a given directory + servicesDir := fmt.Sprintf("%s/%s/services", outputPath, terraformResourceDirectory) + serviceList, err := readAllServicePackages(servicesDir) + if err != nil { + log.Fatalf("error determining service package list: %s", err) + } + + // Create a string of the map that should be created in .teamcity/components/generated/services.kt + serviceMap, err := createMap(serviceList) + if err != nil { + log.Fatalf("error creating service package map: %s", err) + } + + // Ensure .teamcity/components/generated/services.kt exists, create if not present + // "Create creates or truncates the named file. If the file already exists, it is truncated." + servicesKtFilePath := fmt.Sprintf("%s/.teamcity/components/generated/services.kt", outputPath) + log.Printf("Opening %s", servicesKtFilePath) + f, err := os.Create(servicesKtFilePath) + if err != nil { + log.Fatalf("error creating or truncating existing file `.teamcity/components/generated/services.kt` in output directory: %s", err) + } + defer f.Close() + + // Save map to .teamcity/components/generated/services.kt + log.Printf("Saving service map to %s", servicesKtFilePath) + _, err = f.Write([]byte(serviceMap)) + if err != nil { + log.Fatalf("error writing to file `.teamcity/components/generated/services.kt` in output directory: %s", err) + } + + log.Println("Finished") +} + +func readAllServicePackages(providerDir string) ([]string, error) { + packages, err := os.ReadDir(providerDir) + if err != nil { + return nil, err + } + var services = make([]string, 0) + + for _, p := range packages { + services = append(services, p.Name()) + } + if len(services) == 0 { + return nil, fmt.Errorf("found 0 service packages in %s", providerDir) + } + return services, nil +} + +func createMap(packageNames []string) (string, error) { + + entryTemplate := " \"%s\" to \"%s\",\n" + lastEntryTemplate := " \"%s\" to \"%s\"\n" // No trailing comma + caser := cases.Title(language.English) + + var b strings.Builder + b.WriteString("// this file is auto-generated by magic-modules/tools/teamcity-generator, any changes made here will be overwritten\n\n") + b.WriteString("var services = mapOf(\n") + for i, p := range packageNames { + + var e string + if i < (len(packageNames) - 1) { + e = fmt.Sprintf(entryTemplate, p, caser.String(p)) + } else { + // Final entry in map doesn't have comma + e = fmt.Sprintf(lastEntryTemplate, p, caser.String(p)) + } + + _, err := fmt.Fprint(&b, e) + if err != nil { + return "", err + } + + } + b.WriteString(")\n") + + return b.String(), nil +}