diff --git a/.gitignore b/.gitignore index afc5fdafd..7546664d9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,9 @@ coverage.cov # it up when they pass.) **/command-output/ +# Likewise, we don't want to keep the typechecked version of our codegen tests. +pkg/codegen/internal/test/testdata/*/typecheck/** + # By default, we don't check in yarn.lock files **/yarn.lock diff --git a/pkg/codegen/docs/gen_test.go b/pkg/codegen/docs/gen_test.go index 0fc12c258..15fae4a3c 100644 --- a/pkg/codegen/docs/gen_test.go +++ b/pkg/codegen/docs/gen_test.go @@ -411,5 +411,6 @@ func generatePackage(tool string, pkg *schema.Package, extraFiles map[string][]b } func TestGeneratePackage(t *testing.T) { - test.TestSDKCodegen(t, "docs", generatePackage) + // TODO: do we have a compile step on templates? + test.TestSDKCodegen(t, "docs", generatePackage, func(*testing.T, string) {}) } diff --git a/pkg/codegen/dotnet/gen_test.go b/pkg/codegen/dotnet/gen_test.go index f20c45ab4..c80a7181c 100644 --- a/pkg/codegen/dotnet/gen_test.go +++ b/pkg/codegen/dotnet/gen_test.go @@ -1,17 +1,40 @@ package dotnet import ( + "os" + "path/filepath" "testing" - "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test" - "github.com/pulumi/pulumi/pkg/v3/codegen/schema" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test" + "github.com/pulumi/pulumi/pkg/v3/codegen/schema" + "github.com/pulumi/pulumi/pkg/v3/testing/integration" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/executable" ) func TestGeneratePackage(t *testing.T) { - test.TestSDKCodegen(t, "dotnet", GeneratePackage) + test.TestSDKCodegen(t, "dotnet", GeneratePackage, typeCheckGeneratedPackage) +} + +func typeCheckGeneratedPackage(t *testing.T, pwd string) { + var err error + var dotnet string + + // TODO remove when https://github.com/pulumi/pulumi/pull/7938 lands + version := "0.0.0\n" + err = os.WriteFile(filepath.Join(pwd, "version.txt"), []byte(version), 0600) + if !os.IsExist(err) { + require.NoError(t, err) + } + // endTODO + + dotnet, err = executable.FindExecutable("dotnet") + require.NoError(t, err) + cmdOptions := integration.ProgramTestOptions{} + err = integration.RunCommand(t, "dotnet build", []string{dotnet, "build"}, pwd, &cmdOptions) + require.NoError(t, err) } func TestGenerateType(t *testing.T) { diff --git a/pkg/codegen/go/gen_test.go b/pkg/codegen/go/gen_test.go index b4ca2efe1..2715a830d 100644 --- a/pkg/codegen/go/gen_test.go +++ b/pkg/codegen/go/gen_test.go @@ -1,6 +1,7 @@ package gen import ( + "bytes" "encoding/json" "fmt" "io" @@ -19,7 +20,9 @@ import ( "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant" tree "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant/tree/v1" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" + "github.com/pulumi/pulumi/pkg/v3/testing/integration" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/executable" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) @@ -65,7 +68,51 @@ func TestGeneratePackage(t *testing.T) { generatePackage := func(tool string, pkg *schema.Package, files map[string][]byte) (map[string][]byte, error) { return GeneratePackage(tool, pkg) } - test.TestSDKCodegen(t, "go", generatePackage) + test.TestSDKCodegen(t, "go", generatePackage, typeCheckGeneratedPackage) +} + +func typeCheckGeneratedPackage(t *testing.T, pwd string) { + var err error + var ex string + ex, err = executable.FindExecutable("go") + require.NoError(t, err) + + // go SDKs live in their own folder: + // typecheck/go/$NAME/$FILES + // where FILES contains all the project files (including go.mod) + // + // This is not true when `package.language.go.rootPackageName` is set. + dir, err := ioutil.ReadDir(pwd) + require.NoError(t, err) + root := pwd + if len(dir) == 1 { + require.True(t, dir[0].IsDir()) + root = filepath.Join(pwd, dir[0].Name()) + } + t.Logf("*** Testing go in dir: %q ***", root) + + var stdout, stderr bytes.Buffer + cmdOptions := integration.ProgramTestOptions{Stderr: &stderr, Stdout: &stdout} + // We don't want to corrupt the global go.mod and go.sum with packages we + // don't actually depend on. For this, we need to have each go package be + // it's own module. + err = integration.RunCommand(t, "mod init", + []string{ex, "mod", "init", "github.com/pulumi/test/internal"}, root, &cmdOptions) + if err != nil { + stdout := stdout.String() + stderr := stderr.String() + if len(stdout) > 0 { + t.Logf("stdout: %s", stdout) + } + if len(stderr) > 0 { + t.Logf("stderr: %s", stderr) + } + t.FailNow() + } + err = integration.RunCommand(t, "get", []string{ex, "get"}, root, &cmdOptions) + require.NoError(t, err) + err = integration.RunCommand(t, "go build", []string{ex, "build"}, root, &cmdOptions) + require.NoError(t, err) } func TestGenerateTypeNames(t *testing.T) { diff --git a/pkg/codegen/internal/test/helpers.go b/pkg/codegen/internal/test/helpers.go index 0d144aa1f..4e9751fff 100644 --- a/pkg/codegen/internal/test/helpers.go +++ b/pkg/codegen/internal/test/helpers.go @@ -155,7 +155,15 @@ func RewriteFilesWhenPulumiAccept(t *testing.T, dir, lang string, actual map[str require.NoError(t, err) } - for file, bytes := range actual { + WriteTestFiles(t, dir, lang, actual) + + return true +} + +// WriteTestFiles writes out the files generated by GeneratePackage to a directory. +func WriteTestFiles(t *testing.T, dir, lang string, files map[string][]byte) { + var err error + for file, bytes := range files { relPath := filepath.FromSlash(file) path := filepath.Join(dir, lang, relPath) @@ -166,8 +174,6 @@ func RewriteFilesWhenPulumiAccept(t *testing.T, dir, lang string, actual map[str err = ioutil.WriteFile(path, bytes, 0600) require.NoError(t, err) } - - return true } // CheckAllFilesGenerated ensures that the set of expected and actual files generated diff --git a/pkg/codegen/internal/test/sdk_driver.go b/pkg/codegen/internal/test/sdk_driver.go index f76f1d409..4f2866191 100644 --- a/pkg/codegen/internal/test/sdk_driver.go +++ b/pkg/codegen/internal/test/sdk_driver.go @@ -6,20 +6,28 @@ import ( "path/filepath" "testing" - "github.com/pulumi/pulumi/pkg/v3/codegen" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/pulumi/pulumi/pkg/v3/codegen" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" ) type ThenFunc func(t *testing.T, testDir string) type sdkTest struct { - Directory string - Description string - Skip codegen.StringSet - Then map[string]ThenFunc + Directory string + Description string + SkipCompileCheck codegen.StringSet + Then map[string]ThenFunc } +const ( + nodejs = "nodejs" + dotnet = "dotnet" + golang = "go" +) + var sdkTests = []sdkTest{ { Directory: "input-collision", @@ -30,16 +38,19 @@ var sdkTests = []sdkTest{ Description: "Simple schema with a two part name (foo-bar)", }, { - Directory: "external-resource-schema", - Description: "External resource schema", + Directory: "external-resource-schema", + Description: "External resource schema", + SkipCompileCheck: codegen.NewStringSet(nodejs, golang), }, { - Directory: "nested-module", - Description: "Nested module", + Directory: "nested-module", + Description: "Nested module", + SkipCompileCheck: codegen.NewStringSet(dotnet, nodejs), }, { - Directory: "nested-module-thirdparty", - Description: "Third-party nested module", + Directory: "nested-module-thirdparty", + Description: "Third-party nested module", + SkipCompileCheck: codegen.NewStringSet(dotnet, nodejs), }, { Directory: "plain-schema-gh6957", @@ -81,24 +92,35 @@ var sdkTests = []sdkTest{ Description: "Simple schema with local resource properties and custom Python package name", }, { - Directory: "simple-methods-schema", - Description: "Simple schema with methods", + Directory: "simple-methods-schema", + Description: "Simple schema with methods", + SkipCompileCheck: codegen.NewStringSet(nodejs, dotnet, golang), }, { Directory: "simple-yaml-schema", Description: "Simple schema encoded using YAML", }, { - Directory: "provider-config-schema", - Description: "Simple provider config schema", + Directory: "provider-config-schema", + Description: "Simple provider config schema", + SkipCompileCheck: codegen.NewStringSet(dotnet), }, { - Directory: "replace-on-change", - Description: "Simple use of replaceOnChange in schema", + Directory: "replace-on-change", + Description: "Simple use of replaceOnChange in schema", + SkipCompileCheck: codegen.NewStringSet(golang), + }, + { + Directory: "resource-property-overlap", + Description: "A resource with the same name as it's property", + SkipCompileCheck: codegen.NewStringSet(dotnet, nodejs), }, } -// TestSDKCodegen runs the complete set of SDK code generation tests against a particular language's code generator. +type checkPackageSignature = func(t *testing.T, pwd string) + +// TestSDKCodegen runs the complete set of SDK code generation tests against a particular language's code +// generator. It also verifies that the generated code is structurally sound. // // An SDK code generation test consists of a schema and a set of expected outputs for each language. Each test is // structured as a directory that contains that information: @@ -111,16 +133,11 @@ var sdkTests = []sdkTest{ // // The schema is the only piece that must be manually authored. Once the schema has been written, the expected outputs // can be generated by running `PULUMI_ACCEPT=true go test ./..." from the `pkg/codegen` directory. -func TestSDKCodegen(t *testing.T, language string, genPackage GenPkgSignature) { +func TestSDKCodegen(t *testing.T, language string, genPackage GenPkgSignature, checkPackage checkPackageSignature) { testDir := filepath.Join("..", "internal", "test", "testdata") for _, tt := range sdkTests { t.Run(tt.Description, func(t *testing.T) { - if tt.Skip.Has(language) { - t.Skip() - return - } - dirPath := filepath.Join(testDir, filepath.FromSlash(tt.Directory)) schemaPath := filepath.Join(dirPath, "schema.json") @@ -131,6 +148,17 @@ func TestSDKCodegen(t *testing.T, language string, genPackage GenPkgSignature) { files, err := GeneratePackageFilesFromSchema(schemaPath, genPackage) require.NoError(t, err) + // Check output is valid code (will type-check). If code will not + // type-check, we don't allow the user to run PULUMI_ACCEPT=true and + // replace the test files. + if !tt.SkipCompileCheck.Has(language) { + typeCheckPath := filepath.Join(dirPath, "typecheck") + langTypeCheckPath := filepath.Join(typeCheckPath, language) + contract.IgnoreError(os.RemoveAll(langTypeCheckPath)) + WriteTestFiles(t, typeCheckPath, language, files) + checkPackage(t, langTypeCheckPath) + } + if !RewriteFilesWhenPulumiAccept(t, dirPath, language, files) { expectedFiles, err := LoadBaseline(dirPath, language) require.NoError(t, err) diff --git a/pkg/codegen/internal/test/testdata/dash-named-schema/dotnet/Pulumi.FooBar.csproj b/pkg/codegen/internal/test/testdata/dash-named-schema/dotnet/Pulumi.FooBar.csproj index b172ade5b..73d6f9045 100644 --- a/pkg/codegen/internal/test/testdata/dash-named-schema/dotnet/Pulumi.FooBar.csproj +++ b/pkg/codegen/internal/test/testdata/dash-named-schema/dotnet/Pulumi.FooBar.csproj @@ -40,6 +40,10 @@ + + + + diff --git a/pkg/codegen/internal/test/testdata/dash-named-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/dash-named-schema/nodejs/package.json index ea1af898a..5b1b96336 100644 --- a/pkg/codegen/internal/test/testdata/dash-named-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/dash-named-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/dash-named-schema/schema.json b/pkg/codegen/internal/test/testdata/dash-named-schema/schema.json index 1739e4ccb..0e5575b21 100644 --- a/pkg/codegen/internal/test/testdata/dash-named-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/dash-named-schema/schema.json @@ -35,12 +35,25 @@ "csharp": { "namespaces": { "foo-bar": "FooBar" + }, + "packageReferences": { + "Pulumi": "3.12", + "Pulumi.Aws": "4.20", + "Pulumi.Kubernetes": "3.7", + "Pulumi.Random": "4.2" } }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/dash-named-schema/go/foo" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/external-resource-schema/dotnet/Pulumi.Example.csproj index b172ade5b..4f75fb3c2 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/dotnet/Pulumi.Example.csproj @@ -40,6 +40,10 @@ + + + + diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/argFunction.go b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/argFunction.go index 95b3d5897..6a560b669 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/argFunction.go +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/argFunction.go @@ -7,7 +7,7 @@ import ( "context" "reflect" - "github.com/pulumi/pulumi-random/sdk/v2/go/random" + "github.com/pulumi/pulumi-random/sdk/v4/go/random" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/component.go b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/component.go index b10c256f6..404dd9d3a 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/component.go +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/component.go @@ -8,10 +8,10 @@ import ( "reflect" "github.com/pkg/errors" - "github.com/pulumi/pulumi-aws/sdk/v3/go/aws/ec2" - "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes" - metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/meta/v1" - storagev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/storage/v1" + "github.com/pulumi/pulumi-aws/sdk/v4/go/aws/ec2" + "github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes" + metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/meta/v1" + storagev1 "github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/storage/v1" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/pulumiTypes.go b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/pulumiTypes.go index eae3e8dac..4289ace2a 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/pulumiTypes.go +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/pulumiTypes.go @@ -7,7 +7,7 @@ import ( "context" "reflect" - "github.com/pulumi/pulumi-random/sdk/v2/go/random" + "github.com/pulumi/pulumi-random/sdk/v4/go/random" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/workload.go b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/workload.go index 2733e1f95..d23ac7684 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/workload.go +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/go/example/workload.go @@ -7,7 +7,7 @@ import ( "context" "reflect" - corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/core/v1" + corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/core/v1" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/package.json index 9ac06bdfc..a4a7d2234 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/package.json @@ -4,6 +4,11 @@ "scripts": { "build": "tsc" }, + "dependencies": { + "@pulumi/aws": "^4.19.0", + "@pulumi/kubernetes": "^3.7.0", + "@pulumi/random": "^4.2.0" + }, "devDependencies": { "typescript": "^4.3.5" }, diff --git a/pkg/codegen/internal/test/testdata/external-resource-schema/schema.json b/pkg/codegen/internal/test/testdata/external-resource-schema/schema.json index 03e4f5f79..6895b0bb1 100644 --- a/pkg/codegen/internal/test/testdata/external-resource-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/external-resource-schema/schema.json @@ -5,33 +5,33 @@ "example::Pet": { "properties": { "name": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" }, "requiredName": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" }, "nameArray": { "type": "array", "items": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" } }, "requiredNameArray": { "type": "array", "items": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" } }, "nameMap": { "type": "object", "additionalProperties": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" } }, "requiredNameMap": { "type": "object", "additionalProperties": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" } }, "age": { @@ -62,7 +62,7 @@ "example::Workload": { "properties": { "pod": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:core%2Fv1:Pod" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:core%2Fv1:Pod" } }, "type": "object" @@ -70,52 +70,56 @@ "example::Component": { "properties": { "provider": { - "$ref": "/kubernetes/v2.6.3/schema.json#/provider" + "$ref": "/kubernetes/v3.7.0/schema.json#/provider" }, "securityGroup": { - "$ref": "/aws/v3.14.0/schema.json#/resources/aws:ec2%2FsecurityGroup:SecurityGroup" + "$ref": "/aws/v4.19.0/schema.json#/resources/aws:ec2%2FsecurityGroup:SecurityGroup" }, "storageClasses": { "type": "object", "additionalProperties": { - "$ref": "/kubernetes/v2.7.3/schema.json#/resources/kubernetes:storage.k8s.io%2Fv1:StorageClass" + "$ref": "/kubernetes/v3.7.0/schema.json#/resources/kubernetes:storage.k8s.io%2Fv1:StorageClass" } } }, "inputProperties": { "metadata": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" }, "requiredMetadata": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" }, "metadataArray": { "type": "array", "items": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" } }, "requiredMetadataArray": { "type": "array", "items": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" } }, "metadataMap": { "type": "object", "additionalProperties": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" } }, "requiredMetadataMap": { "type": "object", "additionalProperties": { - "$ref": "/kubernetes/v2.6.3/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" + "$ref": "/kubernetes/v3.7.0/schema.json#/types/kubernetes:meta%2Fv1:ObjectMeta" } } }, "required": ["securityGroup"], - "requiredInputs": ["requiredMetadata", "requiredMetadataArray", "requiredMetadataMap"] + "requiredInputs": [ + "requiredMetadata", + "requiredMetadataArray", + "requiredMetadataMap" + ] } }, "functions": { @@ -123,7 +127,7 @@ "inputs": { "properties": { "name": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + "$ref": "/random/v4.2.0/schema.json#/resources/random:index%2FrandomPet:RandomPet" } } }, @@ -137,11 +141,24 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12", + "Pulumi.Aws": "4.20", + "Pulumi.Kubernetes": "3.7.0", + "Pulumi.Random": "4.2.0" + } + }, "go": { "generateResourceContainerTypes": true }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/random": "^4.2.0", + "@pulumi/aws": "^4.19.0", + "@pulumi/kubernetes": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/input-collision/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/input-collision/dotnet/Pulumi.Example.csproj index b172ade5b..5512aec4e 100644 --- a/pkg/codegen/internal/test/testdata/input-collision/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/input-collision/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/input-collision/nodejs/package.json b/pkg/codegen/internal/test/testdata/input-collision/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/input-collision/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/input-collision/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/input-collision/schema.json b/pkg/codegen/internal/test/testdata/input-collision/schema.json index d5dbb2aed..3a755a008 100644 --- a/pkg/codegen/internal/test/testdata/input-collision/schema.json +++ b/pkg/codegen/internal/test/testdata/input-collision/schema.json @@ -1,6 +1,6 @@ { - "version": "0.0.1", "name": "example", + "version": "0.0.1", "types": { "example::Object": { "properties": { @@ -37,11 +37,22 @@ }, "functions": {}, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.*" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/input-collision/go/example" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/nested-module-thirdparty/dotnet/Pulumi.Foo-bar.csproj b/pkg/codegen/internal/test/testdata/nested-module-thirdparty/dotnet/Pulumi.Foo-bar.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/nested-module-thirdparty/dotnet/Pulumi.Foo-bar.csproj +++ b/pkg/codegen/internal/test/testdata/nested-module-thirdparty/dotnet/Pulumi.Foo-bar.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/nested-module-thirdparty/schema.json b/pkg/codegen/internal/test/testdata/nested-module-thirdparty/schema.json index e8a764785..fce042736 100644 --- a/pkg/codegen/internal/test/testdata/nested-module-thirdparty/schema.json +++ b/pkg/codegen/internal/test/testdata/nested-module-thirdparty/schema.json @@ -24,6 +24,11 @@ "requires": { "pulumi": ">=3.0.0,<4.0.0" } + }, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } } } } diff --git a/pkg/codegen/internal/test/testdata/nested-module/dotnet/Pulumi.Foo.csproj b/pkg/codegen/internal/test/testdata/nested-module/dotnet/Pulumi.Foo.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/nested-module/dotnet/Pulumi.Foo.csproj +++ b/pkg/codegen/internal/test/testdata/nested-module/dotnet/Pulumi.Foo.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/nested-module/schema.json b/pkg/codegen/internal/test/testdata/nested-module/schema.json index 588e78236..d2e46d815 100644 --- a/pkg/codegen/internal/test/testdata/nested-module/schema.json +++ b/pkg/codegen/internal/test/testdata/nested-module/schema.json @@ -19,7 +19,11 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/nested-module/go/foo" }, diff --git a/pkg/codegen/internal/test/testdata/plain-schema-gh6957/nodejs/package.json b/pkg/codegen/internal/test/testdata/plain-schema-gh6957/nodejs/package.json index c6192a3ff..412c0710b 100644 --- a/pkg/codegen/internal/test/testdata/plain-schema-gh6957/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/plain-schema-gh6957/nodejs/package.json @@ -5,14 +5,12 @@ "build": "tsc" }, "dependencies": { - "@pulumi/aws": "^4.0.0" + "@pulumi/aws": "^3.7.0", + "@pulumi/pulumi": "^3.12" }, "devDependencies": { "typescript": "^3.7.0" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" - }, "pulumi": { "resource": true } diff --git a/pkg/codegen/internal/test/testdata/plain-schema-gh6957/schema.json b/pkg/codegen/internal/test/testdata/plain-schema-gh6957/schema.json index 4cbe7b379..c1c2c0044 100644 --- a/pkg/codegen/internal/test/testdata/plain-schema-gh6957/schema.json +++ b/pkg/codegen/internal/test/testdata/plain-schema-gh6957/schema.json @@ -1,71 +1,67 @@ { - "name": "xyz", - "types": { - "example:index:Foo": { - "properties": { - "a": { - "type": "boolean" - } - }, - "type": "object" + "name": "xyz", + "types": { + "example:index:Foo": { + "properties": { + "a": { + "type": "boolean" } }, - "resources": { - "xyz:index:StaticPage": { - "isComponent": true, - "inputProperties": { - "indexContent": { - "type": "string", - "description": "The HTML content for index.html." - }, - "foo": { - "$ref": "#/types/example:index:Foo", - "plain": true - } - }, - "requiredInputs": [ - "indexContent" - ], - "properties": { - "bucket": { - "$ref": "/aws/v4.0.0/schema.json#/resources/aws:s3%2Fbucket:Bucket", - "description": "The bucket resource." - }, - "websiteUrl": { - "type": "string", - "description": "The website URL." - } - }, - "required": [ - "bucket", - "websiteUrl" - ] - } - }, - "language": { - "csharp": { - "packageReferences": { - "Pulumi": "3.*", - "Pulumi.Aws": "4.*" - } - }, - "go": { - "generateResourceContainerTypes": true, - "importBasePath": "github.com/pulumi/pulumi-xyz/sdk/go/xyz" - }, - "nodejs": { - "dependencies": { - "@pulumi/aws": "^4.0.0" - }, - "devDependencies": { - "typescript": "^3.7.0" - } - }, - "python": { - "requires": { - "pulumi": ">=3.0.0,<4.0.0", - "pulumi-aws": ">=4.0.0,<5.0.0" - } - } + "type": "object" } + }, + "resources": { + "xyz:index:StaticPage": { + "isComponent": true, + "inputProperties": { + "indexContent": { + "type": "string", + "description": "The HTML content for index.html." + }, + "foo": { + "$ref": "#/types/example:index:Foo", + "plain": true + } + }, + "requiredInputs": ["indexContent"], + "properties": { + "bucket": { + "$ref": "/aws/v4.0.0/schema.json#/resources/aws:s3%2Fbucket:Bucket", + "description": "The bucket resource." + }, + "websiteUrl": { + "type": "string", + "description": "The website URL." + } + }, + "required": ["bucket", "websiteUrl"] + } + }, + "language": { + "csharp": { + "packageReferences": { + "Pulumi": "3.*", + "Pulumi.Aws": "4.*" + } + }, + "go": { + "generateResourceContainerTypes": true, + "importBasePath": "github.com/pulumi/pulumi-xyz/sdk/go/xyz" + }, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12", + "@pulumi/aws": "^3.7.0" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, + "python": { + "requires": { + "pulumi": ">=3.0.0,<4.0.0", + "pulumi-aws": ">=4.0.0,<5.0.0" + } + } + } } diff --git a/pkg/codegen/internal/test/testdata/provider-config-schema/dotnet/Pulumi.Configstation.csproj b/pkg/codegen/internal/test/testdata/provider-config-schema/dotnet/Pulumi.Configstation.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/provider-config-schema/dotnet/Pulumi.Configstation.csproj +++ b/pkg/codegen/internal/test/testdata/provider-config-schema/dotnet/Pulumi.Configstation.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/provider-config-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/provider-config-schema/nodejs/package.json index c06f7ba28..da59780fc 100644 --- a/pkg/codegen/internal/test/testdata/provider-config-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/provider-config-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/provider-config-schema/schema.json b/pkg/codegen/internal/test/testdata/provider-config-schema/schema.json index 911647bd0..a73eb966e 100644 --- a/pkg/codegen/internal/test/testdata/provider-config-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/provider-config-schema/schema.json @@ -23,10 +23,7 @@ "type": "string", "description": "This is a huge secret", "defaultInfo": { - "environment": [ - "SECRET_CODE", - "MY_SUPER_SECRET_CODE" - ] + "environment": ["SECRET_CODE", "MY_SUPER_SECRET_CODE"] } }, "favoriteSandwich": { @@ -37,9 +34,7 @@ "$ref": "#/types/configstation:index:child" } }, - "defaults": [ - "name" - ] + "defaults": ["name"] }, "types": { "configstation:config:sandwich": { @@ -69,9 +64,20 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": {}, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/docs/norecursive/_index.md b/pkg/codegen/internal/test/testdata/replace-on-change/docs/norecursive/_index.md index 526b3f81d..917b9811c 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/docs/norecursive/_index.md +++ b/pkg/codegen/internal/test/testdata/replace-on-change/docs/norecursive/_index.md @@ -189,7 +189,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Rec - Pulumi.Example.Rec + Rec
{{% md %}}{{% /md %}}
@@ -217,7 +217,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Rec - Rec + Rec
{{% md %}}{{% /md %}}
@@ -245,7 +245,7 @@ All [input](#inputs) properties are implicitly available as output properties. A rec - Rec + Rec
{{% md %}}{{% /md %}}
@@ -273,7 +273,7 @@ All [input](#inputs) properties are implicitly available as output properties. A rec - Rec + Rec
{{% md %}}{{% /md %}}
@@ -292,6 +292,60 @@ All [input](#inputs) properties are implicitly available as output properties. A +## Supporting Types + + + +

Rec

+ +{{% choosable language csharp %}} +
+ +Rec1 + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language go %}} +
+ +Rec1 + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+ +rec1 + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language python %}} +
+ +rec1 + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} +

