Compare commits

..

2 commits

Author SHA1 Message Date
Pat Gavlin 41844a5a9f WIP-compat: generate additional types 2021-11-24 15:47:42 -08:00
Mikhail Shilkov 80f0a833a0 (Draft) Do not generate Go inputty types for output-only schema types 2021-11-23 13:59:27 -08:00
235 changed files with 811 additions and 10601 deletions

View file

@ -8,5 +8,3 @@
### Bug Fixes
- [codegen/go] - Respect default values in Pulumi object types.
[#8411](https://github.com/pulumi/pulumi/pull/8400)

View file

@ -22,7 +22,7 @@ To hack on Pulumi, you'll need to get a development environment set up. You'll w
You can easily get all required dependencies with brew and npm
```bash
brew install node pipenv python@3 typescript yarn go@1.17 golangci/tap/golangci-lint pulumi/tap/pulumictl coreutils
brew install node pipenv python@3 typescript yarn go@1.17 golangci/tap/golangci-lint pulumi/tap/pulumictl
curl https://raw.githubusercontent.com/Homebrew/homebrew-cask/0272f0d33f/Casks/dotnet-sdk.rb > dotnet-sdk.rb # v3.1.0
brew install --HEAD -s dotnet-sdk.rb
rm dotnet-sdk.rb
@ -53,10 +53,9 @@ ulimit -n 5000
Across our projects, we try to use a regular set of make targets. The ones you'll care most about are:
1. `make ensure`, which restores/installs any build dependencies
1. `make dist`, which just builds and installs the Pulumi CLI
0. `make ensure`, which restores/installs any build dependencies
1. `make`, which builds Pulumi and runs a quick set of tests
1. `make all` which builds Pulumi and runs the quick tests and a larger set of tests.
2. `make all` which builds Pulumi and runs the quick tests and a larger set of tests.
We make heavy use of integration level testing where we invoke `pulumi` to create and then delete cloud resources. This requires you to have a Pulumi account (so [sign up for free](https://pulumi.com) today if you haven't already) and login with `pulumi login`.

File diff suppressed because it is too large Load diff

View file

@ -36,16 +36,14 @@ func CRDTypes(tool string, pkg *schema.Package) (map[string]*bytes.Buffer, error
pkg.getImports(r, importsAndAliases)
pkg.genHeader(buffer, []string{"context", "reflect"}, importsAndAliases)
if err := pkg.genResource(buffer, r, goPkgInfo.GenerateResourceContainerTypes); err != nil {
if err := pkg.genResource(buffer, r); err != nil {
return nil, fmt.Errorf("generating resource %s: %w", mod, err)
}
}
if len(pkg.types) > 0 {
for _, t := range pkg.types {
if err := pkg.genType(buffer, t); err != nil {
return nil, err
}
pkg.genType(buffer, t)
}
pkg.genTypeRegistrations(buffer, pkg.types)
}

269
pkg/codegen/go/gen_types.go Normal file
View file

@ -0,0 +1,269 @@
package gen
import (
"fmt"
"github.com/pulumi/pulumi/pkg/v3/codegen"
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
)
type outputType struct {
schema.Type
elementType schema.Type
}
func (t *outputType) String() string {
return fmt.Sprintf("Output<%v>", t.elementType)
}
type typeDetails struct {
optionalInputType bool
inputTypes []*schema.InputType
outputTypes []*outputType
}
type genContext struct {
tool string
pulumiPackage *schema.Package
info GoPackageInfo
generateExtraTypes bool
goPackages map[string]*pkgContext
notedTypes codegen.StringSet
}
func newGenContext(tool string, pulumiPackage *schema.Package, info GoPackageInfo) *genContext {
return &genContext{
tool: tool,
pulumiPackage: pulumiPackage,
info: info,
generateExtraTypes: true,
goPackages: map[string]*pkgContext{},
notedTypes: codegen.StringSet{},
}
}
func (ctx *genContext) getPackageForModule(mod string) *pkgContext {
p, ok := ctx.goPackages[mod]
if !ok {
p = &pkgContext{
ctx: ctx,
pkg: ctx.pulumiPackage,
mod: mod,
importBasePath: ctx.info.ImportBasePath,
rootPackageName: ctx.info.RootPackageName,
typeDetails: map[string]*typeDetails{},
names: codegen.NewStringSet(),
schemaNames: codegen.NewStringSet(),
renamed: map[string]string{},
duplicateTokens: map[string]bool{},
functionNames: map[*schema.Function]string{},
tool: ctx.tool,
modToPkg: ctx.info.ModuleToPackage,
pkgImportAliases: ctx.info.PackageImportAliases,
packages: ctx.goPackages,
liftSingleValueMethodReturns: ctx.info.LiftSingleValueMethodReturns,
disableInputTypeRegistrations: ctx.info.DisableInputTypeRegistrations,
}
ctx.goPackages[mod] = p
}
return p
}
func (ctx *genContext) getPackageForToken(token string) *pkgContext {
return ctx.getPackageForModule(tokenToPackage(ctx.pulumiPackage, ctx.info.ModuleToPackage, token))
}
func (ctx *genContext) getPackageForType(t schema.Type) *pkgContext {
_, pkg := ctx.getRepresentativeTypeAndPackage(t)
return pkg
}
func (ctx *genContext) getRepresentativeTypeAndPackage(t schema.Type) (schema.Type, *pkgContext) {
switch t := t.(type) {
case *outputType:
return ctx.getRepresentativeTypeAndPackage(t.elementType)
case *schema.InputType:
return ctx.getRepresentativeTypeAndPackage(t.ElementType)
case *schema.OptionalType:
return ctx.getRepresentativeTypeAndPackage(t.ElementType)
case *schema.ArrayType:
return ctx.getRepresentativeTypeAndPackage(t.ElementType)
case *schema.MapType:
return ctx.getRepresentativeTypeAndPackage(t.ElementType)
case *schema.ObjectType:
if t.Package != ctx.pulumiPackage {
return nil, nil
}
return t, ctx.getPackageForToken(t.Token)
case *schema.EnumType:
if t.Package != ctx.pulumiPackage {
return nil, nil
}
return t, ctx.getPackageForToken(t.Token)
case *schema.ResourceType:
if t.Resource.Package != ctx.pulumiPackage {
return nil, nil
}
return t, ctx.getPackageForToken(t.Token)
case *schema.TokenType:
return t, ctx.getPackageForToken(t.Token)
default:
return nil, nil
}
}
func (ctx *genContext) inputType(elementType schema.Type) *schema.InputType {
if obj, ok := elementType.(*schema.ObjectType); ok && !obj.IsInputShape() {
elementType = obj.InputShape
}
return &schema.InputType{ElementType: elementType}
}
func (ctx *genContext) outputType(elementType schema.Type) *outputType {
if obj, ok := elementType.(*schema.ObjectType); ok && !obj.IsPlainShape() {
elementType = obj.PlainShape
}
return &outputType{elementType: elementType}
}
func (ctx *genContext) resourceType(resource *schema.Resource) *schema.ResourceType {
return &schema.ResourceType{
Token: resource.Token,
Resource: resource,
}
}
func (ctx *genContext) noteType(t schema.Type) {
if ctx.notedTypes.Has(t.String()) {
return
}
ctx.notedTypes.Add(t.String())
switch t := t.(type) {
case *outputType:
ctx.noteOutputType(t)
case *schema.InputType:
ctx.noteInputType(t)
case *schema.OptionalType:
ctx.noteOptionalType(t)
case *schema.ArrayType:
ctx.noteType(t.ElementType)
case *schema.MapType:
ctx.noteType(t.ElementType)
case *schema.UnionType:
ctx.noteUnionType(t)
case *schema.ObjectType:
if t.Package != ctx.pulumiPackage {
return
}
ctx.noteObjectType(t)
case *schema.EnumType:
if t.Package != ctx.pulumiPackage || t.IsOverlay {
return
}
pkg := ctx.getPackageForType(t)
pkg.enums = append(pkg.enums, t)
}
}
func (ctx *genContext) foldOptionalInputOutputType(t *schema.OptionalType) bool {
// If the element type of the optional is nilable, we fold the optional and required input/output types together:
// the required input/output type can already represent the lack of a value.
return isNilType(t.ElementType)
}
func (ctx *genContext) noteOutputType(t *outputType) {
// If the context has been configured to generate extra types, note the corresponding input type.
if ctx.generateExtraTypes {
ctx.noteType(codegen.InputType(t.elementType))
}
// For optional, array, map, and object output types, we need to note some additional
// output types. In the former three cases, we need to note the output of the type's
// element type so we can generate element accessors. In the latter case, we need to
// note an output type per property type so we can generate property accessors.
switch t := t.elementType.(type) {
case *schema.OptionalType:
ctx.noteType(ctx.outputType(t.ElementType))
if ctx.foldOptionalInputOutputType(t) {
return
}
case *schema.ArrayType:
ctx.noteType(ctx.outputType(t.ElementType))
case *schema.MapType:
ctx.noteType(ctx.outputType(t.ElementType))
case *schema.ObjectType:
for _, p := range t.Properties {
ctx.noteType(ctx.outputType(p.Type))
}
}
if representativeType, pkg := ctx.getRepresentativeTypeAndPackage(t); pkg != nil {
details := pkg.detailsForType(representativeType)
details.outputTypes = append(details.outputTypes, t)
}
}
func (ctx *genContext) noteInputType(t *schema.InputType) {
if t, isOptional := t.ElementType.(*schema.OptionalType); isOptional {
if ctx.foldOptionalInputOutputType(t) {
ctx.noteType(ctx.inputType(t.ElementType))
return
}
if pkg := ctx.getPackageForType(t.ElementType); pkg != nil {
pkg.detailsForType(t.ElementType).optionalInputType = true
}
}
ctx.noteType(t.ElementType)
ctx.noteType(ctx.outputType(codegen.ResolvedType(t.ElementType)))
if representativeType, pkg := ctx.getRepresentativeTypeAndPackage(t); pkg != nil {
details := pkg.detailsForType(representativeType)
details.inputTypes = append(details.inputTypes, t)
}
}
func (ctx *genContext) noteOptionalType(t *schema.OptionalType) {
// Go generates optional inputs as inputs of optionals.
if input, ok := t.ElementType.(*schema.InputType); ok {
ctx.noteType(&schema.InputType{
ElementType: &schema.OptionalType{
ElementType: input.ElementType,
},
})
return
}
ctx.noteType(t.ElementType)
}
func (ctx *genContext) noteUnionType(t *schema.UnionType) {
for _, t := range t.ElementTypes {
ctx.noteType(t)
}
}
func (ctx *genContext) noteObjectType(t *schema.ObjectType) {
if !t.IsInputShape() {
pkg := ctx.getPackageForType(t)
pkg.types = append(pkg.types, t)
}
ctx.notePropertyTypes(t.Properties)
}
func (ctx *genContext) notePropertyTypes(props []*schema.Property) {
for _, p := range props {
ctx.noteType(p.Type)
}
}
func (ctx *genContext) noteOutputPropertyTypes(props []*schema.Property) {
for _, p := range props {
ctx.noteType(ctx.outputType(p.Type))
}
}

View file

@ -60,10 +60,6 @@ type GoPackageInfo struct {
// Feature flag to disable generating input type registration. This is a
// space saving measure.
DisableInputTypeRegistrations bool `json:"disableInputTypeRegistrations,omitempty"`
// Feature flag to disable generating Pulumi object default functions. This is a
// space saving measure.
DisableObjectDefaults bool `json:"disableObjectDefaults,omitempty"`
}
// Importer implements schema.Language for Go.

View file

@ -192,22 +192,11 @@ var sdkTests = []sdkTest{
SkipCompileCheck: codegen.NewStringSet(nodejs),
},
{
Directory: "plain-object-defaults",
Description: "Ensure that object defaults are generated (repro #8132)",
Directory: "env-helper",
Description: "Ensure that eviromental helpers are generated (repro #8132)",
Skip: codegen.NewStringSet("python/test", "nodejs/test"),
SkipCompileCheck: codegen.NewStringSet(dotnet),
},
{
Directory: "plain-object-disable-defaults",
Description: "Ensure that we can still compile safely when defaults are disabled",
Skip: codegen.NewStringSet("python/test", "nodejs/test"),
SkipCompileCheck: codegen.NewStringSet(dotnet),
},
{
Directory: "regress-8403",
Description: "Regress pulumi/pulumi#8403",
SkipCompileCheck: codegen.NewStringSet(dotnet, python, nodejs),
},
}
var genSDKOnly bool

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -9,7 +9,6 @@
"plant-provider/tree/v1/init.go",
"plant-provider/tree/v1/nursery.go",
"plant-provider/tree/v1/pulumiEnums.go",
"plant-provider/tree/v1/pulumiUtilities.go",
"plant-provider/tree/v1/rubberTree.go"
]
}

View file

@ -17,19 +17,6 @@ type Container struct {
Size ContainerSize `pulumi:"size"`
}
// Defaults sets the appropriate defaults for Container
func (val *Container) Defaults() *Container {
if val == nil {
return nil
}
tmp := *val
if isZero(tmp.Brightness) {
brightness_ := ContainerBrightness(1.0)
tmp.Brightness = &brightness_
}
return &tmp
}
// ContainerInput is an input type that accepts ContainerArgs and ContainerOutput values.
// You can construct a concrete instance of `ContainerInput` via:
//

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -1,85 +0,0 @@
// *** WARNING: this file was generated by test. ***
// *** Do not edit by hand unless you're certain you know what you are doing! ***
package v1
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-plant/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)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -29,20 +29,16 @@ func NewRubberTree(ctx *pulumi.Context,
return nil, errors.New("missing one or more required arguments")
}
containerApplier := func(v plantprovider.Container) *plantprovider.Container { return v.Defaults() }
if args.Container != nil {
args.Container = args.Container.ToContainerPtrOutput().Elem().ApplyT(containerApplier).(plantprovider.ContainerPtrOutput)
}
if isZero(args.Diameter) {
if args.Diameter == nil {
args.Diameter = Diameter(6.0)
}
if isZero(args.Farm) {
if args.Farm == nil {
args.Farm = pulumi.StringPtr("(unknown)")
}
if isZero(args.Size) {
if args.Size == nil {
args.Size = TreeSize("medium")
}
if isZero(args.Type) {
if args.Type == nil {
args.Type = RubberTreeVariety("Burgundy")
}
var resource RubberTree

View file

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -7,8 +7,8 @@ import (
"context"
"reflect"
"env-helper/example/mod1"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"plain-object-disable-defaults/example/mod1"
)
// A test for namespaces (mod 2)

View file

@ -7,8 +7,8 @@ import (
"context"
"reflect"
"env-helper/example/mod1"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"plain-object-disable-defaults/example/mod1"
)
type ModuleTest struct {

View file

@ -7,9 +7,9 @@ import (
"context"
"reflect"
"env-helper/example/mod1"
"env-helper/example/mod2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"plain-object-disable-defaults/example/mod1"
"plain-object-disable-defaults/example/mod2"
)
// BETA FEATURE - Options to configure the Helm Release resource.

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -219,8 +219,7 @@
}
},
"go": {
"importBasePath": "plain-object-disable-defaults/example",
"disableObjectDefaults": true
"importBasePath": "env-helper/example"
},
"nodejs": {
"dependencies": {

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -35,8 +35,8 @@ func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.Propert
}
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
switch args.Token {
case "mypkg::listStorageAccountKeys":
if args.Token == "mypkg::listStorageAccountKeys" {
targs := mypkg.ListStorageAccountKeysArgs{}
for k, v := range args.Args {
switch k {
@ -72,11 +72,12 @@ func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
"keys": result.Keys,
}
return resource.NewPropertyMapFromMap(outputs), nil
}
case "mypkg::funcWithDefaultValue",
"mypkg::funcWithAllOptionalInputs",
"mypkg::funcWithListParam",
"mypkg::funcWithDictParam":
if args.Token == "mypkg::funcWithDefaultValue" ||
args.Token == "mypkg::funcWithAllOptionalInputs" ||
args.Token == "mypkg::funcWithListParam" ||
args.Token == "mypkg::funcWithDictParam" {
result := mypkg.FuncWithDefaultValueResult{
R: fmt.Sprintf("%v", args.Args),
}
@ -84,8 +85,9 @@ func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
"r": result.R,
}
return resource.NewPropertyMapFromMap(outputs), nil
}
case "mypkg::getIntegrationRuntimeObjectMetadatum":
if args.Token == "mypkg::getIntegrationRuntimeObjectMetadatum" {
targs := mypkg.GetIntegrationRuntimeObjectMetadatumArgs{}
for k, v := range args.Args {
switch k {
@ -149,13 +151,16 @@ func TestListStorageAccountKeysOutput(t *testing.T) {
})
}
// TODO[pulumi/pulumi#7811]: it seems that default values are not
// supported by Go codegen yet, hence we do not observe "B" populated
// to default at all here.
func TestFuncWithDefaultValueOutput(t *testing.T) {
pulumiTest(t, func(ctx *pulumi.Context) error {
output := mypkg.FuncWithDefaultValueOutput(ctx, mypkg.FuncWithDefaultValueOutputArgs{
A: pulumi.String("my-a"),
})
r := waitOut(t, output.R())
assert.Equal(t, "map[a:{my-a} b:{b-default}]", r)
assert.Equal(t, "map[a:{my-a}]", r)
return nil
})
}

View file

@ -13,7 +13,7 @@ import (
// Check codegen of functions with default values.
func FuncWithDefaultValue(ctx *pulumi.Context, args *FuncWithDefaultValueArgs, opts ...pulumi.InvokeOption) (*FuncWithDefaultValueResult, error) {
var rv FuncWithDefaultValueResult
err := ctx.Invoke("mypkg::funcWithDefaultValue", args.Defaults(), &rv, opts...)
err := ctx.Invoke("mypkg::funcWithDefaultValue", args, &rv, opts...)
if err != nil {
return nil, err
}
@ -25,19 +25,6 @@ type FuncWithDefaultValueArgs struct {
B *string `pulumi:"b"`
}
// Defaults sets the appropriate defaults for FuncWithDefaultValueArgs
func (val *FuncWithDefaultValueArgs) Defaults() *FuncWithDefaultValueArgs {
if val == nil {
return nil
}
tmp := *val
if isZero(tmp.B) {
b_ := "b-default"
tmp.B = &b_
}
return &tmp
}
type FuncWithDefaultValueResult struct {
R string `pulumi:"r"`
}

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -22,53 +22,53 @@ func NewModuleResource(ctx *pulumi.Context,
return nil, errors.New("missing one or more required arguments")
}
if isZero(args.Optional_bool) {
if args.Optional_bool == nil {
args.Optional_bool = pulumi.BoolPtr(true)
}
args.Optional_const = pulumi.StringPtr("val")
if isZero(args.Optional_enum) {
if args.Optional_enum == nil {
args.Optional_enum = EnumThing(8)
}
if isZero(args.Optional_number) {
if args.Optional_number == nil {
args.Optional_number = pulumi.Float64Ptr(42.0)
}
if isZero(args.Optional_string) {
if args.Optional_string == nil {
args.Optional_string = pulumi.StringPtr("buzzer")
}
if isZero(args.Plain_optional_bool) {
if args.Plain_optional_bool == nil {
plain_optional_bool_ := true
args.Plain_optional_bool = &plain_optional_bool_
}
plain_optional_const_ := "val"
args.Plain_optional_const = &plain_optional_const_
if isZero(args.Plain_optional_number) {
if args.Plain_optional_number == nil {
plain_optional_number_ := 42.0
args.Plain_optional_number = &plain_optional_number_
}
if isZero(args.Plain_optional_string) {
if args.Plain_optional_string == nil {
plain_optional_string_ := "buzzer"
args.Plain_optional_string = &plain_optional_string_
}
if isZero(args.Plain_required_bool) {
if args.Plain_required_bool == false {
args.Plain_required_bool = true
}
args.Plain_required_const = "val"
if isZero(args.Plain_required_number) {
if args.Plain_required_number == 0.0 {
args.Plain_required_number = 42.0
}
if isZero(args.Plain_required_string) {
if args.Plain_required_string == "" {
args.Plain_required_string = "buzzer"
}
if isZero(args.Required_bool) {
if args.Required_bool == nil {
args.Required_bool = pulumi.Bool(true)
}
if isZero(args.Required_enum) {
if args.Required_enum == nil {
args.Required_enum = EnumThing(4)
}
if isZero(args.Required_number) {
if args.Required_number == nil {
args.Required_number = pulumi.Float64(42.0)
}
if isZero(args.Required_string) {
if args.Required_string == nil {
args.Required_string = pulumi.String("buzzer")
}
var resource ModuleResource

View file

@ -75,11 +75,3 @@ func PkgVersion() (semver.Version, error) {
}
return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
}
// isZero is a null safe check for if a value is it's types zero value.
func isZero(v interface{}) bool {
if v == nil {
return true
}
return reflect.ValueOf(v).IsZero()
}

View file

@ -1,26 +0,0 @@
// *** 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.Mod1.Inputs
{
/// <summary>
/// A test for namespaces (mod 1)
/// </summary>
public sealed class TypArgs : Pulumi.ResourceArgs
{
[Input("val")]
public Input<string>? Val { get; set; }
public TypArgs()
{
Val = Utilities.GetEnv("PULUMI_EXAMPLE_MOD1_DEFAULT") ?? "mod1";
}
}
}

View file

@ -1,118 +0,0 @@
// Copyright 2016-2021, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package codegentest
import (
"fmt"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"plain-object-defaults/example"
)
type mocks int
// We assert that default values were passed to our constuctor
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
checkFloat64 := func(v resource.PropertyValue, k string, expected float64) {
m := v.V.(resource.PropertyMap)
if m[resource.PropertyKey(k)].V.(float64) != expected {
panic(fmt.Sprintf("Expected %s to have value %.2f", k, expected))
}
}
for k, v := range args.Inputs {
switch k {
case "kubeClientSettings":
checkFloat64(v, "burst", 42)
case "backupKubeClientSettings":
checkFloat64(v, "qps", 7)
}
}
return args.Name, args.Inputs.Copy(), nil
}
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
panic("Call not supported")
}
func TestObjectDefaults(t *testing.T) {
path := "thePath"
defaultDriver := "secret"
kcs := example.HelmReleaseSettings{
PluginsPath: &path,
RequiredArg: "This is required",
}
withDefaults := kcs.Defaults()
assert.Equal(t, kcs.RequiredArg, withDefaults.RequiredArg)
assert.Equal(t, kcs.PluginsPath, withDefaults.PluginsPath)
assert.Nil(t, kcs.Driver)
assert.Equal(t, withDefaults.Driver, &defaultDriver)
}
func TestTransitiveObjectDefaults(t *testing.T) {
layered := example.LayeredType{
Other: example.HelmReleaseSettings{},
}
withDefaults := layered.Defaults()
assert.Equal(t, "secret", *withDefaults.Other.Driver)
}
// We already have that defaults for resources. We test that they translate through objects.
func TestDefaultResource(t *testing.T) {
os.Setenv("PULUMI_K8S_CLIENT_BURST", "42")
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := example.NewFoo(ctx, "foo", &example.FooArgs{
KubeClientSettings: example.KubeClientSettingsPtr(&example.KubeClientSettingsArgs{}),
BackupKubeClientSettings: &example.KubeClientSettingsArgs{Qps: pulumi.Float64(7)},
})
assert.NoError(t, err)
return nil
}, pulumi.WithMocks("example", "stack", mocks(0)))
}
func waitOut(t *testing.T, output pulumi.Output) interface{} {
result, err := waitOutput(output, 1*time.Second)
if err != nil {
t.Error(err)
return nil
}
return result
}
func waitOutput(output pulumi.Output, timeout time.Duration) (interface{}, error) {
c := make(chan interface{}, 2)
output.ApplyT(func(v interface{}) interface{} {
c <- v
return v
})
var timeoutMarker *int = new(int)
go func() {
time.Sleep(timeout)
c <- timeoutMarker
}()
result := <-c
if result == timeoutMarker {
return nil, fmt.Errorf("Timed out waiting for pulumi.Output after %v", timeout)
} else {
return result, nil
}
}

View file

@ -1,16 +0,0 @@
{
"emittedFiles": [
"example/doc.go",
"example/foo.go",
"example/funcWithAllOptionalInputs.go",
"example/init.go",
"example/mod1/pulumiTypes.go",
"example/mod1/pulumiUtilities.go",
"example/mod2/pulumiTypes.go",
"example/mod2/pulumiUtilities.go",
"example/moduleTest.go",
"example/provider.go",
"example/pulumiTypes.go",
"example/pulumiUtilities.go"
]
}

View file

@ -1,134 +0,0 @@
// *** 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/pkg/errors"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
// test new feature with resoruces
type Foo struct {
pulumi.CustomResourceState
// A test for plain types
DefaultKubeClientSettings KubeClientSettingsPtrOutput `pulumi:"defaultKubeClientSettings"`
}
// NewFoo registers a new resource with the given unique name, arguments, and options.
func NewFoo(ctx *pulumi.Context,
name string, args *FooArgs, opts ...pulumi.ResourceOption) (*Foo, error) {
if args == nil {
return nil, errors.New("missing one or more required arguments")
}
if args.BackupKubeClientSettings == nil {
return nil, errors.New("invalid value for required argument 'BackupKubeClientSettings'")
}
backupKubeClientSettingsApplier := func(v KubeClientSettings) *KubeClientSettings { return v.Defaults() }
args.BackupKubeClientSettings = args.BackupKubeClientSettings.ToKubeClientSettingsOutput().ApplyT(backupKubeClientSettingsApplier).(KubeClientSettingsPtrOutput).Elem()
kubeClientSettingsApplier := func(v KubeClientSettings) *KubeClientSettings { return v.Defaults() }
if args.KubeClientSettings != nil {
args.KubeClientSettings = args.KubeClientSettings.ToKubeClientSettingsPtrOutput().Elem().ApplyT(kubeClientSettingsApplier).(KubeClientSettingsPtrOutput)
}
settingsApplier := func(v LayeredType) *LayeredType { return v.Defaults() }
if args.Settings != nil {
args.Settings = args.Settings.ToLayeredTypePtrOutput().Elem().ApplyT(settingsApplier).(LayeredTypePtrOutput)
}
var resource Foo
err := ctx.RegisterResource("example:index:Foo", name, args, &resource, opts...)
if err != nil {
return nil, err
}
return &resource, nil
}
// GetFoo gets an existing Foo 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 GetFoo(ctx *pulumi.Context,
name string, id pulumi.IDInput, state *FooState, opts ...pulumi.ResourceOption) (*Foo, error) {
var resource Foo
err := ctx.ReadResource("example:index:Foo", name, id, state, &resource, opts...)
if err != nil {
return nil, err
}
return &resource, nil
}
// Input properties used for looking up and filtering Foo resources.
type fooState struct {
}
type FooState struct {
}
func (FooState) ElementType() reflect.Type {
return reflect.TypeOf((*fooState)(nil)).Elem()
}
type fooArgs struct {
Argument *string `pulumi:"argument"`
// Options for tuning the Kubernetes client used by a Provider.
BackupKubeClientSettings KubeClientSettings `pulumi:"backupKubeClientSettings"`
// Options for tuning the Kubernetes client used by a Provider.
KubeClientSettings *KubeClientSettings `pulumi:"kubeClientSettings"`
// describing things
Settings *LayeredType `pulumi:"settings"`
}
// The set of arguments for constructing a Foo resource.
type FooArgs struct {
Argument *string
// Options for tuning the Kubernetes client used by a Provider.
BackupKubeClientSettings KubeClientSettingsInput
// Options for tuning the Kubernetes client used by a Provider.
KubeClientSettings KubeClientSettingsPtrInput
// describing things
Settings LayeredTypePtrInput
}
func (FooArgs) ElementType() reflect.Type {
return reflect.TypeOf((*fooArgs)(nil)).Elem()
}
type FooInput interface {
pulumi.Input
ToFooOutput() FooOutput
ToFooOutputWithContext(ctx context.Context) FooOutput
}
func (*Foo) ElementType() reflect.Type {
return reflect.TypeOf((**Foo)(nil)).Elem()
}
func (i *Foo) ToFooOutput() FooOutput {
return i.ToFooOutputWithContext(context.Background())
}
func (i *Foo) ToFooOutputWithContext(ctx context.Context) FooOutput {
return pulumi.ToOutputWithContext(ctx, i).(FooOutput)
}
type FooOutput struct{ *pulumi.OutputState }
func (FooOutput) ElementType() reflect.Type {
return reflect.TypeOf((**Foo)(nil)).Elem()
}
func (o FooOutput) ToFooOutput() FooOutput {
return o
}
func (o FooOutput) ToFooOutputWithContext(ctx context.Context) FooOutput {
return o
}
func init() {
pulumi.RegisterInputType(reflect.TypeOf((*FooInput)(nil)).Elem(), &Foo{})
pulumi.RegisterOutputType(FooOutput{})
}

View file

@ -1,89 +0,0 @@
// *** 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"
)
// Check codegen of functions with all optional inputs.
func FuncWithAllOptionalInputs(ctx *pulumi.Context, args *FuncWithAllOptionalInputsArgs, opts ...pulumi.InvokeOption) (*FuncWithAllOptionalInputsResult, error) {
var rv FuncWithAllOptionalInputsResult
err := ctx.Invoke("mypkg::funcWithAllOptionalInputs", args.Defaults(), &rv, opts...)
if err != nil {
return nil, err
}
return &rv, nil
}
type FuncWithAllOptionalInputsArgs struct {
// Property A
A *HelmReleaseSettings `pulumi:"a"`
// Property B
B *string `pulumi:"b"`
}
// Defaults sets the appropriate defaults for FuncWithAllOptionalInputsArgs
func (val *FuncWithAllOptionalInputsArgs) Defaults() *FuncWithAllOptionalInputsArgs {
if val == nil {
return nil
}
tmp := *val
tmp.A = tmp.A.Defaults()
if isZero(tmp.B) {
b_ := "defValue"
tmp.B = &b_
}
return &tmp
}
type FuncWithAllOptionalInputsResult struct {
R string `pulumi:"r"`
}
func FuncWithAllOptionalInputsOutput(ctx *pulumi.Context, args FuncWithAllOptionalInputsOutputArgs, opts ...pulumi.InvokeOption) FuncWithAllOptionalInputsResultOutput {
return pulumi.ToOutputWithContext(context.Background(), args).
ApplyT(func(v interface{}) (FuncWithAllOptionalInputsResult, error) {
args := v.(FuncWithAllOptionalInputsArgs)
r, err := FuncWithAllOptionalInputs(ctx, &args, opts...)
return *r, err
}).(FuncWithAllOptionalInputsResultOutput)
}
type FuncWithAllOptionalInputsOutputArgs struct {
// Property A
A HelmReleaseSettingsPtrInput `pulumi:"a"`
// Property B
B pulumi.StringPtrInput `pulumi:"b"`
}
func (FuncWithAllOptionalInputsOutputArgs) ElementType() reflect.Type {
return reflect.TypeOf((*FuncWithAllOptionalInputsArgs)(nil)).Elem()
}
type FuncWithAllOptionalInputsResultOutput struct{ *pulumi.OutputState }
func (FuncWithAllOptionalInputsResultOutput) ElementType() reflect.Type {
return reflect.TypeOf((*FuncWithAllOptionalInputsResult)(nil)).Elem()
}
func (o FuncWithAllOptionalInputsResultOutput) ToFuncWithAllOptionalInputsResultOutput() FuncWithAllOptionalInputsResultOutput {
return o
}
func (o FuncWithAllOptionalInputsResultOutput) ToFuncWithAllOptionalInputsResultOutputWithContext(ctx context.Context) FuncWithAllOptionalInputsResultOutput {
return o
}
func (o FuncWithAllOptionalInputsResultOutput) R() pulumi.StringOutput {
return o.ApplyT(func(v FuncWithAllOptionalInputsResult) string { return v.R }).(pulumi.StringOutput)
}
func init() {
pulumi.RegisterOutputType(FuncWithAllOptionalInputsResultOutput{})
}

View file

@ -1,167 +0,0 @@
// *** WARNING: this file was generated by test. ***
// *** Do not edit by hand unless you're certain you know what you are doing! ***
package mod1
import (
"context"
"reflect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
// A test for namespaces (mod 1)
type Typ struct {
Val *string `pulumi:"val"`
}
// Defaults sets the appropriate defaults for Typ
func (val *Typ) Defaults() *Typ {
if val == nil {
return nil
}
tmp := *val
if isZero(tmp.Val) {
val_ := getEnvOrDefault("mod1", nil, "PULUMI_EXAMPLE_MOD1_DEFAULT").(string)
tmp.Val = &val_
}
return &tmp
}
// TypInput is an input type that accepts TypArgs and TypOutput values.
// You can construct a concrete instance of `TypInput` via:
//
// TypArgs{...}
type TypInput interface {
pulumi.Input
ToTypOutput() TypOutput
ToTypOutputWithContext(context.Context) TypOutput
}
// A test for namespaces (mod 1)
type TypArgs struct {
Val pulumi.StringPtrInput `pulumi:"val"`
}
func (TypArgs) ElementType() reflect.Type {
return reflect.TypeOf((*Typ)(nil)).Elem()
}
func (i TypArgs) ToTypOutput() TypOutput {
return i.ToTypOutputWithContext(context.Background())
}
func (i TypArgs) ToTypOutputWithContext(ctx context.Context) TypOutput {
return pulumi.ToOutputWithContext(ctx, i).(TypOutput)
}
func (i TypArgs) ToTypPtrOutput() TypPtrOutput {
return i.ToTypPtrOutputWithContext(context.Background())
}
func (i TypArgs) ToTypPtrOutputWithContext(ctx context.Context) TypPtrOutput {
return pulumi.ToOutputWithContext(ctx, i).(TypOutput).ToTypPtrOutputWithContext(ctx)
}
// TypPtrInput is an input type that accepts TypArgs, TypPtr and TypPtrOutput values.
// You can construct a concrete instance of `TypPtrInput` via:
//
// TypArgs{...}
//
// or:
//
// nil
type TypPtrInput interface {
pulumi.Input
ToTypPtrOutput() TypPtrOutput
ToTypPtrOutputWithContext(context.Context) TypPtrOutput
}
type typPtrType TypArgs
func TypPtr(v *TypArgs) TypPtrInput {
return (*typPtrType)(v)
}
func (*typPtrType) ElementType() reflect.Type {
return reflect.TypeOf((**Typ)(nil)).Elem()
}
func (i *typPtrType) ToTypPtrOutput() TypPtrOutput {
return i.ToTypPtrOutputWithContext(context.Background())
}
func (i *typPtrType) ToTypPtrOutputWithContext(ctx context.Context) TypPtrOutput {
return pulumi.ToOutputWithContext(ctx, i).(TypPtrOutput)
}
// A test for namespaces (mod 1)
type TypOutput struct{ *pulumi.OutputState }
func (TypOutput) ElementType() reflect.Type {
return reflect.TypeOf((*Typ)(nil)).Elem()
}
func (o TypOutput) ToTypOutput() TypOutput {
return o
}
func (o TypOutput) ToTypOutputWithContext(ctx context.Context) TypOutput {
return o
}
func (o TypOutput) ToTypPtrOutput() TypPtrOutput {
return o.ToTypPtrOutputWithContext(context.Background())
}
func (o TypOutput) ToTypPtrOutputWithContext(ctx context.Context) TypPtrOutput {
return o.ApplyTWithContext(ctx, func(_ context.Context, v Typ) *Typ {
return &v
}).(TypPtrOutput)
}
func (o TypOutput) Val() pulumi.StringPtrOutput {
return o.ApplyT(func(v Typ) *string { return v.Val }).(pulumi.StringPtrOutput)
}
type TypPtrOutput struct{ *pulumi.OutputState }
func (TypPtrOutput) ElementType() reflect.Type {
return reflect.TypeOf((**Typ)(nil)).Elem()
}
func (o TypPtrOutput) ToTypPtrOutput() TypPtrOutput {
return o
}
func (o TypPtrOutput) ToTypPtrOutputWithContext(ctx context.Context) TypPtrOutput {
return o
}
func (o TypPtrOutput) Elem() TypOutput {
return o.ApplyT(func(v *Typ) Typ {
if v != nil {
return *v
}
var ret Typ
return ret
}).(TypOutput)
}
func (o TypPtrOutput) Val() pulumi.StringPtrOutput {
return o.ApplyT(func(v *Typ) *string {
if v == nil {
return nil
}
return v.Val
}).(pulumi.StringPtrOutput)
}
func init() {
pulumi.RegisterInputType(reflect.TypeOf((*TypInput)(nil)).Elem(), TypArgs{})
pulumi.RegisterInputType(reflect.TypeOf((*TypPtrInput)(nil)).Elem(), TypArgs{})
pulumi.RegisterOutputType(TypOutput{})
pulumi.RegisterOutputType(TypPtrOutput{})
}

Some files were not shown because too many files have changed in this diff Show more