From ad3e4fb05992fc6d90f9a91c1310d2755af26b8a Mon Sep 17 00:00:00 2001
From: Justin Van Patten <jvp@justinvp.com>
Date: Mon, 4 Sep 2023 12:51:13 -0700
Subject: [PATCH] [sdk/go] Fix issues with templates (#13872)

Addresses two issues with codegen templates in the Go SDK:

1. `type_builtins.go.template` was including an import for a package
that doesn't exist. (The import doesn't exist in the current generated
code that is checked-in). This change removes the import line from the
template.

2. Some changes had been made directly to `config/require.go`, but this
is a generated file -- the changes should have been made to the
template. This change moves the changes to the template.

After the changes to these templates, running `make gen` in `sdk/go`
yields no diffs.

Fixes #13871
---
 .github/workflows/ci-lint.yml                 | 21 ++++++++++++
 .../templates/config-require.go.template      | 32 ++++++++++++-------
 .../templates/types_builtins.go.template      |  1 -
 3 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml
index be3d86652020..7d95c8d935b4 100644
--- a/.github/workflows/ci-lint.yml
+++ b/.github/workflows/ci-lint.yml
@@ -71,6 +71,27 @@ jobs:
             exit 1
           fi
 
+  gen:
+    name: Generate Go SDK
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          ref: ${{ inputs.ref }}
+      - name: Set up Go
+        uses: actions/setup-go@v3
+        with:
+          go-version: ${{ fromJson(inputs.version-set).go }}
+      - name: Run make gen
+        run: cd sdk/go && make gen
+      - name: Fail if there are changes
+        run: |
+          if [ -n "$(git status --porcelain)" ]; then
+            echo "::error Running 'make gen' in sdk/go resulted in changes"
+            echo "::error Please run 'make gen' in sdk/go and commit the changes"
+            exit 1
+          fi
+
   protobuf-lint:
     name: Lint Protobufs
     runs-on: ubuntu-latest
diff --git a/sdk/go/pulumi/generate/templates/config-require.go.template b/sdk/go/pulumi/generate/templates/config-require.go.template
index 9d54119b0485..6b71a9308bc0 100644
--- a/sdk/go/pulumi/generate/templates/config-require.go.template
+++ b/sdk/go/pulumi/generate/templates/config-require.go.template
@@ -29,21 +29,29 @@ func failf(format string, a ...interface{}) {
 	panic(fmt.Errorf(format, a...))
 }
 