Package Details

diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/docs/toystore/_index.md b/pkg/codegen/internal/test/testdata/replace-on-change/docs/toystore/_index.md index ddf724076..ba81697ec 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/docs/toystore/_index.md +++ b/pkg/codegen/internal/test/testdata/replace-on-change/docs/toystore/_index.md @@ -189,7 +189,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Chew - Pulumi.Example.Chew + Chew
{{% md %}}{{% /md %}}
@@ -197,7 +197,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Laser - Pulumi.Example.Laser + Laser
{{% md %}}{{% /md %}}
@@ -233,7 +233,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Chew - Chew + Chew
{{% md %}}{{% /md %}}
@@ -241,7 +241,7 @@ All [input](#inputs) properties are implicitly available as output properties. A Laser - Laser + Laser
{{% md %}}{{% /md %}}
@@ -277,7 +277,7 @@ All [input](#inputs) properties are implicitly available as output properties. A chew - Chew + Chew
{{% md %}}{{% /md %}}
@@ -285,7 +285,7 @@ All [input](#inputs) properties are implicitly available as output properties. A laser - Laser + Laser
{{% md %}}{{% /md %}}
@@ -321,7 +321,7 @@ All [input](#inputs) properties are implicitly available as output properties. A chew - Chew + Chew
{{% md %}}{{% /md %}}
@@ -329,7 +329,7 @@ All [input](#inputs) properties are implicitly available as output properties. A laser - Laser + Laser
{{% md %}}{{% /md %}}
@@ -360,6 +360,170 @@ All [input](#inputs) properties are implicitly available as output properties. A +

Chew

+ +{{% choosable language csharp %}} +
+ +Owner + + + Pulumi.Example.Dog +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language go %}} +
+ +Owner + + + Dog +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+ +owner + + + Dog +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language python %}} +
+ +owner + + + Dog +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +

Laser

+ +{{% choosable language csharp %}} +
+ +Animal + + + Pulumi.Example.Cat +
+
{{% md %}}{{% /md %}}
+ +Batteries + + + bool +
+
{{% md %}}{{% /md %}}
+ +Light + + + double +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language go %}} +
+ +Animal + + + Cat +
+
{{% md %}}{{% /md %}}
+ +Batteries + + + bool +
+
{{% md %}}{{% /md %}}
+ +Light + + + float64 +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+ +animal + + + Cat +
+
{{% md %}}{{% /md %}}
+ +batteries + + + boolean +
+
{{% md %}}{{% /md %}}
+ +light + + + number +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language python %}} +
+ +animal + + + Cat +
+
{{% md %}}{{% /md %}}
+ +batteries + + + bool +
+
{{% md %}}{{% /md %}}
+ +light + + + float +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} +