-func require(ctx *pulumi.Context, key, use, insteadOf string) string {
+func require(ctx *pulumi.Context, key string, secret bool, use, insteadOf string) string {
 	v, ok := get(ctx, key, use, insteadOf)
+
+	secretText := " "
+	if secret {
+		secretText = " --secret "
+	}
+
 	if !ok {
-		failf("missing required configuration variable '%s'; run `pulumi config` to set", key)
+		failf("Missing required configuration variable '%s'\n"+
+			"\tplease set a value using the command `pulumi config set%s%s <value>`",
+			key, secretText, key)
 	}
 	return v
 }
 
 // Require loads a configuration value by its key, or panics if it doesn't exist.
 func Require(ctx *pulumi.Context, key string) string {
-	return require(ctx, key, "RequireSecret", "Require")
+	return require(ctx, key, false, "RequireSecret", "Require")
 }
 
-func requireObject(ctx *pulumi.Context, key string, output interface{}, use, insteadOf string) {
-	v := require(ctx, key, use, insteadOf)
+func requireObject(ctx *pulumi.Context, key string, secret bool, output interface{}, use, insteadOf string) {
+	v := require(ctx, key, secret, use, insteadOf)
 	if err := json.Unmarshal([]byte(v), output); err != nil {
 		failf("unable to unmarshall required configuration variable '%s'; %s", key, err.Error())
 	}
@@ -52,13 +60,13 @@ func requireObject(ctx *pulumi.Context, key string, output interface{}, use, ins
 // RequireObject loads an optional configuration value by its key into the output variable,
 // or panics if unable to do so.
 func RequireObject(ctx *pulumi.Context, key string, output interface{}) {
-	requireObject(ctx, key, output, "RequireSecretObject", "RequireObject")
+	requireObject(ctx, key, false, output, "RequireSecretObject", "RequireObject")
 }
 
 {{range .Builtins}}
 {{if .GenerateConfig}}
-func require{{.Name}}(ctx *pulumi.Context, key, use, insteadOf string) {{.Type}} {
-	v := require(ctx, key, use, insteadOf)
+func require{{.Name}}(ctx *pulumi.Context, key string, secret bool, use, insteadOf string) {{.Type}} {
+	v := require(ctx, key, secret, use, insteadOf)
 	o, err := cast.To{{.Name}}E(v)
 	if err != nil {
 		failf("unable to parse required configuration variable '%s'; %s", key, err.Error())
@@ -68,7 +76,7 @@ func require{{.Name}}(ctx *pulumi.Context, key, use, insteadOf string) {{.Type}}
 
 // Require{{.Name}} loads an optional configuration value by its key, as a {{.Type}}, or panics if it doesn't exist.
 func Require{{.Name}}(ctx *pulumi.Context, key string) {{.Type}} {
-	return require{{.Name}}(ctx, key, "RequireSecret{{.Name}}", "Require{{.Name}}")
+	return require{{.Name}}(ctx, key, false, "RequireSecret{{.Name}}", "Require{{.Name}}")
 }
 
 {{end}}
@@ -76,13 +84,13 @@ func Require{{.Name}}(ctx *pulumi.Context, key string) {{.Type}} {
 // RequireSecret loads a configuration value by its key returning it wrapped in a secret Output,
 // or panics if it doesn't exist.
 func RequireSecret(ctx *pulumi.Context, key string) pulumi.StringOutput {
-	return pulumi.ToSecret(require(ctx, key, "", "")).(pulumi.StringOutput)
+	return pulumi.ToSecret(require(ctx, key, true, "", "")).(pulumi.StringOutput)
 }
 
 // RequireSecretObject loads an optional configuration value by its key into the output variable,
 // returning it wrapped in a secret Output, or panics if unable to do so.
 func RequireSecretObject(ctx *pulumi.Context, key string, output interface{}) pulumi.Output {
-	requireObject(ctx, key, output, "", "")
+	requireObject(ctx, key, true, output, "", "")
 	return pulumi.ToSecret(output)
 }
 
@@ -91,7 +99,7 @@ func RequireSecretObject(ctx *pulumi.Context, key string, output interface{}) pu
 // RequireSecret{{.Name}} loads an optional configuration value by its key,
 // as a {{.Type}} wrapped in a secret Output, or panics if it doesn't exist.
 func RequireSecret{{.Name}}(ctx *pulumi.Context, key string) pulumi.{{.Name}}Output {
-	return pulumi.ToSecret(require{{.Name}}(ctx, key, "", "")).(pulumi.{{.Name}}Output)
+	return pulumi.ToSecret(require{{.Name}}(ctx, key, true, "", "")).(pulumi.{{.Name}}Output)
 }
 {{end}}
 {{end}}
diff --git a/sdk/go/pulumi/generate/templates/types_builtins.go.template b/sdk/go/pulumi/generate/templates/types_builtins.go.template
index 2cbfad44ef24..5f4044089c9a 100644
--- a/sdk/go/pulumi/generate/templates/types_builtins.go.template
+++ b/sdk/go/pulumi/generate/templates/types_builtins.go.template
@@ -23,7 +23,6 @@ import (
 	"reflect"
 
 	"github.com/pulumi/pulumi/sdk/v3/go/internal"
-	"github.com/pulumi/pulumi/sdk/v3/go/pulumi/internal"
 	"github.com/pulumi/pulumi/sdk/v3/go/pulumix"
 )
 