Toy

{{% choosable language csharp %}} diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/NoRecursive.cs b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/NoRecursive.cs index c99e9ab72..0333547e1 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/NoRecursive.cs +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/NoRecursive.cs @@ -13,7 +13,7 @@ namespace Pulumi.Example public partial class NoRecursive : Pulumi.CustomResource { [Output("rec")] - public Output Rec { get; private set; } = null!; + public Output Rec { get; private set; } = null!; [Output("replace")] public Output Replace { get; private set; } = null!; diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Chew.cs b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Chew.cs new file mode 100644 index 000000000..6385e69b9 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Chew.cs @@ -0,0 +1,27 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Example.Outputs +{ + + /// + /// A toy for a dog + /// + [OutputType] + public sealed class Chew + { + public readonly Pulumi.Example.Dog? Owner; + + [OutputConstructor] + private Chew(Pulumi.Example.Dog? owner) + { + Owner = owner; + } + } +} diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Laser.cs b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Laser.cs new file mode 100644 index 000000000..0abca7920 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Laser.cs @@ -0,0 +1,36 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Example.Outputs +{ + + /// + /// A Toy for a cat + /// + [OutputType] + public sealed class Laser + { + public readonly Pulumi.Example.Cat? Animal; + public readonly bool? Batteries; + public readonly double? Light; + + [OutputConstructor] + private Laser( + Pulumi.Example.Cat? animal, + + bool? batteries, + + double? light) + { + Animal = animal; + Batteries = batteries; + Light = light; + } + } +} diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Rec.cs b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Rec.cs new file mode 100644 index 000000000..33c3e3292 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Outputs/Rec.cs @@ -0,0 +1,24 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Example.Outputs +{ + + [OutputType] + public sealed class Rec + { + public readonly Outputs.Rec? Rec1; + + [OutputConstructor] + private Rec(Outputs.Rec? rec1) + { + Rec1 = rec1; + } + } +} diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/ToyStore.cs b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/ToyStore.cs index 8b75e9118..707b21498 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/ToyStore.cs +++ b/pkg/codegen/internal/test/testdata/replace-on-change/dotnet/ToyStore.cs @@ -13,10 +13,10 @@ namespace Pulumi.Example public partial class ToyStore : Pulumi.CustomResource { [Output("chew")] - public Output Chew { get; private set; } = null!; + public Output Chew { get; private set; } = null!; [Output("laser")] - public Output Laser { get; private set; } = null!; + public Output Laser { get; private set; } = null!; [Output("stuff")] public Output> Stuff { get; private set; } = null!; @@ -49,6 +49,8 @@ namespace Pulumi.Example Version = Utilities.Version, ReplaceOnChanges = { + "chew.owner", + "laser.batteries", "stuff[*].associated.color", "stuff[*].color", "wanted[*]", diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/noRecursive.go b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/noRecursive.go index b1b8b871d..ee58d9c1b 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/noRecursive.go +++ b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/noRecursive.go @@ -13,7 +13,7 @@ import ( type NoRecursive struct { pulumi.CustomResourceState - Rec RecOutput `pulumi:"rec"` + Rec RecPtrOutput `pulumi:"rec"` Replace pulumi.StringPtrOutput `pulumi:"replace"` } diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/pulumiTypes.go b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/pulumiTypes.go index cfc513183..0dc64b509 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/pulumiTypes.go +++ b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/pulumiTypes.go @@ -43,6 +43,47 @@ func (i ChewArgs) ToChewOutputWithContext(ctx context.Context) ChewOutput { return pulumi.ToOutputWithContext(ctx, i).(ChewOutput) } +func (i ChewArgs) ToChewPtrOutput() ChewPtrOutput { + return i.ToChewPtrOutputWithContext(context.Background()) +} + +func (i ChewArgs) ToChewPtrOutputWithContext(ctx context.Context) ChewPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(ChewOutput).ToChewPtrOutputWithContext(ctx) +} + +// ChewPtrInput is an input type that accepts ChewArgs, ChewPtr and ChewPtrOutput values. +// You can construct a concrete instance of `ChewPtrInput` via: +// +// ChewArgs{...} +// +// or: +// +// nil +type ChewPtrInput interface { + pulumi.Input + + ToChewPtrOutput() ChewPtrOutput + ToChewPtrOutputWithContext(context.Context) ChewPtrOutput +} + +type chewPtrType ChewArgs + +func ChewPtr(v *ChewArgs) ChewPtrInput { + return (*chewPtrType)(v) +} + +func (*chewPtrType) ElementType() reflect.Type { + return reflect.TypeOf((**Chew)(nil)).Elem() +} + +func (i *chewPtrType) ToChewPtrOutput() ChewPtrOutput { + return i.ToChewPtrOutputWithContext(context.Background()) +} + +func (i *chewPtrType) ToChewPtrOutputWithContext(ctx context.Context) ChewPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(ChewPtrOutput) +} + // A toy for a dog type ChewOutput struct{ *pulumi.OutputState } @@ -58,10 +99,53 @@ func (o ChewOutput) ToChewOutputWithContext(ctx context.Context) ChewOutput { return o } +func (o ChewOutput) ToChewPtrOutput() ChewPtrOutput { + return o.ToChewPtrOutputWithContext(context.Background()) +} + +func (o ChewOutput) ToChewPtrOutputWithContext(ctx context.Context) ChewPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v Chew) *Chew { + return &v + }).(ChewPtrOutput) +} + func (o ChewOutput) Owner() DogOutput { return o.ApplyT(func(v Chew) *Dog { return v.Owner }).(DogOutput) } +type ChewPtrOutput struct{ *pulumi.OutputState } + +func (ChewPtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**Chew)(nil)).Elem() +} + +func (o ChewPtrOutput) ToChewPtrOutput() ChewPtrOutput { + return o +} + +func (o ChewPtrOutput) ToChewPtrOutputWithContext(ctx context.Context) ChewPtrOutput { + return o +} + +func (o ChewPtrOutput) Elem() ChewOutput { + return o.ApplyT(func(v *Chew) Chew { + if v != nil { + return *v + } + var ret Chew + return ret + }).(ChewOutput) +} + +func (o ChewPtrOutput) Owner() DogOutput { + return o.ApplyT(func(v *Chew) *Dog { + if v == nil { + return nil + } + return v.Owner + }).(DogOutput) +} + // A Toy for a cat type Laser struct { Animal *Cat `pulumi:"animal"` @@ -99,6 +183,47 @@ func (i LaserArgs) ToLaserOutputWithContext(ctx context.Context) LaserOutput { return pulumi.ToOutputWithContext(ctx, i).(LaserOutput) } +func (i LaserArgs) ToLaserPtrOutput() LaserPtrOutput { + return i.ToLaserPtrOutputWithContext(context.Background()) +} + +func (i LaserArgs) ToLaserPtrOutputWithContext(ctx context.Context) LaserPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(LaserOutput).ToLaserPtrOutputWithContext(ctx) +} + +// LaserPtrInput is an input type that accepts LaserArgs, LaserPtr and LaserPtrOutput values. +// You can construct a concrete instance of `LaserPtrInput` via: +// +// LaserArgs{...} +// +// or: +// +// nil +type LaserPtrInput interface { + pulumi.Input + + ToLaserPtrOutput() LaserPtrOutput + ToLaserPtrOutputWithContext(context.Context) LaserPtrOutput +} + +type laserPtrType LaserArgs + +func LaserPtr(v *LaserArgs) LaserPtrInput { + return (*laserPtrType)(v) +} + +func (*laserPtrType) ElementType() reflect.Type { + return reflect.TypeOf((**Laser)(nil)).Elem() +} + +func (i *laserPtrType) ToLaserPtrOutput() LaserPtrOutput { + return i.ToLaserPtrOutputWithContext(context.Background()) +} + +func (i *laserPtrType) ToLaserPtrOutputWithContext(ctx context.Context) LaserPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(LaserPtrOutput) +} + // A Toy for a cat type LaserOutput struct{ *pulumi.OutputState } @@ -114,6 +239,16 @@ func (o LaserOutput) ToLaserOutputWithContext(ctx context.Context) LaserOutput { return o } +func (o LaserOutput) ToLaserPtrOutput() LaserPtrOutput { + return o.ToLaserPtrOutputWithContext(context.Background()) +} + +func (o LaserOutput) ToLaserPtrOutputWithContext(ctx context.Context) LaserPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v Laser) *Laser { + return &v + }).(LaserPtrOutput) +} + func (o LaserOutput) Animal() CatOutput { return o.ApplyT(func(v Laser) *Cat { return v.Animal }).(CatOutput) } @@ -126,8 +261,59 @@ func (o LaserOutput) Light() pulumi.Float64PtrOutput { return o.ApplyT(func(v Laser) *float64 { return v.Light }).(pulumi.Float64PtrOutput) } +type LaserPtrOutput struct{ *pulumi.OutputState } + +func (LaserPtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**Laser)(nil)).Elem() +} + +func (o LaserPtrOutput) ToLaserPtrOutput() LaserPtrOutput { + return o +} + +func (o LaserPtrOutput) ToLaserPtrOutputWithContext(ctx context.Context) LaserPtrOutput { + return o +} + +func (o LaserPtrOutput) Elem() LaserOutput { + return o.ApplyT(func(v *Laser) Laser { + if v != nil { + return *v + } + var ret Laser + return ret + }).(LaserOutput) +} + +func (o LaserPtrOutput) Animal() CatOutput { + return o.ApplyT(func(v *Laser) *Cat { + if v == nil { + return nil + } + return v.Animal + }).(CatOutput) +} + +func (o LaserPtrOutput) Batteries() pulumi.BoolPtrOutput { + return o.ApplyT(func(v *Laser) *bool { + if v == nil { + return nil + } + return v.Batteries + }).(pulumi.BoolPtrOutput) +} + +func (o LaserPtrOutput) Light() pulumi.Float64PtrOutput { + return o.ApplyT(func(v *Laser) *float64 { + if v == nil { + return nil + } + return v.Light + }).(pulumi.Float64PtrOutput) +} + type Rec struct { - Rec *Rec `pulumi:"rec"` + Rec1 *Rec `pulumi:"rec1"` } // RecInput is an input type that accepts RecArgs and RecOutput values. @@ -142,7 +328,7 @@ type RecInput interface { } type RecArgs struct { - Rec RecInput `pulumi:"rec"` + Rec1 RecPtrInput `pulumi:"rec1"` } func (RecArgs) ElementType() reflect.Type { @@ -157,6 +343,47 @@ func (i RecArgs) ToRecOutputWithContext(ctx context.Context) RecOutput { return pulumi.ToOutputWithContext(ctx, i).(RecOutput) } +func (i RecArgs) ToRecPtrOutput() RecPtrOutput { + return i.ToRecPtrOutputWithContext(context.Background()) +} + +func (i RecArgs) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecOutput).ToRecPtrOutputWithContext(ctx) +} + +// RecPtrInput is an input type that accepts RecArgs, RecPtr and RecPtrOutput values. +// You can construct a concrete instance of `RecPtrInput` via: +// +// RecArgs{...} +// +// or: +// +// nil +type RecPtrInput interface { + pulumi.Input + + ToRecPtrOutput() RecPtrOutput + ToRecPtrOutputWithContext(context.Context) RecPtrOutput +} + +type recPtrType RecArgs + +func RecPtr(v *RecArgs) RecPtrInput { + return (*recPtrType)(v) +} + +func (*recPtrType) ElementType() reflect.Type { + return reflect.TypeOf((**Rec)(nil)).Elem() +} + +func (i *recPtrType) ToRecPtrOutput() RecPtrOutput { + return i.ToRecPtrOutputWithContext(context.Background()) +} + +func (i *recPtrType) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecPtrOutput) +} + type RecOutput struct{ *pulumi.OutputState } func (RecOutput) ElementType() reflect.Type { @@ -171,8 +398,51 @@ func (o RecOutput) ToRecOutputWithContext(ctx context.Context) RecOutput { return o } -func (o RecOutput) Rec() RecOutput { - return o.ApplyT(func(v Rec) *Rec { return v.Rec }).(RecOutput) +func (o RecOutput) ToRecPtrOutput() RecPtrOutput { + return o.ToRecPtrOutputWithContext(context.Background()) +} + +func (o RecOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v Rec) *Rec { + return &v + }).(RecPtrOutput) +} + +func (o RecOutput) Rec1() RecPtrOutput { + return o.ApplyT(func(v Rec) *Rec { return v.Rec1 }).(RecPtrOutput) +} + +type RecPtrOutput struct{ *pulumi.OutputState } + +func (RecPtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**Rec)(nil)).Elem() +} + +func (o RecPtrOutput) ToRecPtrOutput() RecPtrOutput { + return o +} + +func (o RecPtrOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return o +} + +func (o RecPtrOutput) Elem() RecOutput { + return o.ApplyT(func(v *Rec) Rec { + if v != nil { + return *v + } + var ret Rec + return ret + }).(RecOutput) +} + +func (o RecPtrOutput) Rec1() RecPtrOutput { + return o.ApplyT(func(v *Rec) *Rec { + if v == nil { + return nil + } + return v.Rec1 + }).(RecPtrOutput) } // This is a toy @@ -433,8 +703,11 @@ func (o ToyMapOutput) MapIndex(k pulumi.StringInput) ToyOutput { func init() { pulumi.RegisterOutputType(ChewOutput{}) + pulumi.RegisterOutputType(ChewPtrOutput{}) pulumi.RegisterOutputType(LaserOutput{}) + pulumi.RegisterOutputType(LaserPtrOutput{}) pulumi.RegisterOutputType(RecOutput{}) + pulumi.RegisterOutputType(RecPtrOutput{}) pulumi.RegisterOutputType(ToyOutput{}) pulumi.RegisterOutputType(ToyPtrOutput{}) pulumi.RegisterOutputType(ToyArrayOutput{}) diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/toyStore.go b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/toyStore.go index d17c03fb6..211e47bab 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/go/example/toyStore.go +++ b/pkg/codegen/internal/test/testdata/replace-on-change/go/example/toyStore.go @@ -13,8 +13,8 @@ import ( type ToyStore struct { pulumi.CustomResourceState - Chew ChewOutput `pulumi:"chew"` - Laser LaserOutput `pulumi:"laser"` + Chew ChewPtrOutput `pulumi:"chew"` + Laser LaserPtrOutput `pulumi:"laser"` Stuff ToyArrayOutput `pulumi:"stuff"` Wanted ToyArrayOutput `pulumi:"wanted"` } @@ -27,6 +27,8 @@ func NewToyStore(ctx *pulumi.Context, } replaceOnChanges := pulumi.ReplaceOnChanges([]string{ + "chew.owner", + "laser.batteries", "stuff[*].associated.color", "stuff[*].color", "wanted[*]", diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/noRecursive.ts b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/noRecursive.ts index 60414b095..0cf9b0acd 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/noRecursive.ts +++ b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/noRecursive.ts @@ -2,6 +2,7 @@ // *** Do not edit by hand unless you're certain you know what you are doing! *** import * as pulumi from "@pulumi/pulumi"; +import { input as inputs, output as outputs } from "./types"; import * as utilities from "./utilities"; export class NoRecursive extends pulumi.CustomResource { @@ -31,7 +32,7 @@ export class NoRecursive extends pulumi.CustomResource { return obj['__pulumiType'] === NoRecursive.__pulumiType; } - public /*out*/ readonly rec!: pulumi.Output; + public /*out*/ readonly rec!: pulumi.Output; public /*out*/ readonly replace!: pulumi.Output; /** diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/package.json b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/toyStore.ts b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/toyStore.ts index 3447012c6..29fa793ee 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/toyStore.ts +++ b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/toyStore.ts @@ -5,6 +5,8 @@ import * as pulumi from "@pulumi/pulumi"; import { input as inputs, output as outputs } from "./types"; import * as utilities from "./utilities"; +import {Cat, Dog} from "./index"; + export class ToyStore extends pulumi.CustomResource { /** * Get an existing ToyStore resource's state with the given name, ID, and optional extra @@ -32,8 +34,8 @@ export class ToyStore extends pulumi.CustomResource { return obj['__pulumiType'] === ToyStore.__pulumiType; } - public /*out*/ readonly chew!: pulumi.Output; - public /*out*/ readonly laser!: pulumi.Output; + public /*out*/ readonly chew!: pulumi.Output; + public /*out*/ readonly laser!: pulumi.Output; public /*out*/ readonly stuff!: pulumi.Output; public /*out*/ readonly wanted!: pulumi.Output; @@ -61,7 +63,7 @@ export class ToyStore extends pulumi.CustomResource { if (!opts.version) { opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()}); } - const replaceOnChanges = { replaceOnChanges: ["stuff[*].associated.color", "stuff[*].color", "wanted[*]"] }; + const replaceOnChanges = { replaceOnChanges: ["chew.owner", "laser.batteries", "stuff[*].associated.color", "stuff[*].color", "wanted[*]"] }; opts = pulumi.mergeOptions(opts, replaceOnChanges); super(ToyStore.__pulumiType, name, inputs, opts); } diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/types/output.ts b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/types/output.ts index b94ee636e..53c9ec500 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/types/output.ts +++ b/pkg/codegen/internal/test/testdata/replace-on-change/nodejs/types/output.ts @@ -6,6 +6,26 @@ import { input as inputs, output as outputs } from "../types"; import {Cat, Dog} from ".."; +/** + * A toy for a dog + */ +export interface Chew { + owner?: Dog; +} + +/** + * A Toy for a cat + */ +export interface Laser { + animal?: Cat; + batteries?: boolean; + light?: number; +} + +export interface Rec { + rec1?: outputs.Rec; +} + /** * This is a toy */ diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/no_recursive.py b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/no_recursive.py index 01deb952c..719bbd763 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/no_recursive.py +++ b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/no_recursive.py @@ -7,7 +7,7 @@ import pulumi import pulumi.runtime from typing import Any, Mapping, Optional, Sequence, Union, overload from . import _utilities -from .rec import Rec +from . import outputs __all__ = ['NoRecursiveArgs', 'NoRecursive'] @@ -98,7 +98,7 @@ class NoRecursive(pulumi.CustomResource): @property @pulumi.getter - def rec(self) -> pulumi.Output[Optional['Rec']]: + def rec(self) -> pulumi.Output[Optional['outputs.Rec']]: return pulumi.get(self, "rec") @property diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/outputs.py b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/outputs.py index 27d1d8ec9..9c60ce67a 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/outputs.py +++ b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/outputs.py @@ -8,11 +8,83 @@ import pulumi.runtime from typing import Any, Mapping, Optional, Sequence, Union, overload from . import _utilities from . import outputs +from .cat import Cat +from .dog import Dog __all__ = [ + 'Chew', + 'Laser', + 'Rec', 'Toy', ] +@pulumi.output_type +class Chew(dict): + """ + A toy for a dog + """ + def __init__(__self__, *, + owner: Optional['Dog'] = None): + """ + A toy for a dog + """ + if owner is not None: + pulumi.set(__self__, "owner", owner) + + @property + @pulumi.getter + def owner(self) -> Optional['Dog']: + return pulumi.get(self, "owner") + + +@pulumi.output_type +class Laser(dict): + """ + A Toy for a cat + """ + def __init__(__self__, *, + animal: Optional['Cat'] = None, + batteries: Optional[bool] = None, + light: Optional[float] = None): + """ + A Toy for a cat + """ + if animal is not None: + pulumi.set(__self__, "animal", animal) + if batteries is not None: + pulumi.set(__self__, "batteries", batteries) + if light is not None: + pulumi.set(__self__, "light", light) + + @property + @pulumi.getter + def animal(self) -> Optional['Cat']: + return pulumi.get(self, "animal") + + @property + @pulumi.getter + def batteries(self) -> Optional[bool]: + return pulumi.get(self, "batteries") + + @property + @pulumi.getter + def light(self) -> Optional[float]: + return pulumi.get(self, "light") + + +@pulumi.output_type +class Rec(dict): + def __init__(__self__, *, + rec1: Optional['outputs.Rec'] = None): + if rec1 is not None: + pulumi.set(__self__, "rec1", rec1) + + @property + @pulumi.getter + def rec1(self) -> Optional['outputs.Rec']: + return pulumi.get(self, "rec1") + + @pulumi.output_type class Toy(dict): """ diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/toy_store.py b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/toy_store.py index 0b8e6c29a..993eb84a0 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/toy_store.py +++ b/pkg/codegen/internal/test/testdata/replace-on-change/python/pulumi_example/toy_store.py @@ -8,8 +8,8 @@ import pulumi.runtime from typing import Any, Mapping, Optional, Sequence, Union, overload from . import _utilities from . import outputs -from .chew import Chew -from .laser import Laser +from .cat import Cat +from .dog import Dog __all__ = ['ToyStoreArgs', 'ToyStore'] @@ -72,7 +72,7 @@ class ToyStore(pulumi.CustomResource): __props__.__dict__["laser"] = None __props__.__dict__["stuff"] = None __props__.__dict__["wanted"] = None - replace_on_changes = pulumi.ResourceOptions(replace_on_changes=["stuff[*].associated.color", "stuff[*].color", "wanted[*]"]) + replace_on_changes = pulumi.ResourceOptions(replace_on_changes=["chew.owner", "laser.batteries", "stuff[*].associated.color", "stuff[*].color", "wanted[*]"]) opts = pulumi.ResourceOptions.merge(opts, replace_on_changes) super(ToyStore, __self__).__init__( 'example::ToyStore', @@ -104,12 +104,12 @@ class ToyStore(pulumi.CustomResource): @property @pulumi.getter - def chew(self) -> pulumi.Output[Optional['Chew']]: + def chew(self) -> pulumi.Output[Optional['outputs.Chew']]: return pulumi.get(self, "chew") @property @pulumi.getter - def laser(self) -> pulumi.Output[Optional['Laser']]: + def laser(self) -> pulumi.Output[Optional['outputs.Laser']]: return pulumi.get(self, "laser") @property diff --git a/pkg/codegen/internal/test/testdata/replace-on-change/schema.json b/pkg/codegen/internal/test/testdata/replace-on-change/schema.json index f597353c9..42da7625a 100644 --- a/pkg/codegen/internal/test/testdata/replace-on-change/schema.json +++ b/pkg/codegen/internal/test/testdata/replace-on-change/schema.json @@ -5,7 +5,7 @@ "example::NoRecursive": { "properties": { "rec": { - "$ref": "#/resources/example::Rec" + "$ref": "#/types/example::Rec" }, "replace": { "type": "string", @@ -16,10 +16,10 @@ "example::ToyStore": { "properties": { "chew": { - "$ref": "#/resources/example::Chew" + "$ref": "#/types/example::Chew" }, "laser": { - "$ref": "#/resources/example::Laser" + "$ref": "#/types/example::Laser" }, "stuff": { "type": "array", @@ -126,18 +126,29 @@ "example::Rec": { "type": "object", "properties": { - "rec": { - "$ref": "#/resources/example::Rec" + "rec1": { + "$ref": "#/types/example::Rec" } } } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "generateResourceContainerTypes": true }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/resource-args-python/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/resource-args-python/dotnet/Pulumi.Example.csproj index b172ade5b..8304f7df2 100644 --- a/pkg/codegen/internal/test/testdata/resource-args-python/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/resource-args-python/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json b/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/resource-args-python/schema.json b/pkg/codegen/internal/test/testdata/resource-args-python/schema.json index 1799f0c11..55e963b77 100644 --- a/pkg/codegen/internal/test/testdata/resource-args-python/schema.json +++ b/pkg/codegen/internal/test/testdata/resource-args-python/schema.json @@ -52,11 +52,22 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12.0" + } + }, "go": { "generateResourceContainerTypes": true }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md new file mode 100644 index 000000000..7ab5533fd --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md @@ -0,0 +1,30 @@ +--- +title: "example" +title_tag: "example.example" +meta_desc: "" +menu: + reference: + parent: API Reference +--- + + + + + + +

Resources

+ + +

Package Details

+
+
Repository
+
+
License
+
+
Version
+
0.0.1
+
+ diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md new file mode 100644 index 000000000..15bd29e34 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md @@ -0,0 +1,239 @@ + +--- +title: "Provider" +title_tag: "example.Provider" +meta_desc: "Documentation for the example.Provider resource with examples, input properties, output properties, lookup functions, and supporting types." +--- + + + + + + + + + +## Create a Provider Resource {#create} +{{< chooser language "typescript,python,go,csharp" / >}} + + +{{% choosable language nodejs %}} +
new Provider(name: string, args?: ProviderArgs, opts?: CustomResourceOptions);
+{{% /choosable %}} + +{{% choosable language python %}} +
@overload
+def Provider(resource_name: str,
+             opts: Optional[ResourceOptions] = None)
+@overload
+def Provider(resource_name: str,
+             args: Optional[ProviderArgs] = None,
+             opts: Optional[ResourceOptions] = None)
+{{% /choosable %}} + +{{% choosable language go %}} +
func NewProvider(ctx *Context, name string, args *ProviderArgs, opts ...ResourceOption) (*Provider, error)
+{{% /choosable %}} + +{{% choosable language csharp %}} +
public Provider(string name, ProviderArgs? args = null, CustomResourceOptions? opts = null)
+{{% /choosable %}} + +{{% choosable language nodejs %}} + +
+ name + + string +
+
The unique name of the resource.
+ args + + ProviderArgs +
+
The arguments to resource properties.
+ opts + + CustomResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language python %}} + +
+ resource_name + + str +
+
The unique name of the resource.
+ args + + ProviderArgs +
+
The arguments to resource properties.
+ opts + + ResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language go %}} + +
+ ctx + + Context +
+
Context object for the current deployment.
+ name + + string +
+
The unique name of the resource.
+ args + + ProviderArgs +
+
The arguments to resource properties.
+ opts + + ResourceOption +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language csharp %}} + +
+ name + + string +
+
The unique name of the resource.
+ args + + ProviderArgs +
+
The arguments to resource properties.
+ opts + + CustomResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +## Provider Resource Properties {#properties} + +To learn more about resource properties and how to use them, see [Inputs and Outputs]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) in the Architecture and Concepts docs. + +### Inputs + +The Provider resource accepts the following [input]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) properties: + + + +{{% choosable language csharp %}} +
+{{% /choosable %}} + +{{% choosable language go %}} +
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+{{% /choosable %}} + +{{% choosable language python %}} +
+{{% /choosable %}} + + +### Outputs + +All [input](#inputs) properties are implicitly available as output properties. Additionally, the Provider resource produces the following output properties: + + + +{{% choosable language csharp %}} +
+ +Id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}} + +{{% choosable language go %}} +
+ +Id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+ +id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}} + +{{% choosable language python %}} +
+ +id + + + str +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}} + + + + + + + + +

Package Details

+
+
Repository
+
+
License
+
+
+ diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md new file mode 100644 index 000000000..fcf15621a --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md @@ -0,0 +1,271 @@ + +--- +title: "Rec" +title_tag: "example.Rec" +meta_desc: "Documentation for the example.Rec resource with examples, input properties, output properties, lookup functions, and supporting types." +--- + + + + + + + + + +## Create a Rec Resource {#create} +{{< chooser language "typescript,python,go,csharp" / >}} + + +{{% choosable language nodejs %}} +
new Rec(name: string, args?: RecArgs, opts?: CustomResourceOptions);
+{{% /choosable %}} + +{{% choosable language python %}} +
@overload
+def Rec(resource_name: str,
+        opts: Optional[ResourceOptions] = None)
+@overload
+def Rec(resource_name: str,
+        args: Optional[RecArgs] = None,
+        opts: Optional[ResourceOptions] = None)
+{{% /choosable %}} + +{{% choosable language go %}} +
func NewRec(ctx *Context, name string, args *RecArgs, opts ...ResourceOption) (*Rec, error)
+{{% /choosable %}} + +{{% choosable language csharp %}} +
public Rec(string name, RecArgs? args = null, CustomResourceOptions? opts = null)
+{{% /choosable %}} + +{{% choosable language nodejs %}} + +
+ name + + string +
+
The unique name of the resource.
+ args + + RecArgs +
+
The arguments to resource properties.
+ opts + + CustomResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language python %}} + +
+ resource_name + + str +
+
The unique name of the resource.
+ args + + RecArgs +
+
The arguments to resource properties.
+ opts + + ResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language go %}} + +
+ ctx + + Context +
+
Context object for the current deployment.
+ name + + string +
+
The unique name of the resource.
+ args + + RecArgs +
+
The arguments to resource properties.
+ opts + + ResourceOption +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +{{% choosable language csharp %}} + +
+ name + + string +
+
The unique name of the resource.
+ args + + RecArgs +
+
The arguments to resource properties.
+ opts + + CustomResourceOptions +
+
Bag of options to control resource's behavior.
+ +{{% /choosable %}} + +## Rec Resource Properties {#properties} + +To learn more about resource properties and how to use them, see [Inputs and Outputs]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) in the Architecture and Concepts docs. + +### Inputs + +The Rec resource accepts the following [input]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) properties: + + + +{{% choosable language csharp %}} +
+{{% /choosable %}} + +{{% choosable language go %}} +
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+{{% /choosable %}} + +{{% choosable language python %}} +
+{{% /choosable %}} + + +### Outputs + +All [input](#inputs) properties are implicitly available as output properties. Additionally, the Rec resource produces the following output properties: + + + +{{% choosable language csharp %}} +
+ +Id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+ +Rec + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language go %}} +
+ +Id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+ +Rec + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language nodejs %}} +
+ +id + + + string +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+ +rec + + + Rec +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + +{{% choosable language python %}} +
+ +id + + + str +
+
{{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+ +rec + + + Any +
+
{{% md %}}{{% /md %}}
+{{% /choosable %}} + + + + + + + + +

Package Details

+
+
Repository
+
+
License
+
+
+ diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs new file mode 100644 index 000000000..d730dadcd --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs @@ -0,0 +1,46 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Example +{ + [ExampleResourceType("pulumi:providers:example")] + public partial class Provider : Pulumi.ProviderResource + { + /// + /// Create a Provider resource with the given unique name, arguments, and options. + /// + /// + /// The unique name of the resource + /// The arguments used to populate this resource's properties + /// A bag of options that control this resource's behavior + public Provider(string name, ProviderArgs? args = null, CustomResourceOptions? options = null) + : base("example", name, args ?? new ProviderArgs(), MakeResourceOptions(options, "")) + { + } + + private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? options, Input? id) + { + var defaultOptions = new CustomResourceOptions + { + Version = Utilities.Version, + }; + var merged = CustomResourceOptions.Merge(defaultOptions, options); + // Override the ID if one was specified for consistency with other language SDKs. + merged.Id = id ?? merged.Id; + return merged; + } + } + + public sealed class ProviderArgs : Pulumi.ResourceArgs + { + public ProviderArgs() + { + } + } +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj new file mode 100644 index 000000000..6d53245f3 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj @@ -0,0 +1,53 @@ + + + + true + Pulumi Corp. + Pulumi Corp. + + + + + logo.png + + netcoreapp3.1 + enable + false + + + + true + 1701;1702;1591 + + + + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true + true + + + + true + + + + + + + + + + + + + + + + + + True + + + + + diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs new file mode 100644 index 000000000..c5a8e2480 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs @@ -0,0 +1,67 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Example +{ + [ExampleResourceType("example::Rec")] + public partial class Rec : Pulumi.CustomResource + { + [Output("rec")] + public Output Rec { get; private set; } = null!; + + + /// + /// Create a Rec resource with the given unique name, arguments, and options. + /// + /// + /// The unique name of the resource + /// The arguments used to populate this resource's properties + /// A bag of options that control this resource's behavior + public Rec(string name, RecArgs? args = null, CustomResourceOptions? options = null) + : base("example::Rec", name, args ?? new RecArgs(), MakeResourceOptions(options, "")) + { + } + + private Rec(string name, Input id, CustomResourceOptions? options = null) + : base("example::Rec", name, null, MakeResourceOptions(options, id)) + { + } + + private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? options, Input? id) + { + var defaultOptions = new CustomResourceOptions + { + Version = Utilities.Version, + }; + var merged = CustomResourceOptions.Merge(defaultOptions, options); + // Override the ID if one was specified for consistency with other language SDKs. + merged.Id = id ?? merged.Id; + return merged; + } + /// + /// Get an existing Rec resource's state with the given name, ID, and optional extra + /// properties used to qualify the lookup. + /// + /// + /// The unique name of the resulting resource. + /// The unique provider ID of the resource to lookup. + /// A bag of options that control this resource's behavior + public static Rec Get(string name, Input id, CustomResourceOptions? options = null) + { + return new Rec(name, id, options); + } + } + + public sealed class RecArgs : Pulumi.ResourceArgs + { + public RecArgs() + { + } + } +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs new file mode 100644 index 000000000..e99f7fe43 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs @@ -0,0 +1,87 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.IO; +using System.Reflection; +using Pulumi; + +namespace Pulumi.Example +{ + static class Utilities + { + public static string? GetEnv(params string[] names) + { + foreach (var n in names) + { + var value = Environment.GetEnvironmentVariable(n); + if (value != null) + { + return value; + } + } + return null; + } + + static string[] trueValues = { "1", "t", "T", "true", "TRUE", "True" }; + static string[] falseValues = { "0", "f", "F", "false", "FALSE", "False" }; + public static bool? GetEnvBoolean(params string[] names) + { + var s = GetEnv(names); + if (s != null) + { + if (Array.IndexOf(trueValues, s) != -1) + { + return true; + } + if (Array.IndexOf(falseValues, s) != -1) + { + return false; + } + } + return null; + } + + public static int? GetEnvInt32(params string[] names) => int.TryParse(GetEnv(names), out int v) ? (int?)v : null; + + public static double? GetEnvDouble(params string[] names) => double.TryParse(GetEnv(names), out double v) ? (double?)v : null; + + public static InvokeOptions WithVersion(this InvokeOptions? options) + { + if (options?.Version != null) + { + return options; + } + return new InvokeOptions + { + Parent = options?.Parent, + Provider = options?.Provider, + Version = Version, + }; + } + + private readonly static string version; + public static string Version => version; + + static Utilities() + { + var assembly = typeof(Utilities).GetTypeInfo().Assembly; + using var stream = assembly.GetManifestResourceStream("Pulumi.Example.version.txt"); + using var reader = new StreamReader(stream ?? throw new NotSupportedException("Missing embedded version.txt file")); + version = reader.ReadToEnd().Trim(); + var parts = version.Split("\n"); + if (parts.Length == 2) + { + // The first part is the provider name. + version = parts[1].Trim(); + } + } + } + + internal sealed class ExampleResourceTypeAttribute : Pulumi.ResourceTypeAttribute + { + public ExampleResourceTypeAttribute(string type) : base(type, Utilities.Version) + { + } + } +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png new file mode 100644 index 000000000..181f421e9 Binary files /dev/null and b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png differ diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go new file mode 100644 index 000000000..24cd778aa --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go @@ -0,0 +1,3 @@ +// Package example exports types, functions, subpackages for provisioning example resources. +// +package example diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go new file mode 100644 index 000000000..bba613c6f --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go @@ -0,0 +1,65 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package example + +import ( + "fmt" + + "github.com/blang/semver" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type module struct { + version semver.Version +} + +func (m *module) Version() semver.Version { + return m.version +} + +func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi.Resource, err error) { + switch typ { + case "example::Rec": + r = &Rec{} + default: + return nil, fmt.Errorf("unknown resource type: %s", typ) + } + + err = ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn)) + return +} + +type pkg struct { + version semver.Version +} + +func (p *pkg) Version() semver.Version { + return p.version +} + +func (p *pkg) ConstructProvider(ctx *pulumi.Context, name, typ, urn string) (pulumi.ProviderResource, error) { + if typ != "pulumi:providers:example" { + return nil, fmt.Errorf("unknown provider type: %s", typ) + } + + r := &Provider{} + err := ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn)) + return r, err +} + +func init() { + version, err := PkgVersion() + if err != nil { + fmt.Printf("failed to determine package version. defaulting to v1: %v\n", err) + } + pulumi.RegisterResourceModule( + "example", + "", + &module{version}, + ) + pulumi.RegisterResourcePackage( + "example", + &pkg{version}, + ) +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go new file mode 100644 index 000000000..3d9e18032 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go @@ -0,0 +1,142 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package example + +import ( + "context" + "reflect" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type Provider struct { + pulumi.ProviderResourceState +} + +// NewProvider registers a new resource with the given unique name, arguments, and options. +func NewProvider(ctx *pulumi.Context, + name string, args *ProviderArgs, opts ...pulumi.ResourceOption) (*Provider, error) { + if args == nil { + args = &ProviderArgs{} + } + + var resource Provider + err := ctx.RegisterResource("pulumi:providers:example", name, args, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +type providerArgs struct { +} + +// The set of arguments for constructing a Provider resource. +type ProviderArgs struct { +} + +func (ProviderArgs) ElementType() reflect.Type { + return reflect.TypeOf((*providerArgs)(nil)).Elem() +} + +type ProviderInput interface { + pulumi.Input + + ToProviderOutput() ProviderOutput + ToProviderOutputWithContext(ctx context.Context) ProviderOutput +} + +func (*Provider) ElementType() reflect.Type { + return reflect.TypeOf((*Provider)(nil)) +} + +func (i *Provider) ToProviderOutput() ProviderOutput { + return i.ToProviderOutputWithContext(context.Background()) +} + +func (i *Provider) ToProviderOutputWithContext(ctx context.Context) ProviderOutput { + return pulumi.ToOutputWithContext(ctx, i).(ProviderOutput) +} + +func (i *Provider) ToProviderPtrOutput() ProviderPtrOutput { + return i.ToProviderPtrOutputWithContext(context.Background()) +} + +func (i *Provider) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(ProviderPtrOutput) +} + +type ProviderPtrInput interface { + pulumi.Input + + ToProviderPtrOutput() ProviderPtrOutput + ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput +} + +type providerPtrType ProviderArgs + +func (*providerPtrType) ElementType() reflect.Type { + return reflect.TypeOf((**Provider)(nil)) +} + +func (i *providerPtrType) ToProviderPtrOutput() ProviderPtrOutput { + return i.ToProviderPtrOutputWithContext(context.Background()) +} + +func (i *providerPtrType) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(ProviderPtrOutput) +} + +type ProviderOutput struct{ *pulumi.OutputState } + +func (ProviderOutput) ElementType() reflect.Type { + return reflect.TypeOf((*Provider)(nil)) +} + +func (o ProviderOutput) ToProviderOutput() ProviderOutput { + return o +} + +func (o ProviderOutput) ToProviderOutputWithContext(ctx context.Context) ProviderOutput { + return o +} + +func (o ProviderOutput) ToProviderPtrOutput() ProviderPtrOutput { + return o.ToProviderPtrOutputWithContext(context.Background()) +} + +func (o ProviderOutput) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v Provider) *Provider { + return &v + }).(ProviderPtrOutput) +} + +type ProviderPtrOutput struct{ *pulumi.OutputState } + +func (ProviderPtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**Provider)(nil)) +} + +func (o ProviderPtrOutput) ToProviderPtrOutput() ProviderPtrOutput { + return o +} + +func (o ProviderPtrOutput) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput { + return o +} + +func (o ProviderPtrOutput) Elem() ProviderOutput { + return o.ApplyT(func(v *Provider) Provider { + if v != nil { + return *v + } + var ret Provider + return ret + }).(ProviderOutput) +} + +func init() { + pulumi.RegisterOutputType(ProviderOutput{}) + pulumi.RegisterOutputType(ProviderPtrOutput{}) +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go new file mode 100644 index 000000000..61e44b2aa --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go @@ -0,0 +1,77 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package example + +import ( + "fmt" + "os" + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/blang/semver" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type envParser func(v string) interface{} + +func parseEnvBool(v string) interface{} { + b, err := strconv.ParseBool(v) + if err != nil { + return nil + } + return b +} + +func parseEnvInt(v string) interface{} { + i, err := strconv.ParseInt(v, 0, 0) + if err != nil { + return nil + } + return int(i) +} + +func parseEnvFloat(v string) interface{} { + f, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil + } + return f +} + +func parseEnvStringArray(v string) interface{} { + var result pulumi.StringArray + for _, item := range strings.Split(v, ";") { + result = append(result, pulumi.String(item)) + } + return result +} + +func getEnvOrDefault(def interface{}, parser envParser, vars ...string) interface{} { + for _, v := range vars { + if value := os.Getenv(v); value != "" { + if parser != nil { + return parser(value) + } + return value + } + } + return def +} + +// PkgVersion uses reflection to determine the version of the current package. +func PkgVersion() (semver.Version, error) { + type sentinal struct{} + pkgPath := reflect.TypeOf(sentinal{}).PkgPath() + re := regexp.MustCompile("^.*/pulumi-example/sdk(/v\\d+)?") + if match := re.FindStringSubmatch(pkgPath); match != nil { + vStr := match[1] + if len(vStr) == 0 { // If the version capture group was empty, default to v1. + return semver.Version{Major: 1}, nil + } + return semver.MustParse(fmt.Sprintf("%s.0.0", vStr[2:])), nil + } + return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath) +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go new file mode 100644 index 000000000..f0fa1cb92 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go @@ -0,0 +1,259 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package example + +import ( + "context" + "reflect" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type Rec struct { + pulumi.CustomResourceState + + Rec RecPtrOutput `pulumi:"rec"` +} + +// NewRec registers a new resource with the given unique name, arguments, and options. +func NewRec(ctx *pulumi.Context, + name string, args *RecArgs, opts ...pulumi.ResourceOption) (*Rec, error) { + if args == nil { + args = &RecArgs{} + } + + var resource Rec + err := ctx.RegisterResource("example::Rec", name, args, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +// GetRec gets an existing Rec resource's state with the given name, ID, and optional +// state properties that are used to uniquely qualify the lookup (nil if not required). +func GetRec(ctx *pulumi.Context, + name string, id pulumi.IDInput, state *RecState, opts ...pulumi.ResourceOption) (*Rec, error) { + var resource Rec + err := ctx.ReadResource("example::Rec", name, id, state, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +// Input properties used for looking up and filtering Rec resources. +type recState struct { +} + +type RecState struct { +} + +func (RecState) ElementType() reflect.Type { + return reflect.TypeOf((*recState)(nil)).Elem() +} + +type recArgs struct { +} + +// The set of arguments for constructing a Rec resource. +type RecArgs struct { +} + +func (RecArgs) ElementType() reflect.Type { + return reflect.TypeOf((*recArgs)(nil)).Elem() +} + +type RecInput interface { + pulumi.Input + + ToRecOutput() RecOutput + ToRecOutputWithContext(ctx context.Context) RecOutput +} + +func (*Rec) ElementType() reflect.Type { + return reflect.TypeOf((*Rec)(nil)) +} + +func (i *Rec) ToRecOutput() RecOutput { + return i.ToRecOutputWithContext(context.Background()) +} + +func (i *Rec) ToRecOutputWithContext(ctx context.Context) RecOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecOutput) +} + +func (i *Rec) ToRecPtrOutput() RecPtrOutput { + return i.ToRecPtrOutputWithContext(context.Background()) +} + +func (i *Rec) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecPtrOutput) +} + +type RecPtrInput interface { + pulumi.Input + + ToRecPtrOutput() RecPtrOutput + ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput +} + +type recPtrType RecArgs + +func (*recPtrType) ElementType() reflect.Type { + return reflect.TypeOf((**Rec)(nil)) +} + +func (i *recPtrType) ToRecPtrOutput() RecPtrOutput { + return i.ToRecPtrOutputWithContext(context.Background()) +} + +func (i *recPtrType) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecPtrOutput) +} + +// RecArrayInput is an input type that accepts RecArray and RecArrayOutput values. +// You can construct a concrete instance of `RecArrayInput` via: +// +// RecArray{ RecArgs{...} } +type RecArrayInput interface { + pulumi.Input + + ToRecArrayOutput() RecArrayOutput + ToRecArrayOutputWithContext(context.Context) RecArrayOutput +} + +type RecArray []RecInput + +func (RecArray) ElementType() reflect.Type { + return reflect.TypeOf((*[]*Rec)(nil)).Elem() +} + +func (i RecArray) ToRecArrayOutput() RecArrayOutput { + return i.ToRecArrayOutputWithContext(context.Background()) +} + +func (i RecArray) ToRecArrayOutputWithContext(ctx context.Context) RecArrayOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecArrayOutput) +} + +// RecMapInput is an input type that accepts RecMap and RecMapOutput values. +// You can construct a concrete instance of `RecMapInput` via: +// +// RecMap{ "key": RecArgs{...} } +type RecMapInput interface { + pulumi.Input + + ToRecMapOutput() RecMapOutput + ToRecMapOutputWithContext(context.Context) RecMapOutput +} + +type RecMap map[string]RecInput + +func (RecMap) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]*Rec)(nil)).Elem() +} + +func (i RecMap) ToRecMapOutput() RecMapOutput { + return i.ToRecMapOutputWithContext(context.Background()) +} + +func (i RecMap) ToRecMapOutputWithContext(ctx context.Context) RecMapOutput { + return pulumi.ToOutputWithContext(ctx, i).(RecMapOutput) +} + +type RecOutput struct{ *pulumi.OutputState } + +func (RecOutput) ElementType() reflect.Type { + return reflect.TypeOf((*Rec)(nil)) +} + +func (o RecOutput) ToRecOutput() RecOutput { + return o +} + +func (o RecOutput) ToRecOutputWithContext(ctx context.Context) RecOutput { + return o +} + +func (o RecOutput) ToRecPtrOutput() RecPtrOutput { + return o.ToRecPtrOutputWithContext(context.Background()) +} + +func (o RecOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v Rec) *Rec { + return &v + }).(RecPtrOutput) +} + +type RecPtrOutput struct{ *pulumi.OutputState } + +func (RecPtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**Rec)(nil)) +} + +func (o RecPtrOutput) ToRecPtrOutput() RecPtrOutput { + return o +} + +func (o RecPtrOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput { + return o +} + +func (o RecPtrOutput) Elem() RecOutput { + return o.ApplyT(func(v *Rec) Rec { + if v != nil { + return *v + } + var ret Rec + return ret + }).(RecOutput) +} + +type RecArrayOutput struct{ *pulumi.OutputState } + +func (RecArrayOutput) ElementType() reflect.Type { + return reflect.TypeOf((*[]Rec)(nil)) +} + +func (o RecArrayOutput) ToRecArrayOutput() RecArrayOutput { + return o +} + +func (o RecArrayOutput) ToRecArrayOutputWithContext(ctx context.Context) RecArrayOutput { + return o +} + +func (o RecArrayOutput) Index(i pulumi.IntInput) RecOutput { + return pulumi.All(o, i).ApplyT(func(vs []interface{}) Rec { + return vs[0].([]Rec)[vs[1].(int)] + }).(RecOutput) +} + +type RecMapOutput struct{ *pulumi.OutputState } + +func (RecMapOutput) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]Rec)(nil)) +} + +func (o RecMapOutput) ToRecMapOutput() RecMapOutput { + return o +} + +func (o RecMapOutput) ToRecMapOutputWithContext(ctx context.Context) RecMapOutput { + return o +} + +func (o RecMapOutput) MapIndex(k pulumi.StringInput) RecOutput { + return pulumi.All(o, k).ApplyT(func(vs []interface{}) Rec { + return vs[0].(map[string]Rec)[vs[1].(string)] + }).(RecOutput) +} + +func init() { + pulumi.RegisterOutputType(RecOutput{}) + pulumi.RegisterOutputType(RecPtrOutput{}) + pulumi.RegisterOutputType(RecArrayOutput{}) + pulumi.RegisterOutputType(RecMapOutput{}) +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts new file mode 100644 index 000000000..421b766ef --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts @@ -0,0 +1,37 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +import * as pulumi from "@pulumi/pulumi"; +import * as utilities from "./utilities"; + +// Export members: +export * from "./provider"; +export * from "./rec"; + +// Import resources to register: +import { Rec } from "./rec"; + +const _module = { + version: utilities.getVersion(), + construct: (name: string, type: string, urn: string): pulumi.Resource => { + switch (type) { + case "example::Rec": + return new Rec(name, undefined, { urn }) + default: + throw new Error(`unknown resource type ${type}`); + } + }, +}; +pulumi.runtime.registerResourceModule("example", "", _module) + +import { Provider } from "./provider"; + +pulumi.runtime.registerResourcePackage("example", { + version: utilities.getVersion(), + constructProvider: (name: string, type: string, urn: string): pulumi.ProviderResource => { + if (type !== "pulumi:providers:example") { + throw new Error(`unknown provider type ${type}`); + } + return new Provider(name, undefined, { urn }); + }, +}); diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json new file mode 100644 index 000000000..9ac06bdfc --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json @@ -0,0 +1,16 @@ +{ + "name": "@pulumi/example", + "version": "${VERSION}", + "scripts": { + "build": "tsc" + }, + "devDependencies": { + "typescript": "^4.3.5" + }, + "peerDependencies": { + "@pulumi/pulumi": "latest" + }, + "pulumi": { + "resource": true + } +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts new file mode 100644 index 000000000..791f0a3cf --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts @@ -0,0 +1,46 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +import * as pulumi from "@pulumi/pulumi"; +import * as utilities from "./utilities"; + +export class Provider extends pulumi.ProviderResource { + /** @internal */ + public static readonly __pulumiType = 'example'; + + /** + * Returns true if the given object is an instance of Provider. This is designed to work even + * when multiple copies of the Pulumi SDK have been loaded into the same process. + */ + public static isInstance(obj: any): obj is Provider { + if (obj === undefined || obj === null) { + return false; + } + return obj['__pulumiType'] === Provider.__pulumiType; + } + + + /** + * Create a Provider resource with the given unique name, arguments, and options. + * + * @param name The _unique_ name of the resource. + * @param args The arguments to use to populate this resource's properties. + * @param opts A bag of options that control this resource's behavior. + */ + constructor(name: string, args?: ProviderArgs, opts?: pulumi.ResourceOptions) { + let inputs: pulumi.Inputs = {}; + opts = opts || {}; + { + } + if (!opts.version) { + opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()}); + } + super(Provider.__pulumiType, name, inputs, opts); + } +} + +/** + * The set of arguments for constructing a Provider resource. + */ +export interface ProviderArgs { +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts new file mode 100644 index 000000000..6aa2030cd --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts @@ -0,0 +1,64 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +import * as pulumi from "@pulumi/pulumi"; +import * as utilities from "./utilities"; + +import {Rec} from "./index"; + +export class Rec extends pulumi.CustomResource { + /** + * Get an existing Rec resource's state with the given name, ID, and optional extra + * properties used to qualify the lookup. + * + * @param name The _unique_ name of the resulting resource. + * @param id The _unique_ provider ID of the resource to lookup. + * @param opts Optional settings to control the behavior of the CustomResource. + */ + public static get(name: string, id: pulumi.Input, opts?: pulumi.CustomResourceOptions): Rec { + return new Rec(name, undefined as any, { ...opts, id: id }); + } + + /** @internal */ + public static readonly __pulumiType = 'example::Rec'; + + /** + * Returns true if the given object is an instance of Rec. This is designed to work even + * when multiple copies of the Pulumi SDK have been loaded into the same process. + */ + public static isInstance(obj: any): obj is Rec { + if (obj === undefined || obj === null) { + return false; + } + return obj['__pulumiType'] === Rec.__pulumiType; + } + + public /*out*/ readonly rec!: pulumi.Output; + + /** + * Create a Rec resource with the given unique name, arguments, and options. + * + * @param name The _unique_ name of the resource. + * @param args The arguments to use to populate this resource's properties. + * @param opts A bag of options that control this resource's behavior. + */ + constructor(name: string, args?: RecArgs, opts?: pulumi.CustomResourceOptions) { + let inputs: pulumi.Inputs = {}; + opts = opts || {}; + if (!opts.id) { + inputs["rec"] = undefined /*out*/; + } else { + inputs["rec"] = undefined /*out*/; + } + if (!opts.version) { + opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()}); + } + super(Rec.__pulumiType, name, inputs, opts); + } +} + +/** + * The set of arguments for constructing a Rec resource. + */ +export interface RecArgs { +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json new file mode 100644 index 000000000..e2e0424ca --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "outDir": "bin", + "target": "es2016", + "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, + "stripInternal": true, + "experimentalDecorators": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true, + "strict": true + }, + "files": [ + "index.ts", + "provider.ts", + "rec.ts", + "utilities.ts" + ] +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts new file mode 100644 index 000000000..f26ed073c --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts @@ -0,0 +1,49 @@ +// *** WARNING: this file was generated by test. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + + +export function getEnv(...vars: string[]): string | undefined { + for (const v of vars) { + const value = process.env[v]; + if (value) { + return value; + } + } + return undefined; +} + +export function getEnvBoolean(...vars: string[]): boolean | undefined { + const s = getEnv(...vars); + if (s !== undefined) { + // NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what + // Terraform uses internally when parsing boolean values. + if (["1", "t", "T", "true", "TRUE", "True"].find(v => v === s) !== undefined) { + return true; + } + if (["0", "f", "F", "false", "FALSE", "False"].find(v => v === s) !== undefined) { + return false; + } + } + return undefined; +} + +export function getEnvNumber(...vars: string[]): number | undefined { + const s = getEnv(...vars); + if (s !== undefined) { + const f = parseFloat(s); + if (!isNaN(f)) { + return f; + } + } + return undefined; +} + +export function getVersion(): string { + let version = require('./package.json').version; + // Node allows for the version to be prefixed by a "v", while semver doesn't. + // If there is a v, strip it off. + if (version.indexOf('v') === 0) { + version = version.slice(1); + } + return version; +} diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py new file mode 100644 index 000000000..63ca3153b --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py @@ -0,0 +1,33 @@ +# coding=utf-8 +# *** WARNING: this file was generated by test. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + +from . import _utilities +import typing +# Export this package's modules as members: +from .provider import * +from .rec import * +_utilities.register( + resource_modules=""" +[ + { + "pkg": "example", + "mod": "", + "fqn": "pulumi_example", + "classes": { + "example::Rec": "Rec" + } + } +] +""", + resource_packages=""" +[ + { + "pkg": "example", + "token": "pulumi:providers:example", + "fqn": "pulumi_example", + "class": "Provider" + } +] +""" +) diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py new file mode 100644 index 000000000..df9d60e73 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py @@ -0,0 +1,235 @@ +# coding=utf-8 +# *** WARNING: this file was generated by test. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + + +import importlib.util +import inspect +import json +import os +import pkg_resources +import sys +import typing + +import pulumi +import pulumi.runtime + +from semver import VersionInfo as SemverVersion +from parver import Version as PEP440Version + + +def get_env(*args): + for v in args: + value = os.getenv(v) + if value is not None: + return value + return None + + +def get_env_bool(*args): + str = get_env(*args) + if str is not None: + # NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what + # Terraform uses internally when parsing boolean values. + if str in ["1", "t", "T", "true", "TRUE", "True"]: + return True + if str in ["0", "f", "F", "false", "FALSE", "False"]: + return False + return None + + +def get_env_int(*args): + str = get_env(*args) + if str is not None: + try: + return int(str) + except: + return None + return None + + +def get_env_float(*args): + str = get_env(*args) + if str is not None: + try: + return float(str) + except: + return None + return None + + +def _get_semver_version(): + # __name__ is set to the fully-qualified name of the current module, In our case, it will be + # ._utilities. is the module we want to query the version for. + root_package, *rest = __name__.split('.') + + # pkg_resources uses setuptools to inspect the set of installed packages. We use it here to ask + # for the currently installed version of the root package (i.e. us) and get its version. + + # Unfortunately, PEP440 and semver differ slightly in incompatible ways. The Pulumi engine expects + # to receive a valid semver string when receiving requests from the language host, so it's our + # responsibility as the library to convert our own PEP440 version into a valid semver string. + + pep440_version_string = pkg_resources.require(root_package)[0].version + pep440_version = PEP440Version.parse(pep440_version_string) + (major, minor, patch) = pep440_version.release + prerelease = None + if pep440_version.pre_tag == 'a': + prerelease = f"alpha.{pep440_version.pre}" + elif pep440_version.pre_tag == 'b': + prerelease = f"beta.{pep440_version.pre}" + elif pep440_version.pre_tag == 'rc': + prerelease = f"rc.{pep440_version.pre}" + elif pep440_version.dev is not None: + prerelease = f"dev.{pep440_version.dev}" + + # The only significant difference between PEP440 and semver as it pertains to us is that PEP440 has explicit support + # for dev builds, while semver encodes them as "prerelease" versions. In order to bridge between the two, we convert + # our dev build version into a prerelease tag. This matches what all of our other packages do when constructing + # their own semver string. + return SemverVersion(major=major, minor=minor, patch=patch, prerelease=prerelease) + + +# Determine the version once and cache the value, which measurably improves program performance. +_version = _get_semver_version() +_version_str = str(_version) + + +def get_version(): + return _version_str + + +def get_resource_args_opts(resource_args_type, resource_options_type, *args, **kwargs): + """ + Return the resource args and options given the *args and **kwargs of a resource's + __init__ method. + """ + + resource_args, opts = None, None + + # If the first item is the resource args type, save it and remove it from the args list. + if args and isinstance(args[0], resource_args_type): + resource_args, args = args[0], args[1:] + + # Now look at the first item in the args list again. + # If the first item is the resource options class, save it. + if args and isinstance(args[0], resource_options_type): + opts = args[0] + + # If resource_args is None, see if "args" is in kwargs, and, if so, if it's typed as the + # the resource args type. + if resource_args is None: + a = kwargs.get("args") + if isinstance(a, resource_args_type): + resource_args = a + + # If opts is None, look it up in kwargs. + if opts is None: + opts = kwargs.get("opts") + + return resource_args, opts + + +# Temporary: just use pulumi._utils.lazy_import once everyone upgrades. +def lazy_import(fullname): + + import pulumi._utils as u + f = getattr(u, 'lazy_import', None) + if f is None: + f = _lazy_import_temp + + return f(fullname) + + +# Copied from pulumi._utils.lazy_import, see comments there. +def _lazy_import_temp(fullname): + m = sys.modules.get(fullname, None) + if m is not None: + return m + + spec = importlib.util.find_spec(fullname) + + m = sys.modules.get(fullname, None) + if m is not None: + return m + + loader = importlib.util.LazyLoader(spec.loader) + spec.loader = loader + module = importlib.util.module_from_spec(spec) + + m = sys.modules.get(fullname, None) + if m is not None: + return m + + sys.modules[fullname] = module + loader.exec_module(module) + return module + + +class Package(pulumi.runtime.ResourcePackage): + def __init__(self, pkg_info): + super().__init__() + self.pkg_info = pkg_info + + def version(self): + return _version + + def construct_provider(self, name: str, typ: str, urn: str) -> pulumi.ProviderResource: + if typ != self.pkg_info['token']: + raise Exception(f"unknown provider type {typ}") + Provider = getattr(lazy_import(self.pkg_info['fqn']), self.pkg_info['class']) + return Provider(name, pulumi.ResourceOptions(urn=urn)) + + +class Module(pulumi.runtime.ResourceModule): + def __init__(self, mod_info): + super().__init__() + self.mod_info = mod_info + + def version(self): + return _version + + def construct(self, name: str, typ: str, urn: str) -> pulumi.Resource: + class_name = self.mod_info['classes'].get(typ, None) + + if class_name is None: + raise Exception(f"unknown resource type {typ}") + + TheClass = getattr(lazy_import(self.mod_info['fqn']), class_name) + return TheClass(name, pulumi.ResourceOptions(urn=urn)) + + +def register(resource_modules, resource_packages): + resource_modules = json.loads(resource_modules) + resource_packages = json.loads(resource_packages) + + for pkg_info in resource_packages: + pulumi.runtime.register_resource_package(pkg_info['pkg'], Package(pkg_info)) + + for mod_info in resource_modules: + pulumi.runtime.register_resource_module( + mod_info['pkg'], + mod_info['mod'], + Module(mod_info)) + + +_F = typing.TypeVar('_F', bound=typing.Callable[..., typing.Any]) + + +def lift_output_func(func: typing.Any) -> typing.Callable[[_F], _F]: + """Decorator internally used on {fn}_output lifted function versions + to implement them automatically from the un-lifted function.""" + + func_sig = inspect.signature(func) + + def lifted_func(*args, opts=None, **kwargs): + bound_args = func_sig.bind(*args, **kwargs) + + return pulumi.Output.from_input({ + 'args': bound_args.args, + 'kwargs': bound_args.kwargs + }).apply(lambda resolved_args: func(*resolved_args['args'], + opts=opts, + **resolved_args['kwargs'])) + + return (lambda _: lifted_func) diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py new file mode 100644 index 000000000..d6ca5375e --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py @@ -0,0 +1,73 @@ +# coding=utf-8 +# *** WARNING: this file was generated by test. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + +import warnings +import pulumi +import pulumi.runtime +from typing import Any, Mapping, Optional, Sequence, Union, overload +from . import _utilities + +__all__ = ['ProviderArgs', 'Provider'] + +@pulumi.input_type +class ProviderArgs: + def __init__(__self__): + """ + The set of arguments for constructing a Provider resource. + """ + pass + + +class Provider(pulumi.ProviderResource): + @overload + def __init__(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + __props__=None): + """ + Create a Example resource with the given unique name, props, and options. + :param str resource_name: The name of the resource. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + ... + @overload + def __init__(__self__, + resource_name: str, + args: Optional[ProviderArgs] = None, + opts: Optional[pulumi.ResourceOptions] = None): + """ + Create a Example resource with the given unique name, props, and options. + :param str resource_name: The name of the resource. + :param ProviderArgs args: The arguments to use to populate this resource's properties. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + ... + def __init__(__self__, resource_name: str, *args, **kwargs): + resource_args, opts = _utilities.get_resource_args_opts(ProviderArgs, pulumi.ResourceOptions, *args, **kwargs) + if resource_args is not None: + __self__._internal_init(resource_name, opts, **resource_args.__dict__) + else: + __self__._internal_init(resource_name, *args, **kwargs) + + def _internal_init(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + __props__=None): + if opts is None: + opts = pulumi.ResourceOptions() + if not isinstance(opts, pulumi.ResourceOptions): + raise TypeError('Expected resource options to be a ResourceOptions instance') + if opts.version is None: + opts.version = _utilities.get_version() + if opts.id is None: + if __props__ is not None: + raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource') + __props__ = ProviderArgs.__new__(ProviderArgs) + + super(Provider, __self__).__init__( + 'example', + resource_name, + __props__, + opts) + diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/py.typed b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/py.typed new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py new file mode 100644 index 000000000..2c71342f1 --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py @@ -0,0 +1,98 @@ +# coding=utf-8 +# *** WARNING: this file was generated by test. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + +import warnings +import pulumi +import pulumi.runtime +from typing import Any, Mapping, Optional, Sequence, Union, overload +from . import _utilities + +__all__ = ['RecArgs', 'Rec'] + +@pulumi.input_type +class RecArgs: + def __init__(__self__): + """ + The set of arguments for constructing a Rec resource. + """ + pass + + +class Rec(pulumi.CustomResource): + @overload + def __init__(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + __props__=None): + """ + Create a Rec resource with the given unique name, props, and options. + :param str resource_name: The name of the resource. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + ... + @overload + def __init__(__self__, + resource_name: str, + args: Optional[RecArgs] = None, + opts: Optional[pulumi.ResourceOptions] = None): + """ + Create a Rec resource with the given unique name, props, and options. + :param str resource_name: The name of the resource. + :param RecArgs args: The arguments to use to populate this resource's properties. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + ... + def __init__(__self__, resource_name: str, *args, **kwargs): + resource_args, opts = _utilities.get_resource_args_opts(RecArgs, pulumi.ResourceOptions, *args, **kwargs) + if resource_args is not None: + __self__._internal_init(resource_name, opts, **resource_args.__dict__) + else: + __self__._internal_init(resource_name, *args, **kwargs) + + def _internal_init(__self__, + resource_name: str, + opts: Optional[pulumi.ResourceOptions] = None, + __props__=None): + if opts is None: + opts = pulumi.ResourceOptions() + if not isinstance(opts, pulumi.ResourceOptions): + raise TypeError('Expected resource options to be a ResourceOptions instance') + if opts.version is None: + opts.version = _utilities.get_version() + if opts.id is None: + if __props__ is not None: + raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource') + __props__ = RecArgs.__new__(RecArgs) + + __props__.__dict__["rec"] = None + super(Rec, __self__).__init__( + 'example::Rec', + resource_name, + __props__, + opts) + + @staticmethod + def get(resource_name: str, + id: pulumi.Input[str], + opts: Optional[pulumi.ResourceOptions] = None) -> 'Rec': + """ + Get an existing Rec resource's state with the given name, id, and optional extra + properties used to qualify the lookup. + + :param str resource_name: The unique name of the resulting resource. + :param pulumi.Input[str] id: The unique provider ID of the resource to lookup. + :param pulumi.ResourceOptions opts: Options for the resource. + """ + opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id)) + + __props__ = RecArgs.__new__(RecArgs) + + __props__.__dict__["rec"] = None + return Rec(resource_name, opts=opts, __props__=__props__) + + @property + @pulumi.getter + def rec(self) -> pulumi.Output[Optional[Any]]: + return pulumi.get(self, "rec") + diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py new file mode 100644 index 000000000..4550e1ebd --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py @@ -0,0 +1,58 @@ +# coding=utf-8 +# *** WARNING: this file was generated by test. *** +# *** Do not edit by hand unless you're certain you know what you are doing! *** + +import errno +from setuptools import setup, find_packages +from setuptools.command.install import install +from subprocess import check_call + + +VERSION = "0.0.0" +PLUGIN_VERSION = "0.0.0" + +class InstallPluginCommand(install): + def run(self): + install.run(self) + try: + check_call(['pulumi', 'plugin', 'install', 'resource', 'example', PLUGIN_VERSION]) + except OSError as error: + if error.errno == errno.ENOENT: + print(f""" + There was an error installing the example resource provider plugin. + It looks like `pulumi` is not installed on your system. + Please visit https://pulumi.com/ to install the Pulumi CLI. + You may try manually installing the plugin by running + `pulumi plugin install resource example {PLUGIN_VERSION}` + """) + else: + raise + + +def readme(): + try: + with open('README.md', encoding='utf-8') as f: + return f.read() + except FileNotFoundError: + return "example Pulumi Package - Development Version" + + +setup(name='pulumi_example', + version=VERSION, + long_description=readme(), + long_description_content_type='text/markdown', + cmdclass={ + 'install': InstallPluginCommand, + }, + packages=find_packages(), + package_data={ + 'pulumi_example': [ + 'py.typed', + ] + }, + install_requires=[ + 'parver>=0.2.1', + 'pulumi', + 'semver>=2.8.1' + ], + zip_safe=False) diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json new file mode 100644 index 000000000..2aa83be1d --- /dev/null +++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json @@ -0,0 +1,25 @@ +{ + "name": "example", + "version": "0.0.1", + "resources": { + "example::Rec": { + "properties": { + "rec": { + "$ref": "#/types/example::Rec" + } + } + } + }, + "language": { + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, + "go": { + "generateResourceContainerTypes": true + }, + "nodejs": {}, + "python": {} + } +} diff --git a/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj b/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj +++ b/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj @@ -40,6 +40,7 @@
+ diff --git a/pkg/codegen/internal/test/testdata/simple-enum-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-enum-schema/nodejs/package.json index 835e18694..1725a7b7d 100644 --- a/pkg/codegen/internal/test/testdata/simple-enum-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-enum-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-enum-schema/schema.json b/pkg/codegen/internal/test/testdata/simple-enum-schema/schema.json index 7b41fe32a..2938a2456 100644 --- a/pkg/codegen/internal/test/testdata/simple-enum-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-enum-schema/schema.json @@ -19,7 +19,7 @@ "description": "The sizes of trees available" } }, - "requiredInputs": [ "varieties"] + "requiredInputs": ["varieties"] }, "plant:tree/v1:RubberTree": { "inputProperties": { @@ -32,8 +32,8 @@ }, "farm": { "oneOf": [ - {"$ref": "#/types/plant:tree/v1:Farm"}, - {"type": "string"} + { "$ref": "#/types/plant:tree/v1:Farm" }, + { "type": "string" } ], "default": "(unknown)" }, @@ -50,8 +50,8 @@ "properties": { "farm": { "oneOf": [ - {"$ref": "#/types/plant:tree/v1:Farm"}, - {"type": "string"} + { "$ref": "#/types/plant:tree/v1:Farm" }, + { "type": "string" } ], "default": "(unknown)" } @@ -66,8 +66,8 @@ }, "farm": { "oneOf": [ - {"$ref": "#/types/plant:tree/v1:Farm"}, - {"type": "string"} + { "$ref": "#/types/plant:tree/v1:Farm" }, + { "type": "string" } ] }, "size": { @@ -121,8 +121,8 @@ }, "color": { "oneOf": [ - {"$ref": "#/types/plant::ContainerColor"}, - {"type": "string"} + { "$ref": "#/types/plant::ContainerColor" }, + { "type": "string" } ] }, "brightness": { @@ -248,6 +248,9 @@ "namespaces": { "plant": "Plant", "tree/v1": "Tree.V1" + }, + "packageReferences": { + "Pulumi": "3.12" } }, "go": { @@ -256,7 +259,14 @@ "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant/tree/v1": "treev1" } }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": { "moduleNameOverrides": { "tree/v1": "tree/v1" diff --git a/pkg/codegen/internal/test/testdata/simple-methods-schema/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-methods-schema/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-methods-schema/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-methods-schema/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-methods-schema/schema.json b/pkg/codegen/internal/test/testdata/simple-methods-schema/schema.json index ae28166eb..382a2f1cf 100644 --- a/pkg/codegen/internal/test/testdata/simple-methods-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-methods-schema/schema.json @@ -1,144 +1,139 @@ { - "version": "0.0.1", - "name": "example", - "types": { - "example:nested:Baz": { - "properties": { - "hello": { - "type": "string" - }, - "world": { - "type": "string" - } - }, - "type": "object" - } - }, - "resources": { - "example::Foo": { - "isComponent": true, - "methods": { - "bar": "example::Foo/bar", - "baz": "example::Foo/baz", - "generateKubeconfig": "example::Foo/generateKubeconfig" - } - } - }, - "functions": { - "example::Foo/bar": { - "description": "A description of bar.", - "inputs": { - "properties": { - "__self__": { - "$ref": "#/resources/example::Foo" - }, - "boolValue": { - "type": "boolean" - }, - "boolValueRequired": { - "type": "boolean" - }, - "boolValuePlain": { - "type": "boolean", - "plain": true - }, - "stringValue": { - "type": "string" - }, - "stringValueRequired": { - "type": "string" - }, - "stringValuePlain": { - "type": "string", - "plain": true - }, - "name": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" - }, - "nameRequired": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" - }, - "namePlain": { - "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet", - "plain": true - }, - "baz": { - "$ref": "#/types/example:nested:Baz" - }, - "bazRequired": { - "$ref": "#/types/example:nested:Baz" - }, - "bazPlain": { - "$ref": "#/types/example:nested:Baz", - "plain": true - } - }, - "required": [ - "__self__", - "boolValueRequired", - "stringValueRequired", - "nameRequired", - "bazRequired" - ] - }, - "outputs": { - "properties": { - "someValue": { - "type": "string" - } - }, - "required": [ - "someValue" - ] - } + "version": "0.0.1", + "name": "example", + "types": { + "example:nested:Baz": { + "properties": { + "hello": { + "type": "string" }, - "example::Foo/baz": { - "inputs": { - "properties": { - "__self__": { - "$ref": "#/resources/example::Foo" - } - }, - "required": [ - "__self__" - ] - } - }, - "example::Foo/generateKubeconfig": { - "description": "Do something with something else", - "inputs": { - "properties": { - "__self__": { - "$ref": "#/resources/example::Foo" - }, - "boolValue": { - "type": "boolean", - "plain": true - } - }, - "required": [ - "__self__", - "boolValue" - ] - }, - "outputs": { - "properties": { - "kubeconfig": { - "type": "string" - } - }, - "required": [ - "kubeconfig" - ] - } + "world": { + "type": "string" } - }, - "language": { - "csharp": {}, - "go": { - "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-methods-schema/go/example" - }, - "nodejs": {}, - "python": {} + }, + "type": "object" } + }, + "resources": { + "example::Foo": { + "isComponent": true, + "methods": { + "bar": "example::Foo/bar", + "baz": "example::Foo/baz", + "generateKubeconfig": "example::Foo/generateKubeconfig" + } + } + }, + "functions": { + "example::Foo/bar": { + "description": "A description of bar.", + "inputs": { + "properties": { + "__self__": { + "$ref": "#/resources/example::Foo" + }, + "boolValue": { + "type": "boolean" + }, + "boolValueRequired": { + "type": "boolean" + }, + "boolValuePlain": { + "type": "boolean", + "plain": true + }, + "stringValue": { + "type": "string" + }, + "stringValueRequired": { + "type": "string" + }, + "stringValuePlain": { + "type": "string", + "plain": true + }, + "name": { + "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + }, + "nameRequired": { + "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet" + }, + "namePlain": { + "$ref": "/random/v2.3.1/schema.json#/resources/random:index%2FrandomPet:RandomPet", + "plain": true + }, + "baz": { + "$ref": "#/types/example:nested:Baz" + }, + "bazRequired": { + "$ref": "#/types/example:nested:Baz" + }, + "bazPlain": { + "$ref": "#/types/example:nested:Baz", + "plain": true + } + }, + "required": [ + "__self__", + "boolValueRequired", + "stringValueRequired", + "nameRequired", + "bazRequired" + ] + }, + "outputs": { + "properties": { + "someValue": { + "type": "string" + } + }, + "required": ["someValue"] + } + }, + "example::Foo/baz": { + "inputs": { + "properties": { + "__self__": { + "$ref": "#/resources/example::Foo" + } + }, + "required": ["__self__"] + } + }, + "example::Foo/generateKubeconfig": { + "description": "Do something with something else", + "inputs": { + "properties": { + "__self__": { + "$ref": "#/resources/example::Foo" + }, + "boolValue": { + "type": "boolean", + "plain": true + } + }, + "required": ["__self__", "boolValue"] + }, + "outputs": { + "properties": { + "kubeconfig": { + "type": "string" + } + }, + "required": ["kubeconfig"] + } + } + }, + "language": { + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, + "go": { + "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-methods-schema/go/example" + }, + "nodejs": {}, + "python": {} + } } diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/schema.json b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/schema.json index 0526948a4..e417bf46c 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema-with-root-package/schema.json @@ -5,22 +5,28 @@ "example::Foo": { "properties": { "a": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "b": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "c": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "d": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "e": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "f": { - "type": "string", "plain": true + "type": "string", + "plain": true } }, "required": ["a", "c", "e"], @@ -65,28 +71,35 @@ "required": ["a", "c", "e"], "inputProperties": { "a": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "b": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "c": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "d": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "e": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "f": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "foo": { "$ref": "#/types/example::Foo" }, "bar": { - "$ref": "#/types/example::Foo", "plain": true + "$ref": "#/types/example::Foo", + "plain": true }, "baz": { "type": "array", @@ -101,12 +114,23 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-plain-schema-with-root-package/go/example", "rootPackageName": "different" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-plain-schema/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-plain-schema/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-plain-schema/schema.json b/pkg/codegen/internal/test/testdata/simple-plain-schema/schema.json index 724ef156d..da8edbbd7 100644 --- a/pkg/codegen/internal/test/testdata/simple-plain-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-plain-schema/schema.json @@ -5,22 +5,28 @@ "example::Foo": { "properties": { "a": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "b": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "c": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "d": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "e": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "f": { - "type": "string", "plain": true + "type": "string", + "plain": true } }, "required": ["a", "c", "e"], @@ -65,28 +71,35 @@ "required": ["a", "c", "e"], "inputProperties": { "a": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "b": { - "type": "boolean", "plain": true + "type": "boolean", + "plain": true }, "c": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "d": { - "type": "integer", "plain": true + "type": "integer", + "plain": true }, "e": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "f": { - "type": "string", "plain": true + "type": "string", + "plain": true }, "foo": { "$ref": "#/types/example::Foo" }, "bar": { - "$ref": "#/types/example::Foo", "plain": true + "$ref": "#/types/example::Foo", + "plain": true }, "baz": { "type": "array", @@ -121,11 +134,22 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-plain-schema/go/example" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/schema.json b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/schema.json index f341a4031..391ec912a 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema-custom-pypackage-name/schema.json @@ -115,11 +115,22 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-resource-schema/go/example" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": { "packageName": "custom_py_package" } diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-resource-schema/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-resource-schema/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-resource-schema/schema.json b/pkg/codegen/internal/test/testdata/simple-resource-schema/schema.json index bef9da857..de8e782b0 100644 --- a/pkg/codegen/internal/test/testdata/simple-resource-schema/schema.json +++ b/pkg/codegen/internal/test/testdata/simple-resource-schema/schema.json @@ -159,11 +159,22 @@ } }, "language": { - "csharp": {}, + "csharp": { + "packageReferences": { + "Pulumi": "3.12" + } + }, "go": { "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-resource-schema/go/example" }, - "nodejs": {}, + "nodejs": { + "dependencies": { + "@pulumi/pulumi": "^3.12" + }, + "devDependencies": { + "typescript": "^3.7.0" + } + }, "python": {} } } diff --git a/pkg/codegen/internal/test/testdata/simple-yaml-schema/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/simple-yaml-schema/dotnet/Pulumi.Example.csproj index b172ade5b..6d53245f3 100644 --- a/pkg/codegen/internal/test/testdata/simple-yaml-schema/dotnet/Pulumi.Example.csproj +++ b/pkg/codegen/internal/test/testdata/simple-yaml-schema/dotnet/Pulumi.Example.csproj @@ -40,6 +40,7 @@ + diff --git a/pkg/codegen/internal/test/testdata/simple-yaml-schema/nodejs/package.json b/pkg/codegen/internal/test/testdata/simple-yaml-schema/nodejs/package.json index 9ac06bdfc..63e5dd7b9 100644 --- a/pkg/codegen/internal/test/testdata/simple-yaml-schema/nodejs/package.json +++ b/pkg/codegen/internal/test/testdata/simple-yaml-schema/nodejs/package.json @@ -4,11 +4,11 @@ "scripts": { "build": "tsc" }, - "devDependencies": { - "typescript": "^4.3.5" + "dependencies": { + "@pulumi/pulumi": "^3.12" }, - "peerDependencies": { - "@pulumi/pulumi": "latest" + "devDependencies": { + "typescript": "^3.7.0" }, "pulumi": { "resource": true diff --git a/pkg/codegen/internal/test/testdata/simple-yaml-schema/schema.yaml b/pkg/codegen/internal/test/testdata/simple-yaml-schema/schema.yaml index 771583805..9071e3ccc 100644 --- a/pkg/codegen/internal/test/testdata/simple-yaml-schema/schema.yaml +++ b/pkg/codegen/internal/test/testdata/simple-yaml-schema/schema.yaml @@ -118,9 +118,14 @@ functions: result: "$ref": "#/resources/example::Resource" language: - csharp: {} - go: { - "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-resource-schema/go/example" - } - nodejs: {} + csharp: { "packageReferences": { "Pulumi": "3.12" } } + go: + { + "importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-resource-schema/go/example", + } + nodejs: + { + "dependencies": { "@pulumi/pulumi": "^3.12" }, + "devDependencies": { "typescript": "^3.7.0" }, + } python: {} diff --git a/pkg/codegen/nodejs/gen_test.go b/pkg/codegen/nodejs/gen_test.go index 9e1ab0bda..0c0322d2f 100644 --- a/pkg/codegen/nodejs/gen_test.go +++ b/pkg/codegen/nodejs/gen_test.go @@ -2,15 +2,61 @@ package nodejs import ( + "bytes" + "io/ioutil" + "path/filepath" + "strings" "testing" + "github.com/stretchr/testify/require" + "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" - "github.com/stretchr/testify/require" + "github.com/pulumi/pulumi/pkg/v3/testing/integration" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/executable" ) func TestGeneratePackage(t *testing.T) { - test.TestSDKCodegen(t, "nodejs", GeneratePackage) + test.TestSDKCodegen(t, "nodejs", GeneratePackage, typeCheckGeneratedPackage) +} + +func typeCheckGeneratedPackage(t *testing.T, pwd string) { + var err error + var npm string + npm, err = executable.FindExecutable("npm") + require.NoError(t, err) + + var stdout, stderr bytes.Buffer + cmdOptions := integration.ProgramTestOptions{ + Verbose: true, + Stderr: &stderr, + Stdout: &stdout, + } + + // TODO remove when https://github.com/pulumi/pulumi/pull/7938 lands + file := filepath.Join(pwd, "package.json") + oldFile, err := ioutil.ReadFile(file) + require.NoError(t, err) + newFile := strings.ReplaceAll(string(oldFile), "${VERSION}", "0.0.1") + err = ioutil.WriteFile(file, []byte(newFile), 0600) + require.NoError(t, err) + + err = integration.RunCommand(t, "npm install", []string{npm, "i"}, pwd, &cmdOptions) + require.NoError(t, err) + err = integration.RunCommand(t, "typecheck ts", + []string{filepath.Join(".", "node_modules", ".bin", "tsc"), "--noEmit"}, pwd, &cmdOptions) + if err != nil { + stderr := stderr.String() + if len(stderr) > 0 { + t.Logf("stderr: %s", stderr) + } + stdout := stdout.String() + if len(stdout) > 0 { + t.Logf("stdout: %s", stdout) + } + + } + require.NoError(t, err) } func TestGenerateTypeNames(t *testing.T) { diff --git a/pkg/codegen/python/gen_test.go b/pkg/codegen/python/gen_test.go index 2e498d0d3..1c27881da 100644 --- a/pkg/codegen/python/gen_test.go +++ b/pkg/codegen/python/gen_test.go @@ -18,17 +18,19 @@ import ( "encoding/json" "fmt" "io" + filesystem "io/fs" "io/ioutil" "path/filepath" "sort" "strings" "testing" + "github.com/stretchr/testify/require" + "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" + "github.com/pulumi/pulumi/pkg/v3/testing/integration" "github.com/pulumi/pulumi/sdk/v3/python" - - "github.com/stretchr/testify/require" ) var pathTests = []struct { @@ -57,7 +59,26 @@ func TestRelPathToRelImport(t *testing.T) { } func TestGeneratePackage(t *testing.T) { - test.TestSDKCodegen(t, "python", GeneratePackage) + test.TestSDKCodegen(t, "python", GeneratePackage, typeCheckGeneratedPackage) +} + +// We can't type check a python program. We just check for syntax errors. +func typeCheckGeneratedPackage(t *testing.T, pwd string) { + ex, _, err := python.CommandPath() + require.NoError(t, err) + cmdOptions := integration.ProgramTestOptions{} + err = filepath.Walk(pwd, func(path string, info filesystem.FileInfo, err error) error { + require.NoError(t, err) // an error in the walk + if info.Mode().IsRegular() && strings.HasSuffix(info.Name(), ".py") { + path, err = filepath.Abs(path) + require.NoError(t, err) + err = integration.RunCommand(t, "python syntax check", + []string{ex, "-m", "py_compile", path}, pwd, &cmdOptions) + require.NoError(t, err) + } + return nil + }) + require.NoError(t, err) } func TestGenerateTypeNames(t *testing.T) {