pulumi/pkg/codegen/go/gen.go

5025 lines
157 KiB
Go
Raw Normal View History

// 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.
// Pulling out some of the repeated strings tokens into constants would harm readability, so we just ignore the
// goconst linter's warning.
//
sdk/go: Remove 'nolint' directives from package docs Go treats comments that match the following regex as directives. //[a-z0-9]+:[a-z0-9] Comments that are directives don't show in an entity's documentation. https://github.com/golang/go/commit/5a550b695117f07a4f2454039a4871250cd3ed09#diff-f56160fd9fcea272966a8a1d692ad9f49206fdd8dbcbfe384865a98cd9bc2749R165 Our code has `//nolint` directives that now show in the API Reference. This is because these directives are in one of the following forms, which don't get this special treatment. // nolint:foo //nolint: foo This change fixes all such directives found by the regex: `// nolint|//nolint: `. See bottom of commit for command used for the fix. Verification: Here's the output of `go doc` on some entities before and after this change. Before ``` % go doc github.com/pulumi/pulumi/sdk/v3/go/pulumi | head -n8 package pulumi // import "github.com/pulumi/pulumi/sdk/v3/go/pulumi" nolint: lll, interfacer nolint: lll, interfacer const EnvOrganization = "PULUMI_ORGANIZATION" ... var ErrPlugins = errors.New("pulumi: plugins requested") ``` After ``` % go doc github.com/pulumi/pulumi/sdk/v3/go/pulumi | head -n8 package pulumi // import "github.com/pulumi/pulumi/sdk/v3/go/pulumi" const EnvOrganization = "PULUMI_ORGANIZATION" ... var ErrPlugins = errors.New("pulumi: plugins requested") func BoolRef(v bool) *bool func Float64Ref(v float64) *float64 func IntRef(v int) *int func IsSecret(o Output) bool ``` Before ``` % go doc github.com/pulumi/pulumi/sdk/v3/go/pulumi URN_ package pulumi // import "github.com/pulumi/pulumi/sdk/v3/go/pulumi" func URN_(o string) ResourceOption URN_ is an optional URN of a previously-registered resource of this type to read from the engine. nolint: revive ``` After: ``` % go doc github.com/pulumi/pulumi/sdk/v3/go/pulumi URN_ package pulumi // import "github.com/pulumi/pulumi/sdk/v3/go/pulumi" func URN_(o string) ResourceOption URN_ is an optional URN of a previously-registered resource of this type to read from the engine. ``` Note that golangci-lint offers a 'nolintlint' linter that finds such miuses of nolint, but it also finds other issues so I've deferred that to a follow up PR. Resolves #11785 Related: https://github.com/golangci/golangci-lint/issues/892 [git-generate] FILES=$(mktemp) rg -l '// nolint|//nolint: ' | tee "$FILES" | xargs perl -p -i -e ' s|// nolint|//nolint|g; s|//nolint: |//nolint:|g; ' rg '.go$' < "$FILES" | xargs gofmt -w -s
2023-01-06 00:07:45 +00:00
//nolint:lll, goconst
package gen
import (
"bytes"
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
_ "embed"
"fmt"
"go/format"
"io"
"os"
"path"
"reflect"
"sort"
"strconv"
"strings"
"sync"
"github.com/pulumi/pulumi/pkg/v3/codegen"
"github.com/pulumi/pulumi/pkg/v3/codegen/cgstrings"
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
"github.com/pulumi/pulumi/sdk/v3/go/common/slice"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
)
// A signifier that the module is external, and will never match.
//
// This token is always an invalid module since ':' is not allowed within modules.
const ExternalModuleSig = ":always-external:"
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
const (
GenericsSettingNone = "none"
GenericsSettingSideBySide = "side-by-side"
GenericsSettingGenericsOnly = "generics-only"
)
type typeDetails struct {
// Note: if any of {ptr,array,map}Input are set, input and the corresponding output field must also be set. The
// mark* functions ensure that these invariants hold.
input bool
ptrInput bool
arrayInput bool
mapInput bool
// Note: if any of {ptr,array,map}Output are set, output must also be set. The mark* functions ensure that these
// invariants hold.
output bool
ptrOutput bool
arrayOutput bool
mapOutput bool
}
func (d *typeDetails) hasOutputs() bool {
return d.output || d.ptrOutput || d.arrayOutput || d.mapOutput
}
func (d *typeDetails) mark(input, output bool) {
d.input = d.input || input
d.output = d.output || input || output
}
func (d *typeDetails) markPtr(input, output bool) {
d.mark(input, output)
d.ptrInput = d.ptrInput || input
d.ptrOutput = d.ptrOutput || input || output
}
func (d *typeDetails) markArray(input, output bool) {
d.mark(input, output)
d.arrayInput = d.arrayInput || input
d.arrayOutput = d.arrayOutput || input || output
}
func (d *typeDetails) markMap(input, output bool) {
d.mark(input, output)
d.mapInput = d.mapInput || input
d.mapOutput = d.mapOutput || input || output
}
// Title converts the input string to a title case
// where only the initial letter is upper-cased.
// It also removes $-prefix if any.
func Title(s string) string {
if s == "" {
return ""
}
if s[0] == '$' {
return Title(s[1:])
}
s = cgstrings.UppercaseFirst(s)
s = cgstrings.Unhyphenate(s)
return s
}
func tokenToPackage(pkg schema.PackageReference, overrides map[string]string, tok string) string {
mod := pkg.TokenToModule(tok)
if override, ok := overrides[mod]; ok {
mod = override
}
return strings.ToLower(mod)
}
// A threadsafe cache for sharing between invocations of GenerateProgram.
type Cache struct {
externalPackages map[*schema.Package]map[string]*pkgContext
m *sync.Mutex
}
var globalCache = NewCache()
func NewCache() *Cache {
return &Cache{
externalPackages: map[*schema.Package]map[string]*pkgContext{},
m: new(sync.Mutex),
}
}
func (c *Cache) lookupContextMap(pkg *schema.Package) (map[string]*pkgContext, bool) {
c.m.Lock()
defer c.m.Unlock()
m, ok := c.externalPackages[pkg]
return m, ok
}
func (c *Cache) setContextMap(pkg *schema.Package, m map[string]*pkgContext) {
c.m.Lock()
defer c.m.Unlock()
c.externalPackages[pkg] = m
}
type pkgContext struct {
pkg schema.PackageReference
mod string
importBasePath string
rootPackageName string
typeDetails map[schema.Type]*typeDetails
enums []*schema.EnumType
types []*schema.ObjectType
resources []*schema.Resource
functions []*schema.Function
2021-03-31 05:23:04 +00:00
// schemaNames tracks the names of types/resources as specified in the schema
schemaNames codegen.StringSet
names codegen.StringSet
renamed map[string]string
// A mapping between external packages and their bound contents.
externalPackages *Cache
// duplicateTokens tracks tokens that exist for both types and resources
duplicateTokens map[string]bool
functionNames map[*schema.Function]string
tool string
packages map[string]*pkgContext
// Name overrides set in GoPackageInfo
modToPkg map[string]string // Module name -> package name
pkgImportAliases map[string]string // Package name -> import alias
// the name used for the internal module, defaults to "internal" if not set by the schema
internalModuleName string
// Determines whether to make single-return-value methods return an output struct or the value
liftSingleValueMethodReturns bool
// Determines if we should emit type registration code
disableInputTypeRegistrations bool
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
// Determines if we should emit object defaults code
disableObjectDefaults bool
}
2021-03-11 05:04:30 +00:00
func (pkg *pkgContext) detailsForType(t schema.Type) *typeDetails {
if obj, ok := t.(*schema.ObjectType); ok && obj.IsInputShape() {
t = obj.PlainShape
}
details, ok := pkg.typeDetails[t]
if !ok {
details = &typeDetails{}
pkg.typeDetails[t] = details
}
return details
}
func (pkg *pkgContext) tokenToPackage(tok string) string {
return tokenToPackage(pkg.pkg, pkg.modToPkg, tok)
}
func (pkg *pkgContext) tokenToType(tok string) string {
// token := pkg : module : member
// module := path/to/module
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "tok: %s", tok)
2022-12-12 19:14:02 +00:00
contract.Assertf(pkg != nil, "pkg is nil. token %s", tok)
contract.Assertf(pkg.pkg != nil, "pkg.pkg is nil. token %s", tok)
mod, name := pkg.tokenToPackage(tok), components[2]
name = Title(name)
if modPkg, ok := pkg.packages[mod]; ok {
newName, renamed := modPkg.renamed[name]
if renamed {
name = newName
} else if modPkg.duplicateTokens[strings.ToLower(tok)] {
// maintain support for duplicate tokens for types and resources in Kubernetes
name += "Type"
}
}
if mod == pkg.mod {
return name
}
if mod == "" {
var err error
mod, err = packageRoot(pkg.pkg)
contract.AssertNoErrorf(err, "Unable to determine package root")
}
var importPath string
if alias, hasAlias := pkg.pkgImportAliases[path.Join(pkg.importBasePath, mod)]; hasAlias {
importPath = alias
} else {
2022-12-12 19:14:02 +00:00
importPath = mod[strings.IndexRune(mod, '/')+1:]
importPath = strings.ReplaceAll(importPath, "-", "")
}
return strings.ReplaceAll(importPath+"."+name, "-provider", "")
}
// Resolve a enum type to its name.
func (pkg *pkgContext) resolveEnumType(t *schema.EnumType) string {
if !pkg.isExternalReference(t) {
return pkg.tokenToEnum(t.Token)
}
extPkgCtx, _ := pkg.contextForExternalReference(t)
enumType := extPkgCtx.typeString(t)
return enumType
}
func (pkg *pkgContext) tokenToEnum(tok string) string {
// token := pkg : module : member
// module := path/to/module
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "Token must have 3 components, got %d", len(components))
if pkg == nil {
panic(fmt.Errorf("pkg is nil. token %s", tok))
}
if pkg.pkg == nil {
panic(fmt.Errorf("pkg.pkg is nil. token %s", tok))
}
mod, name := pkg.tokenToPackage(tok), components[2]
name = Title(name)
if modPkg, ok := pkg.packages[mod]; ok {
newName, renamed := modPkg.renamed[name]
if renamed {
name = newName
} else if modPkg.duplicateTokens[tok] {
// If the package containing the enum's token already has a resource or type with the
// same name, add an `Enum` suffix.
name += "Enum"
}
}
if mod == pkg.mod {
return name
}
if mod == "" {
mod = components[0]
}
var importPath string
if alias, hasAlias := pkg.pkgImportAliases[path.Join(pkg.importBasePath, mod)]; hasAlias {
importPath = alias
} else {
importPath = strings.ReplaceAll(mod, "/", "")
}
return importPath + "." + name
}
func (pkg *pkgContext) tokenToResource(tok string) string {
// token := pkg : module : member
// module := path/to/module
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "Token must have 3 components, got %d", len(components))
if pkg == nil {
panic(fmt.Errorf("pkg is nil. token %s", tok))
}
if pkg.pkg == nil {
panic(fmt.Errorf("pkg.pkg is nil. token %s", tok))
}
// Is it a provider resource?
if components[0] == "pulumi" && components[1] == "providers" {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return components[2] + ".Provider"
}
mod, name := pkg.tokenToPackage(tok), components[2]
name = Title(name)
if mod == pkg.mod {
return name
}
if mod == "" {
mod = components[0]
}
var importPath string
if alias, hasAlias := pkg.pkgImportAliases[path.Join(pkg.importBasePath, mod)]; hasAlias {
importPath = alias
} else {
importPath = strings.ReplaceAll(mod, "/", "")
}
return importPath + "." + name
}
func tokenToModule(tok string) string {
// token := pkg : module : member
// module := path/to/module
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "Token must have 3 components, got %d", len(components))
return components[1]
}
func tokenToName(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "Token must have 3 components, got %d", len(components))
return Title(components[2])
}
// disambiguatedResourceName gets the name of a resource as it should appear in source, resolving conflicts in the process.
func disambiguatedResourceName(r *schema.Resource, pkg *pkgContext) string {
name := rawResourceName(r)
if renamed, ok := pkg.renamed[name]; ok {
name = renamed
}
return name
}
// rawResourceName produces raw resource name translated from schema type token without resolving conflicts or dupes.
func rawResourceName(r *schema.Resource) string {
if r.IsProvider {
return "Provider"
}
return tokenToName(r.Token)
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
// If `nil` is a valid value of type `t`.
func isNilType(t schema.Type) bool {
switch t := t.(type) {
case *schema.OptionalType, *schema.ArrayType, *schema.MapType, *schema.ResourceType, *schema.InputType:
return true
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return isNilType(t.UnderlyingType)
}
case *schema.UnionType:
// If the union is actually a relaxed enum type, use the underlying
// type for the enum instead
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return isNilType(typ.ElementType)
}
}
default:
switch t {
case schema.ArchiveType, schema.AssetType, schema.JSONType, schema.AnyType:
return true
}
}
return false
}
func (pkg *pkgContext) inputType(t schema.Type) (result string) {
switch t := codegen.SimplifyInputUnion(t).(type) {
case *schema.OptionalType:
return pkg.typeString(t)
case *schema.InputType:
return pkg.inputType(t.ElementType)
2020-11-03 07:02:56 +00:00
case *schema.EnumType:
// Since enum type is itself an input
return pkg.resolveEnumType(t) + "Input"
case *schema.ArrayType:
en := pkg.inputType(t.ElementType)
return strings.TrimSuffix(en, "Input") + "ArrayInput"
case *schema.MapType:
en := pkg.inputType(t.ElementType)
return strings.TrimSuffix(en, "Input") + "MapInput"
case *schema.ObjectType:
if t.IsInputShape() {
t = t.PlainShape
}
return pkg.resolveObjectType(t) + "Input"
case *schema.ResourceType:
return pkg.resolveResourceType(t) + "Input"
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return pkg.inputType(t.UnderlyingType)
}
return pkg.tokenToType(t.Token) + "Input"
case *schema.UnionType:
2020-11-03 07:02:56 +00:00
// If the union is actually a relaxed enum type, use the underlying
// type for the input instead
2020-11-03 07:02:56 +00:00
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.inputType(typ.ElementType)
2020-11-03 07:02:56 +00:00
}
}
// TODO(pdg): union types
return "pulumi.Input"
default:
switch t {
case schema.BoolType:
return "pulumi.BoolInput"
case schema.IntType:
return "pulumi.IntInput"
case schema.NumberType:
return "pulumi.Float64Input"
case schema.StringType:
return "pulumi.StringInput"
case schema.ArchiveType:
return "pulumi.ArchiveInput"
case schema.AssetType:
return "pulumi.AssetOrArchiveInput"
case schema.JSONType:
fallthrough
case schema.AnyType:
return "pulumi.Input"
}
}
panic(fmt.Errorf("unexpected type %T", t))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genericInputTypeImpl(t schema.Type) string {
switch t := codegen.SimplifyInputUnion(t).(type) {
case *schema.OptionalType:
return pkg.genericInputTypeImpl(t.ElementType)
case *schema.InputType:
return pkg.genericInputTypeImpl(t.ElementType)
case *schema.EnumType:
return pkg.resolveEnumType(t)
case *schema.ArrayType:
elementType := pkg.genericInputTypeImpl(t.ElementType)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return "[]" + elementType
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
case *schema.MapType:
elementType := pkg.genericInputTypeImpl(t.ElementType)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return "map[string]" + elementType
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
case *schema.ObjectType:
elementType := pkg.resolveObjectType(t)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return "*" + elementType
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
case *schema.UnionType:
// If the union is actually a relaxed enum type, use the underlying
// type for the input instead
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.genericInputTypeImpl(typ.ElementType)
}
}
return "any"
default:
elementType, _ := pkg.genericElementType(t)
return elementType
}
}
func isArrayType(t schema.Type) bool {
switch t.(type) {
case *schema.ArrayType:
return true
default:
return false
}
}
func isMapType(t schema.Type) bool {
switch t.(type) {
case *schema.MapType:
return true
default:
return false
}
}
func isOptionalType(t schema.Type) bool {
switch t.(type) {
case *schema.OptionalType:
return true
default:
return false
}
}
func reduceInputType(t schema.Type) schema.Type {
switch t := t.(type) {
case *schema.InputType:
return reduceInputType(t.ElementType)
default:
return t
}
}
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
func (pkg *pkgContext) genericTypeNeedsPointer(t schema.Type) bool {
return isOptionalType(reduceInputType(t)) && !isArrayType(codegen.UnwrapType(t)) && !isMapType(codegen.UnwrapType(t))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genericInputType(t schema.Type) string {
optionalPointer := ""
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
if pkg.genericTypeNeedsPointer(t) {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
optionalPointer = "*"
}
inputType := pkg.genericInputTypeImpl(t)
if strings.HasPrefix(inputType, "*") {
optionalPointer = ""
}
return fmt.Sprintf("pulumix.Input[%s%s]", optionalPointer, inputType)
}
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
func (pkg *pkgContext) plainGenericInputType(t schema.Type) string {
optionalPointer := ""
if pkg.genericTypeNeedsPointer(t) {
optionalPointer = "*"
}
inputType := pkg.genericInputTypeImpl(t)
if strings.HasPrefix(inputType, "*") {
optionalPointer = ""
}
return fmt.Sprintf("%s%s", optionalPointer, inputType)
}
func (pkg *pkgContext) argsTypeImpl(t schema.Type) (result string) {
switch t := codegen.SimplifyInputUnion(t).(type) {
case *schema.OptionalType:
return pkg.typeStringImpl(t, true)
case *schema.InputType:
return pkg.argsTypeImpl(t.ElementType)
case *schema.EnumType:
// Since enum type is itself an input
return pkg.resolveEnumType(t)
case *schema.ArrayType:
en := pkg.argsTypeImpl(t.ElementType)
if en == "pulumi.Any" {
en = strings.TrimSuffix(en, "Any")
}
return strings.TrimSuffix(en, "Args") + "Array"
case *schema.MapType:
en := pkg.argsTypeImpl(t.ElementType)
if en == "pulumi.Any" {
en = strings.TrimSuffix(en, "Any")
}
return strings.TrimSuffix(en, "Args") + "Map"
case *schema.ObjectType:
return pkg.resolveObjectType(t)
case *schema.ResourceType:
return pkg.resolveResourceType(t)
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return pkg.argsTypeImpl(t.UnderlyingType)
}
return pkg.tokenToType(t.Token)
case *schema.UnionType:
// If the union is actually a relaxed enum type, use the underlying
// type for the input instead
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.argsTypeImpl(typ.ElementType)
}
}
return "pulumi.Any"
default:
switch t {
case schema.BoolType:
return "pulumi.Bool"
case schema.IntType:
return "pulumi.Int"
case schema.NumberType:
return "pulumi.Float64"
case schema.StringType:
return "pulumi.String"
case schema.ArchiveType:
2020-01-23 18:42:38 +00:00
return "pulumi.Archive"
case schema.AssetType:
2020-01-23 18:42:38 +00:00
return "pulumi.AssetOrArchive"
case schema.JSONType:
fallthrough
case schema.AnyType:
return "pulumi.Any"
}
}
panic(fmt.Errorf("unexpected type %T", t))
}
func (pkg *pkgContext) argsType(t schema.Type) string {
return pkg.typeStringImpl(t, true)
}
func (pkg *pkgContext) typeStringImpl(t schema.Type, argsType bool) string {
switch t := t.(type) {
case *schema.OptionalType:
if input, isInputType := t.ElementType.(*schema.InputType); isInputType {
elem := pkg.inputType(input.ElementType)
if isNilType(input.ElementType) || elem == "pulumi.Input" {
return elem
}
if pkg.isExternalReference(input.ElementType) {
_, details := pkg.contextForExternalReference(input.ElementType)
switch input.ElementType.(type) {
case *schema.ObjectType:
if !details.ptrInput {
return "*" + elem
}
case *schema.EnumType:
if !(details.ptrInput || details.input) {
return "*" + elem
}
}
}
if argsType {
return elem + "Ptr"
}
return strings.TrimSuffix(elem, "Input") + "PtrInput"
}
elementType := pkg.typeStringImpl(t.ElementType, argsType)
if isNilType(t.ElementType) || elementType == "interface{}" {
return elementType
}
return "*" + elementType
case *schema.InputType:
if argsType {
return pkg.argsTypeImpl(t.ElementType)
}
return pkg.inputType(t.ElementType)
case *schema.EnumType:
return pkg.resolveEnumType(t)
case *schema.ArrayType:
typ := "[]"
return typ + pkg.typeStringImpl(t.ElementType, argsType)
case *schema.MapType:
typ := "map[string]"
return typ + pkg.typeStringImpl(t.ElementType, argsType)
case *schema.ObjectType:
return pkg.resolveObjectType(t)
case *schema.ResourceType:
return "*" + pkg.resolveResourceType(t)
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return pkg.typeStringImpl(t.UnderlyingType, argsType)
}
return pkg.tokenToType(t.Token)
case *schema.UnionType:
2020-11-03 07:02:56 +00:00
// If the union is actually a relaxed enum type, use the underlying
// type for the enum instead
2020-11-03 07:02:56 +00:00
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.typeStringImpl(typ.ElementType, argsType)
2020-11-03 07:02:56 +00:00
}
}
// TODO(pdg): union types
return "interface{}"
default:
switch t {
case schema.BoolType:
return "bool"
case schema.IntType:
return "int"
case schema.NumberType:
return "float64"
case schema.StringType:
return "string"
case schema.ArchiveType:
return "pulumi.Archive"
case schema.AssetType:
return "pulumi.AssetOrArchive"
case schema.JSONType:
fallthrough
case schema.AnyType:
return "interface{}"
}
}
panic(fmt.Errorf("unexpected type %T", t))
}
func (pkg *pkgContext) typeString(t schema.Type) string {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
s := pkg.typeStringImpl(t, false)
if s == "pulumi." {
return "pulumi.Any"
}
return s
}
func (pkg *pkgContext) isExternalReference(t schema.Type) bool {
isExternal, _, _ := pkg.isExternalReferenceWithPackage(t)
return isExternal
}
// Return if `t` is external to `pkg`. If so, the associated foreign schema.Package is returned.
func (pkg *pkgContext) isExternalReferenceWithPackage(t schema.Type) (
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
isExternal bool, extPkg schema.PackageReference, token string,
) {
switch typ := t.(type) {
case *schema.ObjectType:
isExternal = typ.PackageReference != nil && !codegen.PkgEquals(typ.PackageReference, pkg.pkg)
if isExternal {
extPkg = typ.PackageReference
token = typ.Token
}
return
case *schema.ResourceType:
isExternal = typ.Resource != nil && pkg.pkg != nil && !codegen.PkgEquals(typ.Resource.PackageReference, pkg.pkg)
if isExternal {
extPkg = typ.Resource.PackageReference
token = typ.Token
}
return
case *schema.EnumType:
isExternal = pkg.pkg != nil && !codegen.PkgEquals(typ.PackageReference, pkg.pkg)
if isExternal {
extPkg = typ.PackageReference
token = typ.Token
}
return
}
return
}
// resolveResourceType resolves resource references in properties while
// taking into account potential external resources. Returned type is
// always marked as required. Caller should check if the property is
// optional and convert the type to a pointer if necessary.
func (pkg *pkgContext) resolveResourceType(t *schema.ResourceType) string {
if !pkg.isExternalReference(t) {
2021-01-19 17:55:40 +00:00
return pkg.tokenToResource(t.Token)
}
extPkgCtx, _ := pkg.contextForExternalReference(t)
2021-01-19 17:55:40 +00:00
resType := extPkgCtx.tokenToResource(t.Token)
if !strings.Contains(resType, ".") {
resType = fmt.Sprintf("%s.%s", extPkgCtx.pkg.Name(), resType)
2021-01-19 17:55:40 +00:00
}
return resType
}
// resolveObjectType resolves resource references in properties while
// taking into account potential external resources. Returned type is
// always marked as required. Caller should check if the property is
// optional and convert the type to a pointer if necessary.
func (pkg *pkgContext) resolveObjectType(t *schema.ObjectType) string {
isExternal, _, _ := pkg.isExternalReferenceWithPackage(t)
if !isExternal {
name := pkg.tokenToType(t.Token)
[sdk-gen/go] Fix compiling plain element type with plain maps (#14704) # Description Fixes #14662 when choosing whether to use `ObjectName` (plain) or `ObjectNameArgs` (non-plain) we have to check whether the non-plain version was actually available in first place (sometimes it isn't when the type isn't used anywhere as non-plain) so the fix here is to use the package context that tracks the usages to determine whether the `Args` suffix should be used. Funny though, for other languages like C#, TypeScript and Python we don't have a concept of a strictly plain type. Instead all types are non-plain (accepting values for their properties being inputs/outputs) which means that a plain element type on maps for these languages has no effect ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-04 12:34:40 +00:00
objectTypeDetails := pkg.detailsForType(t)
if t.IsInputShape() && objectTypeDetails.input {
return name + "Args"
}
return name
2021-01-19 17:55:40 +00:00
}
[sdk-gen/go] Fix compiling plain element type with plain maps (#14704) # Description Fixes #14662 when choosing whether to use `ObjectName` (plain) or `ObjectNameArgs` (non-plain) we have to check whether the non-plain version was actually available in first place (sometimes it isn't when the type isn't used anywhere as non-plain) so the fix here is to use the package context that tracks the usages to determine whether the `Args` suffix should be used. Funny though, for other languages like C#, TypeScript and Python we don't have a concept of a strictly plain type. Instead all types are non-plain (accepting values for their properties being inputs/outputs) which means that a plain element type on maps for these languages has no effect ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-04 12:34:40 +00:00
extPkg, externalTypeDetails := pkg.contextForExternalReference(t)
typeName := extPkg.tokenToType(t.Token)
if t.IsInputShape() && externalTypeDetails.input {
return typeName + "Args"
}
return typeName
}
func (pkg *pkgContext) contextForExternalReference(t schema.Type) (*pkgContext, typeDetails) {
isExternal, extPkg, token := pkg.isExternalReferenceWithPackage(t)
contract.Assertf(isExternal, "Expected external reference for %v", t)
var goInfo GoPackageInfo
extDef, err := extPkg.Definition()
contract.AssertNoErrorf(err, "Could not load definition for %q", extPkg.Name())
contract.AssertNoErrorf(extDef.ImportLanguages(map[string]schema.Language{"go": Importer}),
"Failed to import languages")
if info, ok := extDef.Language["go"].(GoPackageInfo); ok {
2021-01-19 17:55:40 +00:00
goInfo = info
} else {
goInfo.ImportBasePath = extractImportBasePath(extPkg)
2021-01-19 17:55:40 +00:00
}
pkgImportAliases := goInfo.PackageImportAliases
// Ensure that any package import aliases we have specified locally take precedence over those
// specified in the remote package.
def, err := pkg.pkg.Definition()
contract.AssertNoErrorf(err, "Could not load definition for %q", pkg.pkg.Name())
if ourPkgGoInfoI, has := def.Language["go"]; has {
ourPkgGoInfo := ourPkgGoInfoI.(GoPackageInfo)
if len(ourPkgGoInfo.PackageImportAliases) > 0 {
pkgImportAliases = make(map[string]string)
// Copy the external import aliases.
for k, v := range goInfo.PackageImportAliases {
pkgImportAliases[k] = v
}
// Copy the local import aliases, overwriting any external aliases.
for k, v := range ourPkgGoInfo.PackageImportAliases {
pkgImportAliases[k] = v
}
}
}
var maps map[string]*pkgContext
if extMap, ok := pkg.externalPackages.lookupContextMap(extDef); ok {
maps = extMap
} else {
maps, err = generatePackageContextMap(pkg.tool, extPkg, goInfo, pkg.externalPackages)
contract.AssertNoErrorf(err, "Could not generate package context map")
pkg.externalPackages.setContextMap(extDef, maps)
}
extPkgCtx := maps[""]
extPkgCtx.pkgImportAliases = pkgImportAliases
extPkgCtx.externalPackages = pkg.externalPackages
mod := tokenToPackage(extPkg, goInfo.ModuleToPackage, token)
extPkgCtx.mod = ExternalModuleSig
return extPkgCtx, *maps[mod].detailsForType(t)
}
// outputTypeImpl does the meat of the generation of output type names from schema types. This function should only be
// called with a fully-resolved type (e.g. the result of codegen.ResolvedType). Instead of calling this function, you
// probably want to call pkgContext.outputType, which ensures that its argument is resolved.
func (pkg *pkgContext) outputTypeImpl(t schema.Type) string {
switch t := t.(type) {
case *schema.OptionalType:
elem := pkg.outputTypeImpl(t.ElementType)
if isNilType(t.ElementType) || elem == "pulumi.AnyOutput" {
return elem
}
if pkg.isExternalReference(t.ElementType) {
_, details := pkg.contextForExternalReference(t.ElementType)
switch t.ElementType.(type) {
case *schema.ObjectType:
if !details.ptrOutput {
return "*" + elem
}
case *schema.EnumType:
if !(details.ptrOutput || details.output) {
return "*" + elem
}
}
}
return strings.TrimSuffix(elem, "Output") + "PtrOutput"
2020-11-03 07:02:56 +00:00
case *schema.EnumType:
return pkg.resolveEnumType(t) + "Output"
case *schema.ArrayType:
en := strings.TrimSuffix(pkg.outputTypeImpl(t.ElementType), "Output")
if en == "pulumi.Any" {
return "pulumi.ArrayOutput"
}
return en + "ArrayOutput"
case *schema.MapType:
en := strings.TrimSuffix(pkg.outputTypeImpl(t.ElementType), "Output")
if en == "pulumi.Any" {
return "pulumi.MapOutput"
}
return en + "MapOutput"
case *schema.ObjectType:
return pkg.resolveObjectType(t) + "Output"
case *schema.ResourceType:
return pkg.resolveResourceType(t) + "Output"
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return pkg.outputTypeImpl(t.UnderlyingType)
}
return pkg.tokenToType(t.Token) + "Output"
case *schema.UnionType:
2020-11-03 07:02:56 +00:00
// If the union is actually a relaxed enum type, use the underlying
// type for the output instead
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.outputTypeImpl(typ.ElementType)
2020-11-03 07:02:56 +00:00
}
}
// TODO(pdg): union types
return "pulumi.AnyOutput"
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
case *schema.InputType:
// We can't make output types for input types. We instead strip the input and try again.
return pkg.outputTypeImpl(t.ElementType)
default:
switch t {
case schema.BoolType:
return "pulumi.BoolOutput"
case schema.IntType:
return "pulumi.IntOutput"
case schema.NumberType:
return "pulumi.Float64Output"
case schema.StringType:
return "pulumi.StringOutput"
case schema.ArchiveType:
return "pulumi.ArchiveOutput"
case schema.AssetType:
2020-01-23 18:00:18 +00:00
return "pulumi.AssetOrArchiveOutput"
case schema.JSONType:
fallthrough
case schema.AnyType:
return "pulumi.AnyOutput"
}
}
panic(fmt.Errorf("unexpected type %T", t))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func isAssetOrArchive(t schema.Type) bool {
switch t {
case schema.ArchiveType, schema.AssetType:
return true
default:
return false
}
}
func (pkg *pkgContext) genericElementType(schemaType schema.Type) (string, bool) {
switch schemaType {
case schema.StringType:
return "string", true
case schema.BoolType:
return "bool", true
case schema.IntType:
return "int", true
case schema.NumberType:
return "float64", true
case schema.ArchiveType:
return "pulumi.Archive", true
case schema.AssetType:
return "pulumi.AssetOrArchive", true
default:
switch schemaType := schemaType.(type) {
case *schema.ObjectType:
return pkg.resolveObjectType(schemaType), false
case *schema.EnumType:
return pkg.resolveEnumType(schemaType), true
case *schema.ResourceType:
return pkg.resolveResourceType(schemaType), false
case *schema.TokenType:
return pkg.genericElementType(schemaType.UnderlyingType)
case *schema.ArrayType:
elementType, _ := pkg.genericElementType(schemaType.ElementType)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return "[]" + elementType, false
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
case *schema.MapType:
elementType, _ := pkg.genericElementType(schemaType.ElementType)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return "map[string]" + elementType, false
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
case *schema.UnionType:
for _, e := range schemaType.ElementTypes {
if enumType, ok := e.(*schema.EnumType); ok {
return pkg.genericElementType(enumType.ElementType)
}
}
return "any", true
default:
return "any", true
}
}
}
// genericOutputTypeImpl is similar to outputTypeImpl, but it generates the generic variant.
// for example instead of pulumi.StringOutput, it generates pulumix.Output[string]
func (pkg *pkgContext) genericOutputTypeImpl(t schema.Type) string {
switch t := t.(type) {
case *schema.OptionalType:
elementType, isPrimitive := pkg.genericElementType(t.ElementType)
if elementType == "any" {
return fmt.Sprintf("pulumix.Output[%s]", elementType)
}
if isPrimitive {
// for example OptionalType{StringType} becomes pulumix.Output[*string]
return fmt.Sprintf("pulumix.Output[*%s]", elementType)
}
if pkg.isExternalReference(t.ElementType) {
_, details := pkg.contextForExternalReference(t.ElementType)
switch t.ElementType.(type) {
case *schema.ObjectType:
if !details.ptrOutput {
return "*" + elementType
}
case *schema.EnumType:
if !(details.ptrOutput || details.output) {
return "*" + elementType
}
}
}
return pkg.genericOutputTypeImpl(t.ElementType)
case *schema.EnumType:
elementType, _ := pkg.genericElementType(t)
return fmt.Sprintf("pulumix.Output[%s]", elementType)
case *schema.ArrayType:
elementType, isPrimitive := pkg.genericElementType(t.ElementType)
if isPrimitive {
return fmt.Sprintf("pulumix.ArrayOutput[%s]", elementType)
}
// for non-primitive types such as objects and resources
// use GArrayOutput[Type, TypeOutput]
return fmt.Sprintf("pulumix.GArrayOutput[%s, %sOutput]", elementType, elementType)
case *schema.MapType:
elementType, isPrimitive := pkg.genericElementType(t.ElementType)
if isPrimitive {
return fmt.Sprintf("pulumix.MapOutput[%s]", elementType)
}
// for non-primitive types such as objects and resources
// use GMapOutput[Type, TypeOutput]
return fmt.Sprintf("pulumix.GMapOutput[%s, %sOutput]", elementType, elementType)
case *schema.ObjectType:
objectTypeName, _ := pkg.genericElementType(t)
return fmt.Sprintf("pulumix.GPtrOutput[%s, %sOutput]", objectTypeName, objectTypeName)
case *schema.ResourceType:
resourceTypeName, _ := pkg.genericElementType(t)
// element type of a ResourceOutput is Resource
return fmt.Sprintf("pulumix.GPtrOutput[%s, %sOutput]", resourceTypeName, resourceTypeName)
case *schema.TokenType:
// Use the underlying type for now.
if t.UnderlyingType != nil {
return pkg.genericOutputType(t.UnderlyingType)
}
tokenType := pkg.tokenToType(t.Token)
return fmt.Sprintf("pulumix.Output[%s]", tokenType)
case *schema.UnionType:
// If the union is actually a relaxed enum type, use the underlying
// type for the enum instead
for _, e := range t.ElementTypes {
if typ, ok := e.(*schema.EnumType); ok {
return pkg.genericOutputTypeImpl(typ.ElementType)
}
}
// TODO(pdg): union types
return "pulumix.Output[interface{}]"
case *schema.InputType:
// We can't make output types for input types. We instead strip the input and try again.
return pkg.genericOutputTypeImpl(t.ElementType)
default:
elementType, _ := pkg.genericElementType(t)
return fmt.Sprintf("pulumix.Output[%s]", elementType)
}
}
// outputType returns a reference to the Go output type that corresponds to the given schema type. For example, given
// a schema.String, outputType returns "pulumi.String", and given a *schema.ObjectType with the token pkg:mod:Name,
// outputType returns "mod.NameOutput" or "NameOutput", depending on whether or not the object type lives in a
// different module than the one associated with the receiver.
func (pkg *pkgContext) outputType(t schema.Type) string {
return pkg.outputTypeImpl(codegen.ResolvedType(t))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// genericOutputType returns a reference to the Go output type that corresponds to the given schema type.
// For example, given a schema.StringType, genericOutputType returns "pulumix.Output[string]",
// and given a *schema.ObjectType with the token pkg:mod:Name,
// outputType returns "mod.NameOutput" or "NameOutput", depending on whether the object type lives in a
// different module than the one associated with the receiver.
func (pkg *pkgContext) genericOutputType(t schema.Type) string {
return pkg.genericOutputTypeImpl(codegen.ResolvedType(t))
}
// toOutputMethod returns the name of the "ToXXXOutput" method for the given schema type. For example, given a
// schema.String, toOutputMethod returns "ToStringOutput", and given a *schema.ObjectType with the token pkg:mod:Name,
// outputType returns "ToNameOutput".
func (pkg *pkgContext) toOutputMethod(t schema.Type) string {
outputTypeName := pkg.outputType(t)
if i := strings.LastIndexByte(outputTypeName, '.'); i != -1 {
outputTypeName = outputTypeName[i+1:]
}
return "To" + outputTypeName
}
// printComment filters examples for the Go languages and prepends double forward slash to each line in the given
// comment. If indent is true, each line is indented with tab character. It returns the number of lines in the
// resulting comment. It guarantees that each line is terminated with newline character.
func printComment(w io.Writer, comment string, indent bool) int {
comment = codegen.FilterExamples(comment, "go")
lines := strings.Split(comment, "\n")
for len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
for _, l := range lines {
if indent {
fmt.Fprintf(w, "\t")
}
if l == "" {
fmt.Fprintf(w, "//\n")
} else {
fmt.Fprintf(w, "// %s\n", l)
}
}
return len(lines)
}
func printCommentWithDeprecationMessage(w io.Writer, comment, deprecationMessage string, indent bool) {
lines := printComment(w, comment, indent)
if deprecationMessage != "" {
if lines > 0 {
fmt.Fprintf(w, "//\n")
}
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
printComment(w, "Deprecated: "+deprecationMessage, indent)
}
}
2021-03-31 05:23:04 +00:00
func (pkg *pkgContext) genInputInterface(w io.Writer, name string) {
printComment(w, pkg.getInputUsage(name), false)
fmt.Fprintf(w, "type %sInput interface {\n", name)
fmt.Fprintf(w, "\tpulumi.Input\n\n")
fmt.Fprintf(w, "\tTo%sOutput() %sOutput\n", Title(name), name)
fmt.Fprintf(w, "\tTo%sOutputWithContext(context.Context) %sOutput\n", Title(name), name)
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) genEnumInputInterface(w io.Writer, name string, enumType *schema.EnumType) {
enumCases := []string{}
for _, enumCase := range enumType.Elements {
if enumCase.DeprecationMessage != "" {
// skip deprecated enum cases
continue
}
enumCases = append(enumCases, fmt.Sprintf("\t\t%s", enumCase.Name))
}
enumUsage := strings.Join([]string{
fmt.Sprintf("%sInput is an input type that accepts values of the %s enum", name, name),
fmt.Sprintf("A concrete instance of `%sInput` can be one of the following:", name),
"",
strings.Join(enumCases, "\n"),
" ",
}, "\n")
printComment(w, enumUsage, false)
fmt.Fprintf(w, "type %sInput interface {\n", name)
fmt.Fprintf(w, "\tpulumi.Input\n\n")
fmt.Fprintf(w, "\tTo%sOutput() %sOutput\n", Title(name), name)
fmt.Fprintf(w, "\tTo%sOutputWithContext(context.Context) %sOutput\n", Title(name), name)
fmt.Fprintf(w, "}\n\n")
}
2021-03-31 05:23:04 +00:00
func (pkg *pkgContext) getUsageForNestedType(name, baseTypeName string) string {
const defaultExampleFormat = "%sArgs{...}"
example := fmt.Sprintf(defaultExampleFormat, baseTypeName)
trimmer := func(typeName string) string {
if strings.HasSuffix(typeName, "Array") {
return typeName[:strings.LastIndex(typeName, "Array")]
}
if strings.HasSuffix(typeName, "Map") {
return typeName[:strings.LastIndex(typeName, "Map")]
}
return typeName
}
2021-03-31 05:23:04 +00:00
// If not a nested collection type, use the default example format
if trimmer(name) == name {
return example
}
if strings.HasSuffix(name, "Map") {
2021-03-31 05:23:04 +00:00
if pkg.schemaNames.Has(baseTypeName) {
return fmt.Sprintf("%s{ \"key\": %s }", name, example)
}
2021-03-31 05:23:04 +00:00
return fmt.Sprintf("%s{ \"key\": %s }", name, pkg.getUsageForNestedType(baseTypeName, trimmer(baseTypeName)))
}
if strings.HasSuffix(name, "Array") {
2021-03-31 05:23:04 +00:00
if pkg.schemaNames.Has(baseTypeName) {
return fmt.Sprintf("%s{ %s }", name, example)
}
2021-03-31 05:23:04 +00:00
return fmt.Sprintf("%s{ %s }", name, pkg.getUsageForNestedType(baseTypeName, trimmer(baseTypeName)))
}
return example
}
2021-03-31 05:23:04 +00:00
func (pkg *pkgContext) getInputUsage(name string) string {
if strings.HasSuffix(name, "Array") {
baseTypeName := name[:strings.LastIndex(name, "Array")]
return strings.Join([]string{
fmt.Sprintf("%sInput is an input type that accepts %s and %sOutput values.", name, name, name),
fmt.Sprintf("You can construct a concrete instance of `%sInput` via:", name),
"",
2021-03-31 05:23:04 +00:00
"\t\t " + pkg.getUsageForNestedType(name, baseTypeName),
" ",
}, "\n")
}
if strings.HasSuffix(name, "Map") {
baseTypeName := name[:strings.LastIndex(name, "Map")]
return strings.Join([]string{
fmt.Sprintf("%sInput is an input type that accepts %s and %sOutput values.", name, name, name),
fmt.Sprintf("You can construct a concrete instance of `%sInput` via:", name),
"",
2021-03-31 05:23:04 +00:00
"\t\t " + pkg.getUsageForNestedType(name, baseTypeName),
" ",
}, "\n")
}
if strings.HasSuffix(name, "Ptr") {
baseTypeName := name[:strings.LastIndex(name, "Ptr")]
return strings.Join([]string{
fmt.Sprintf("%sInput is an input type that accepts %sArgs, %s and %sOutput values.", name, baseTypeName, name, name),
fmt.Sprintf("You can construct a concrete instance of `%sInput` via:", name),
"",
fmt.Sprintf("\t\t %sArgs{...}", baseTypeName),
"",
" or:",
"",
"\t\t nil",
" ",
}, "\n")
}
return strings.Join([]string{
fmt.Sprintf("%sInput is an input type that accepts %sArgs and %sOutput values.", name, name, name),
fmt.Sprintf("You can construct a concrete instance of `%sInput` via:", name),
"",
fmt.Sprintf("\t\t %sArgs{...}", name),
" ",
}, "\n")
}
type genInputImplementationArgs struct {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
name string
receiverType string
elementType string
ptrMethods bool
toOutputMethods bool
usingGenericTypes bool
goPackageinfo GoPackageInfo
}
func (pkg *pkgContext) genInputImplementation(
w io.Writer,
name string,
receiverType string,
elementType string,
ptrMethods bool,
usingGenericTypes bool,
) {
genInputImplementationWithArgs(w, genInputImplementationArgs{
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
name: name,
receiverType: receiverType,
elementType: elementType,
ptrMethods: ptrMethods,
toOutputMethods: true,
usingGenericTypes: usingGenericTypes,
goPackageinfo: goPackageInfo(pkg.pkg),
})
}
func genInputImplementationWithArgs(w io.Writer, genArgs genInputImplementationArgs) {
name := genArgs.name
receiverType := genArgs.receiverType
elementType := genArgs.elementType
fmt.Fprintf(w, "func (%s) ElementType() reflect.Type {\n", receiverType)
[codegen/go] Remove ResourcePtr input/output types (#8449) These changes remove the `Ptr` variants of input/ouptut types for resources. A `TPtr` input or output is normally generated for `T` if `T` is present in an `optional(input(T))` or `optional(output(T))` and if the Go representation for `T` is not nilable. The generation of `Ptr` variants for resource types breaks the latter rule: the canonical representation of a resource type named `Foo` is a pointer to a struct type named `Foo` (i.e. `*Foo`). `Foo` itself is not a resource, as it does not implement the Go `Resource` interface. Because this representation already accommodates `nil` to indicate the lack of a value, we need not generate `FooPtr{Input,Output}` types. Besides being unnecessary, the implementation of `Ptr` types for resources was incorrect. Rather than using `**Foo` as their element type, these types use `*Foo`--identical to the element type used for the normal input/output types. Furthermore, the generated code for at least `FooOutput.ToFooPtrOutputWithContext` and `FooPtrOutput.Elem` was incorrect, making these types virtually unusable in practice. Finally, these `Ptr` types should never appear on input/output properties in practice, as the logic we use to generate input and output type references never generates them for `optional({input,output}(T)). Instead, it generates references to the standard input/output types. Though this is _technically_ a breaking change--it changes the set of exported types for any package that defines resources--I believe that in practice it will be invisible to users for the reasons stated above. These types are not usable, and were never referenced. This is preparatory work for #7943.
2021-11-23 18:24:56 +00:00
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s)(nil)).Elem()\n", elementType)
fmt.Fprintf(w, "}\n\n")
var hasToOutput bool
if genArgs.toOutputMethods {
fmt.Fprintf(w, "func (i %s) To%sOutput() %sOutput {\n", receiverType, Title(name), name)
fmt.Fprintf(w, "\treturn i.To%sOutputWithContext(context.Background())\n", Title(name))
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (i %s) To%sOutputWithContext(ctx context.Context) %sOutput {\n", receiverType, Title(name), name)
fmt.Fprintf(w, "\treturn pulumi.ToOutputWithContext(ctx, i).(%sOutput)\n", name)
fmt.Fprintf(w, "}\n\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !genArgs.usingGenericTypes {
// Generate 'ToOuput(context.Context) pulumix.Output[T]' method
// to satisfy pulumix.Input[T].
if genArgs.goPackageinfo.Generics == GenericsSettingSideBySide {
fmt.Fprintf(w, "func (i %s) ToOutput(ctx context.Context) pulumix.Output[%s] {\n", receiverType, elementType)
fmt.Fprintf(w, "\treturn pulumix.Output[%s]{\n", elementType)
fmt.Fprintf(w, "\t\tOutputState: i.To%sOutputWithContext(ctx).OutputState,\n", Title(name))
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "}\n\n")
hasToOutput = true
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
} else {
// Generate 'ToOuput(context.Context) pulumix.Output[T]' method which lifts the receiver type *T
// to satisfy pulumix.Input[*T].
fmt.Fprintf(w, "func (i *%s) ToOutput(ctx context.Context) pulumix.Output[*%s] {\n", receiverType, receiverType)
fmt.Fprint(w, "\treturn pulumix.Val(i)\n")
fmt.Fprint(w, "}\n\n")
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if genArgs.ptrMethods && !genArgs.usingGenericTypes {
fmt.Fprintf(w, "func (i %s) To%sPtrOutput() %sPtrOutput {\n", receiverType, Title(name), name)
fmt.Fprintf(w, "\treturn i.To%sPtrOutputWithContext(context.Background())\n", Title(name))
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (i %s) To%sPtrOutputWithContext(ctx context.Context) %sPtrOutput {\n", receiverType, Title(name), name)
if strings.HasSuffix(receiverType, "Args") {
fmt.Fprintf(w, "\treturn pulumi.ToOutputWithContext(ctx, i).(%[1]sOutput).To%[1]sPtrOutputWithContext(ctx)\n", name)
} else {
fmt.Fprintf(w, "\treturn pulumi.ToOutputWithContext(ctx, i).(%sPtrOutput)\n", name)
}
fmt.Fprintf(w, "}\n\n")
if !hasToOutput {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// Generate 'ToOuput(context.Context) pulumix.Output[*T]' method
// to satisfy pulumix.Input[*T].
if genArgs.goPackageinfo.Generics == GenericsSettingSideBySide {
fmt.Fprintf(w, "func (i %s) ToOutput(ctx context.Context) pulumix.Output[*%s] {\n", receiverType, elementType)
fmt.Fprintf(w, "\treturn pulumix.Output[*%s]{\n", elementType)
fmt.Fprintf(w, "\t\tOutputState: i.To%sPtrOutputWithContext(ctx).OutputState,\n", Title(name))
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "}\n\n")
}
}
}
}
func (pkg *pkgContext) genOutputType(w io.Writer, baseName, elementType string, ptrMethods, usingGenericTypes bool) {
fmt.Fprintf(w, "type %sOutput struct { *pulumi.OutputState }\n\n", baseName)
fmt.Fprintf(w, "func (%sOutput) ElementType() reflect.Type {\n", baseName)
[codegen/go] Remove ResourcePtr input/output types (#8449) These changes remove the `Ptr` variants of input/ouptut types for resources. A `TPtr` input or output is normally generated for `T` if `T` is present in an `optional(input(T))` or `optional(output(T))` and if the Go representation for `T` is not nilable. The generation of `Ptr` variants for resource types breaks the latter rule: the canonical representation of a resource type named `Foo` is a pointer to a struct type named `Foo` (i.e. `*Foo`). `Foo` itself is not a resource, as it does not implement the Go `Resource` interface. Because this representation already accommodates `nil` to indicate the lack of a value, we need not generate `FooPtr{Input,Output}` types. Besides being unnecessary, the implementation of `Ptr` types for resources was incorrect. Rather than using `**Foo` as their element type, these types use `*Foo`--identical to the element type used for the normal input/output types. Furthermore, the generated code for at least `FooOutput.ToFooPtrOutputWithContext` and `FooPtrOutput.Elem` was incorrect, making these types virtually unusable in practice. Finally, these `Ptr` types should never appear on input/output properties in practice, as the logic we use to generate input and output type references never generates them for `optional({input,output}(T)). Instead, it generates references to the standard input/output types. Though this is _technically_ a breaking change--it changes the set of exported types for any package that defines resources--I believe that in practice it will be invisible to users for the reasons stated above. These types are not usable, and were never referenced. This is preparatory work for #7943.
2021-11-23 18:24:56 +00:00
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s)(nil)).Elem()\n", elementType)
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutput() %[1]sOutput {\n", baseName, Title(baseName))
fmt.Fprintf(w, "\treturn o\n")
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutputWithContext(ctx context.Context) %[1]sOutput {\n", baseName, Title(baseName))
fmt.Fprintf(w, "\treturn o\n")
fmt.Fprintf(w, "}\n\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if ptrMethods && !usingGenericTypes {
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutput() %[1]sPtrOutput {\n", baseName, Title(baseName))
fmt.Fprintf(w, "\treturn o.To%sPtrOutputWithContext(context.Background())\n", Title(baseName))
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutputWithContext(ctx context.Context) %[1]sPtrOutput {\n", baseName, Title(baseName))
fmt.Fprintf(w, "\treturn o.ApplyTWithContext(ctx, func(_ context.Context, v %[1]s) *%[1]s {\n", elementType)
fmt.Fprintf(w, "\t\treturn &v\n")
fmt.Fprintf(w, "\t}).(%sPtrOutput)\n", baseName)
fmt.Fprintf(w, "}\n\n")
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// Generate 'ToOuput(context.Context) pulumix.Output[T]' method
// to satisfy pulumix.Input[T].
goPackageInfo := goPackageInfo(pkg.pkg)
[go/sdk-gen] Fix generics-only option missing ToOutput(...) methods (#14584) # Description PR #14492 removed `ToOutput(...)` methods for output types when generating non-generic SDK variants. The fix there was added to only include these when `side-by-side` is enabled, which implicitly included `generics-only` except for a _single_ place where that wasn't the case 😓 (see comment below in `gen.go`) This PR fixes issue and includes tests for go sdkgen where `generics` setting is set to `generics-only`: - `output-funcs-go-generics-only` - `plain-and-default-go-generics-only` - `secrets-go-generics-only` - `simple-enum-schema-go-generics-only` - `simple-plain-schema-go-generics-only` ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-16 18:41:57 +00:00
if goPackageInfo.Generics == GenericsSettingSideBySide || goPackageInfo.Generics == GenericsSettingGenericsOnly {
fmt.Fprintf(w, "func (o %sOutput) ToOutput(ctx context.Context) pulumix.Output[%s] {\n", baseName, elementType)
fmt.Fprintf(w, "\treturn pulumix.Output[%s]{\n", elementType)
fmt.Fprintf(w, "\t\tOutputState: o.OutputState,\n")
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "}\n\n")
}
}
func (pkg *pkgContext) genArrayOutput(w io.Writer, baseName, elementType string) {
pkg.genOutputType(w, baseName+"Array", "[]"+elementType, false, false)
fmt.Fprintf(w, "func (o %[1]sArrayOutput) Index(i pulumi.IntInput) %[1]sOutput {\n", baseName)
fmt.Fprintf(w, "\treturn pulumi.All(o, i).ApplyT(func (vs []interface{}) %s {\n", elementType)
fmt.Fprintf(w, "\t\treturn vs[0].([]%s)[vs[1].(int)]\n", elementType)
fmt.Fprintf(w, "\t}).(%sOutput)\n", baseName)
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) genMapOutput(w io.Writer, baseName, elementType string) {
pkg.genOutputType(w, baseName+"Map", "map[string]"+elementType, false, false)
fmt.Fprintf(w, "func (o %[1]sMapOutput) MapIndex(k pulumi.StringInput) %[1]sOutput {\n", baseName)
fmt.Fprintf(w, "\treturn pulumi.All(o, k).ApplyT(func (vs []interface{}) %s{\n", elementType)
fmt.Fprintf(w, "\t\treturn vs[0].(map[string]%s)[vs[1].(string)]\n", elementType)
fmt.Fprintf(w, "\t}).(%sOutput)\n", baseName)
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) genPtrOutput(w io.Writer, baseName, elementType string) {
pkg.genOutputType(w, baseName+"Ptr", "*"+elementType, false, false)
fmt.Fprintf(w, "func (o %[1]sPtrOutput) Elem() %[1]sOutput {\n", baseName)
fmt.Fprintf(w, "\treturn o.ApplyT(func(v *%[1]s) %[1]s {\n", baseName)
fmt.Fprint(w, "\t\tif v != nil {\n")
fmt.Fprintf(w, "\t\t\treturn *v\n")
fmt.Fprint(w, "\t\t}\n")
fmt.Fprintf(w, "\t\tvar ret %s\n", baseName)
fmt.Fprint(w, "\t\treturn ret\n")
fmt.Fprintf(w, "\t}).(%sOutput)\n", baseName)
fmt.Fprint(w, "}\n\n")
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genEnum(w io.Writer, enumType *schema.EnumType, usingGenericTypes bool) error {
name := pkg.tokenToEnum(enumType.Token)
2020-11-03 07:02:56 +00:00
2020-11-09 21:05:59 +00:00
mod := pkg.tokenToPackage(enumType.Token)
modPkg, ok := pkg.packages[mod]
contract.Assertf(ok, "Context for module %q not found", mod)
2020-11-03 07:02:56 +00:00
printCommentWithDeprecationMessage(w, enumType.Comment, "", false)
elementArgsType := pkg.argsTypeImpl(enumType.ElementType)
elementGoType := pkg.typeString(enumType.ElementType)
asFuncName := strings.TrimPrefix(elementArgsType, "pulumi.")
fmt.Fprintf(w, "type %s %s\n\n", name, elementGoType)
2020-11-03 07:02:56 +00:00
2021-01-19 17:55:40 +00:00
fmt.Fprintln(w, "const (")
2020-11-03 07:02:56 +00:00
for _, e := range enumType.Elements {
printCommentWithDeprecationMessage(w, e.Comment, e.DeprecationMessage, true)
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
elementName := e.Name
2020-11-03 07:02:56 +00:00
if e.Name == "" {
elementName = fmt.Sprintf("%v", e.Value)
}
enumName, err := makeSafeEnumName(elementName, name)
if err != nil {
return err
}
e.Name = enumName
contract.Assertf(!modPkg.names.Has(e.Name), "Name collision for enum constant: %s for %s",
2020-11-09 21:05:59 +00:00
e.Name, enumType.Token)
2020-11-03 07:02:56 +00:00
switch reflect.TypeOf(e.Value).Kind() {
case reflect.String:
fmt.Fprintf(w, "%s = %s(%q)\n", e.Name, name, e.Value)
2020-11-03 07:02:56 +00:00
default:
fmt.Fprintf(w, "%s = %s(%v)\n", e.Name, name, e.Value)
}
}
fmt.Fprintln(w, ")")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if usingGenericTypes {
// no need to generate the rest of the enum output/input types
return nil
}
details := pkg.detailsForType(enumType)
if details.input || details.ptrInput {
inputType := pkg.inputType(enumType)
pkg.genEnumInputFuncs(w, name, enumType, elementArgsType, inputType, asFuncName)
}
if details.output || details.ptrOutput {
pkg.genEnumOutputTypes(w, name, elementArgsType, elementGoType, asFuncName)
}
if details.input || details.ptrInput {
pkg.genEnumInputTypes(w, name, enumType, elementGoType)
}
// Generate the array input.
if details.arrayInput {
pkg.genInputInterface(w, name+"Array")
fmt.Fprintf(w, "type %[1]sArray []%[1]s\n\n", name)
pkg.genInputImplementation(w, name+"Array", name+"Array", "[]"+name, false, usingGenericTypes)
}
// Generate the map input.
if details.mapInput {
pkg.genInputInterface(w, name+"Map")
fmt.Fprintf(w, "type %[1]sMap map[string]%[1]s\n\n", name)
pkg.genInputImplementation(w, name+"Map", name+"Map", "map[string]"+name, false, usingGenericTypes)
}
// Generate the array output
if details.arrayOutput {
pkg.genArrayOutput(w, name, name)
}
// Generate the map output.
if details.mapOutput {
pkg.genMapOutput(w, name, name)
}
return nil
2020-11-03 07:02:56 +00:00
}
func (pkg *pkgContext) genEnumOutputTypes(w io.Writer, name, elementArgsType, elementGoType, asFuncName string) {
pkg.genOutputType(w, name, name, true, false)
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutput() %[3]sOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.To%sOutputWithContext(context.Background())\n", asFuncName)
fmt.Fprint(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutputWithContext(ctx context.Context) %[3]sOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.ApplyTWithContext(ctx, func(_ context.Context, e %s) %s {\n", name, elementGoType)
fmt.Fprintf(w, "return %s(e)\n", elementGoType)
fmt.Fprintf(w, "}).(%sOutput)\n", elementArgsType)
fmt.Fprint(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutput() %[3]sPtrOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.To%sPtrOutputWithContext(context.Background())\n", asFuncName)
fmt.Fprint(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutputWithContext(ctx context.Context) %[3]sPtrOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.ApplyTWithContext(ctx, func(_ context.Context, e %s) *%s {\n", name, elementGoType)
fmt.Fprintf(w, "v := %s(e)\n", elementGoType)
fmt.Fprintf(w, "return &v\n")
fmt.Fprintf(w, "}).(%sPtrOutput)\n", elementArgsType)
fmt.Fprint(w, "}\n\n")
pkg.genPtrOutput(w, name, name)
fmt.Fprintf(w, "func (o %[1]sPtrOutput) To%[2]sPtrOutput() %[3]sPtrOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.To%sPtrOutputWithContext(context.Background())\n", asFuncName)
fmt.Fprint(w, "}\n\n")
fmt.Fprintf(w, "func (o %[1]sPtrOutput) To%[2]sPtrOutputWithContext(ctx context.Context) %[3]sPtrOutput {\n", name, asFuncName, elementArgsType)
fmt.Fprintf(w, "return o.ApplyTWithContext(ctx, func(_ context.Context, e *%s) *%s {\n", name, elementGoType)
fmt.Fprintf(w, "if e == nil {\n")
fmt.Fprintf(w, "return nil\n")
fmt.Fprintf(w, "}\n")
fmt.Fprintf(w, "v := %s(*e)\n", elementGoType)
fmt.Fprintf(w, "return &v\n")
fmt.Fprintf(w, "}).(%sPtrOutput)\n", elementArgsType)
fmt.Fprint(w, "}\n\n")
}
func (pkg *pkgContext) genEnumInputTypes(w io.Writer, name string, enumType *schema.EnumType, elementGoType string) {
pkg.genEnumInputInterface(w, name, enumType)
typeName := cgstrings.Camel(name)
fmt.Fprintf(w, "var %sPtrType = reflect.TypeOf((**%s)(nil)).Elem()\n", typeName, name)
fmt.Fprintln(w)
fmt.Fprintf(w, "type %sPtrInput interface {\n", name)
fmt.Fprint(w, "pulumi.Input\n\n")
fmt.Fprintf(w, "To%[1]sPtrOutput() %[1]sPtrOutput\n", name)
fmt.Fprintf(w, "To%[1]sPtrOutputWithContext(context.Context) %[1]sPtrOutput\n", name)
fmt.Fprintf(w, "}\n")
fmt.Fprintln(w)
fmt.Fprintf(w, "type %sPtr %s\n", typeName, elementGoType)
fmt.Fprintln(w)
fmt.Fprintf(w, "func %[1]sPtr(v %[2]s) %[1]sPtrInput {\n", name, elementGoType)
fmt.Fprintf(w, "return (*%sPtr)(&v)\n", typeName)
fmt.Fprintf(w, "}\n")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (*%sPtr) ElementType() reflect.Type {\n", typeName)
fmt.Fprintf(w, "return %sPtrType\n", typeName)
fmt.Fprintf(w, "}\n")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (in *%[1]sPtr) To%[2]sPtrOutput() %[2]sPtrOutput {\n", typeName, name)
fmt.Fprintf(w, "return pulumi.ToOutput(in).(%sPtrOutput)\n", name)
fmt.Fprintf(w, "}\n")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (in *%[1]sPtr) To%[2]sPtrOutputWithContext(ctx context.Context) %[2]sPtrOutput {\n", cgstrings.Camel(name), name)
fmt.Fprintf(w, "return pulumi.ToOutputWithContext(ctx, in).(%sPtrOutput)\n", name)
fmt.Fprintf(w, "}\n")
fmt.Fprintln(w)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// ToOutput implementation for pulumix.Input.
fmt.Fprintf(w, "func (in *%sPtr) ToOutput(ctx context.Context) pulumix.Output[*%s] {\n", typeName, name)
fmt.Fprintf(w, "\treturn pulumix.Output[*%s]{\n", name)
fmt.Fprintf(w, "\t\tOutputState: in.To%sPtrOutputWithContext(ctx).OutputState,\n", name)
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) genEnumInputFuncs(w io.Writer, typeName string, enum *schema.EnumType, elementArgsType, inputType, asFuncName string) {
fmt.Fprintln(w)
2020-11-03 07:02:56 +00:00
fmt.Fprintf(w, "func (%s) ElementType() reflect.Type {\n", typeName)
fmt.Fprintf(w, "return reflect.TypeOf((*%s)(nil)).Elem()\n", typeName)
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[1]sOutput() %[1]sOutput {\n", typeName)
fmt.Fprintf(w, "return pulumi.ToOutput(e).(%sOutput)\n", typeName)
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[1]sOutputWithContext(ctx context.Context) %[1]sOutput {\n", typeName)
fmt.Fprintf(w, "return pulumi.ToOutputWithContext(ctx, e).(%sOutput)\n", typeName)
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[1]sPtrOutput() %[1]sPtrOutput {\n", typeName)
fmt.Fprintf(w, "return e.To%sPtrOutputWithContext(context.Background())\n", typeName)
2020-11-03 07:02:56 +00:00
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[1]sPtrOutputWithContext(ctx context.Context) %[1]sPtrOutput {\n", typeName)
fmt.Fprintf(w, "return %[1]s(e).To%[1]sOutputWithContext(ctx).To%[1]sPtrOutputWithContext(ctx)\n", typeName)
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[2]sOutput() %[3]sOutput {\n", typeName, asFuncName, elementArgsType)
fmt.Fprintf(w, "return pulumi.ToOutput(%[1]s(e)).(%[1]sOutput)\n", elementArgsType)
2020-11-03 07:02:56 +00:00
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[2]sOutputWithContext(ctx context.Context) %[3]sOutput {\n", typeName, asFuncName, elementArgsType)
fmt.Fprintf(w, "return pulumi.ToOutputWithContext(ctx, %[1]s(e)).(%[1]sOutput)\n", elementArgsType)
2020-11-03 07:02:56 +00:00
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[2]sPtrOutput() %[3]sPtrOutput {\n", typeName, asFuncName, elementArgsType)
fmt.Fprintf(w, "return %s(e).To%sPtrOutputWithContext(context.Background())\n", elementArgsType, asFuncName)
2020-11-03 07:02:56 +00:00
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
fmt.Fprintf(w, "func (e %[1]s) To%[2]sPtrOutputWithContext(ctx context.Context) %[3]sPtrOutput {\n", typeName, asFuncName, elementArgsType)
fmt.Fprintf(w, "return %[1]s(e).To%[2]sOutputWithContext(ctx).To%[2]sPtrOutputWithContext(ctx)\n", elementArgsType, asFuncName)
2020-11-03 07:02:56 +00:00
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) assignProperty(
w io.Writer,
p *schema.Property,
object,
value string,
indirectAssign bool,
useGenericTypes bool,
) {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
t := strings.TrimSuffix(pkg.typeString(p.Type), "Input")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericTypes {
t = "pulumix.Val"
if isOptionalType(reduceInputType(p.Type)) {
t = "pulumix.Ptr"
}
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
switch codegen.UnwrapType(p.Type).(type) {
case *schema.EnumType:
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !useGenericTypes {
t = ""
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
if codegen.IsNOptionalInput(p.Type) {
if t != "" {
value = fmt.Sprintf("%s(%s)", t, value)
}
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\t%s.%s = %s\n", object, pkg.fieldName(nil, p), value)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else if indirectAssign {
tmpName := cgstrings.Camel(p.Name) + "_"
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
fmt.Fprintf(w, "%s := %s\n", tmpName, value)
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "%s.%s = &%s\n", object, pkg.fieldName(nil, p), tmpName)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else {
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "%s.%s = %s\n", object, pkg.fieldName(nil, p), value)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
}
2022-11-04 00:12:20 +00:00
func (pkg *pkgContext) fieldName(r *schema.Resource, field *schema.Property) string {
contract.Assertf(field != nil, "Field must not be nil")
2022-11-04 00:12:20 +00:00
return fieldName(pkg, r, field)
}
func (pkg *pkgContext) genPlainType(w io.Writer, name, comment, deprecationMessage string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
properties []*schema.Property,
) {
printCommentWithDeprecationMessage(w, comment, deprecationMessage, false)
fmt.Fprintf(w, "type %s struct {\n", name)
for _, p := range properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name)
}
fmt.Fprintf(w, "}\n\n")
}
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
// genGenericPlainType is the same as genPlainType, but used for generic variant SDKs
// where it maintains optionalness of property types
func (pkg *pkgContext) genGenericPlainType(w io.Writer, name, comment, deprecationMessage string,
properties []*schema.Property,
) {
printCommentWithDeprecationMessage(w, comment, deprecationMessage, false)
fmt.Fprintf(w, "type %s struct {\n", name)
for _, p := range properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), pkg.plainGenericInputType(p.Type), p.Name)
}
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) genObjectDefaultFunc(w io.Writer, name string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
properties []*schema.Property,
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
useGenericTypes bool,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
) error {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
defaults := []*schema.Property{}
for _, p := range properties {
if p.DefaultValue != nil || codegen.IsProvideDefaultsFuncRequired(p.Type) {
defaults = append(defaults, p)
}
}
// There are no defaults, so we don't need to generate a defaults function.
if len(defaults) == 0 {
return nil
}
printComment(w, fmt.Sprintf("%s sets the appropriate defaults for %s", ProvideDefaultsMethodName, name), false)
fmt.Fprintf(w, "func (val *%[1]s) %[2]s() *%[1]s {\n", name, ProvideDefaultsMethodName)
fmt.Fprintf(w, "if val == nil {\n return nil\n}\n")
fmt.Fprintf(w, "tmp := *val\n")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
for _, p := range defaults {
if p.DefaultValue != nil {
if isNilType(p.Type) {
fmt.Fprintf(w, "if tmp.%s == nil {\n", pkg.fieldName(nil, p))
} else {
fmt.Fprintf(w, "if %s.IsZero(tmp.%s) {\n", pkg.internalModuleName, pkg.fieldName(nil, p))
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
err := pkg.setDefaultValue(w, p.DefaultValue, codegen.UnwrapType(p.Type), func(w io.Writer, dv string) error {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.assignProperty(w, p, "tmp", dv, !p.IsRequired(), useGenericTypes)
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
return nil
})
if err != nil {
return err
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
fmt.Fprintf(w, "}\n")
} else if funcName := pkg.provideDefaultsFuncName(p.Type); funcName != "" {
var member string
if codegen.IsNOptionalInput(p.Type) {
// f := fmt.Sprintf("func(v %[1]s) %[1]s { return *v.%[2]s() }", name, funcName)
2022-11-04 00:12:20 +00:00
// member = fmt.Sprintf("tmp.%[1]s.ApplyT(%[2]s)", pkg.fieldName(nil, p), f)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else {
2022-11-04 00:12:20 +00:00
member = fmt.Sprintf("tmp.%[1]s.%[2]s()", pkg.fieldName(nil, p), funcName)
sigil := ""
if p.IsRequired() {
sigil = "*"
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.assignProperty(w, p, "tmp", sigil+member, false, useGenericTypes)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
fmt.Fprintln(w)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else {
panic(fmt.Sprintf("Property %s[%s] should not be in the default list", p.Name, p.Type.String()))
}
}
fmt.Fprintf(w, "return &tmp\n}\n")
return nil
}
// The name of the method used to instantiate defaults.
const ProvideDefaultsMethodName = "Defaults"
func (pkg *pkgContext) provideDefaultsFuncName(typ schema.Type) string {
if !codegen.IsProvideDefaultsFuncRequired(typ) {
return ""
}
return ProvideDefaultsMethodName
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genInputTypes(
w io.Writer,
t *schema.ObjectType,
details *typeDetails,
usingGenericTypes bool,
) error {
contract.Assertf(t.IsInputShape(), "Object type must have input shape")
name := pkg.tokenToType(t.Token)
// Generate the plain inputs.
if details.input {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !usingGenericTypes {
pkg.genInputInterface(w, name)
}
inputName := name + "Args"
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.genInputArgsStruct(w, inputName, t, usingGenericTypes)
if !pkg.disableObjectDefaults {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genObjectDefaultFunc(w, inputName, t.Properties, usingGenericTypes); err != nil {
return err
}
}
pkg.genInputImplementation(w, name, inputName, name, details.ptrInput, usingGenericTypes)
}
// Generate the pointer input.
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.ptrInput && !usingGenericTypes {
2021-03-31 05:23:04 +00:00
pkg.genInputInterface(w, name+"Ptr")
ptrTypeName := cgstrings.Camel(name) + "PtrType"
fmt.Fprintf(w, "type %s %sArgs\n\n", ptrTypeName, name)
fmt.Fprintf(w, "func %[1]sPtr(v *%[1]sArgs) %[1]sPtrInput {", name)
fmt.Fprintf(w, "\treturn (*%s)(v)\n", ptrTypeName)
fmt.Fprintf(w, "}\n\n")
pkg.genInputImplementation(w, name+"Ptr", "*"+ptrTypeName, "*"+name, false, usingGenericTypes)
}
// Generate the array input.
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.arrayInput && !pkg.names.Has(name+"Array") && !usingGenericTypes {
2021-03-31 05:23:04 +00:00
pkg.genInputInterface(w, name+"Array")
fmt.Fprintf(w, "type %[1]sArray []%[1]sInput\n\n", name)
pkg.genInputImplementation(w, name+"Array", name+"Array", "[]"+name, false, usingGenericTypes)
}
// Generate the map input.
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.mapInput && !pkg.names.Has(name+"Map") && !usingGenericTypes {
2021-03-31 05:23:04 +00:00
pkg.genInputInterface(w, name+"Map")
fmt.Fprintf(w, "type %[1]sMap map[string]%[1]sInput\n\n", name)
pkg.genInputImplementation(w, name+"Map", name+"Map", "map[string]"+name, false, usingGenericTypes)
}
return nil
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genInputArgsStruct(
w io.Writer,
typeName string,
t *schema.ObjectType,
useGenericTypes bool,
) {
contract.Assertf(t.IsInputShape(), "Object type must have input shape")
printComment(w, t.Comment, false)
fmt.Fprintf(w, "type %s struct {\n", typeName)
for _, p := range t.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputType := pkg.typeString(p.Type)
if useGenericTypes {
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
if p.Plain {
inputType = pkg.plainGenericInputType(p.Type)
} else {
inputType = pkg.genericInputType(p.Type)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
}
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), inputType, p.Name)
}
fmt.Fprintf(w, "}\n\n")
}
type genOutputTypesArgs struct {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
t *schema.ObjectType
usingGenericTypes bool
// optional type name override
name string
output bool
}
func (pkg *pkgContext) genOutputTypes(w io.Writer, genArgs genOutputTypesArgs) {
t := genArgs.t
details := pkg.detailsForType(t)
contract.Assertf(!t.IsInputShape(), "Object type must not have input shape")
name := genArgs.name
if name == "" {
name = pkg.tokenToType(t.Token)
}
if details.output || genArgs.output {
printComment(w, t.Comment, false)
pkg.genOutputType(w,
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
name, /* baseName */
name, /* elementType */
details.ptrInput, /* ptrMethods */
genArgs.usingGenericTypes, /* usingGenericTypes */
)
for _, p := range t.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false)
outputType, applyType := pkg.outputType(p.Type), pkg.typeString(p.Type)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if genArgs.usingGenericTypes {
outputType = pkg.genericOutputType(p.Type)
}
2022-11-04 00:12:20 +00:00
propName := pkg.fieldName(nil, p)
switch strings.ToLower(p.Name) {
case "elementtype", "issecret":
propName = "Get" + propName
}
fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, propName, outputType)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !genArgs.usingGenericTypes {
fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n",
name, applyType, pkg.fieldName(nil, p), outputType)
} else {
needsCast := genericTypeNeedsExplicitCasting(outputType)
if !needsCast {
fmt.Fprintf(w, "\treturn pulumix.Apply[%s](o, func (v %s) %s { return v.%s })\n",
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
name, name, pkg.plainGenericInputType(p.Type), pkg.fieldName(nil, p))
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
} else {
fmt.Fprintf(w, "\tvalue := pulumix.Apply[%s](o, func (v %s) %s { return v.%s })\n",
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
name, name, pkg.plainGenericInputType(p.Type), pkg.fieldName(nil, p))
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
fmt.Fprintf(w, "\treturn %s{OutputState: value.OutputState}\n", outputType)
}
}
fmt.Fprintf(w, "}\n\n")
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.ptrOutput && !genArgs.usingGenericTypes {
pkg.genPtrOutput(w, name, name)
for _, p := range t.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false)
optionalType := codegen.OptionalType(p)
outputType, applyType := pkg.outputType(optionalType), pkg.typeString(optionalType)
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
deref := ""
// If the property was required, but the type it needs to return is an explicit pointer type, then we need
// to dereference it, unless it is a resource type which should remain a pointer.
_, isResourceType := p.Type.(*schema.ResourceType)
if p.IsRequired() && applyType[0] == '*' && !isResourceType {
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
deref = "&"
}
2021-03-11 05:04:30 +00:00
funcName := Title(p.Name)
// Avoid conflicts with Output interface for lifted attributes.
switch funcName {
case "IsSecret", "ElementType":
funcName = funcName + "Prop"
}
fmt.Fprintf(w, "func (o %sPtrOutput) %s() %s {\n", name, funcName, outputType)
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
fmt.Fprintf(w, "\treturn o.ApplyT(func (v *%s) %s {\n", name, applyType)
fmt.Fprintf(w, "\t\tif v == nil {\n")
fmt.Fprintf(w, "\t\t\treturn nil\n")
fmt.Fprintf(w, "\t\t}\n")
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\t\treturn %sv.%s\n", deref, pkg.fieldName(nil, p))
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
fmt.Fprintf(w, "\t}).(%s)\n", outputType)
fmt.Fprintf(w, "}\n\n")
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.arrayOutput && !pkg.names.Has(name+"Array") && !genArgs.usingGenericTypes {
pkg.genArrayOutput(w, name, name)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.mapOutput && !pkg.names.Has(name+"Map") && !genArgs.usingGenericTypes {
pkg.genMapOutput(w, name, name)
}
}
func goPrimitiveValue(value interface{}) (string, error) {
v := reflect.ValueOf(value)
if v.Kind() == reflect.Interface {
v = v.Elem()
}
switch v.Kind() {
case reflect.Bool:
if v.Bool() {
return "true", nil
}
return "false", nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
return strconv.FormatInt(v.Int(), 10), nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
return strconv.FormatUint(v.Uint(), 10), nil
case reflect.Float32, reflect.Float64:
value := strconv.FormatFloat(v.Float(), 'f', -1, 64)
if !strings.ContainsRune(value, '.') {
value += ".0"
}
return value, nil
case reflect.String:
return fmt.Sprintf("%q", v.String()), nil
default:
return "", fmt.Errorf("unsupported default value of type %T", value)
}
}
func (pkg *pkgContext) getConstValue(cv interface{}) (string, error) {
var val string
if cv != nil {
v, err := goPrimitiveValue(cv)
if err != nil {
return "", err
}
val = v
}
return val, nil
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
// setDefaultValue generates a statement that assigns the default value of a
// property to a variable.
//
// The assign function is invoked with an expression that evaluates to the
// default value.
// It should return a statement that assigns that default value to the relevant
// variable.
// For example,
//
// err := pkg.setDefaultValue(w, dv, t, func(w io.Writer, value string) error {
// _, err := fmt.Fprintf(w, "v.%s = %s", fieldName, value)
// return err
// })
func (pkg *pkgContext) setDefaultValue(
w io.Writer,
dv *schema.DefaultValue,
t schema.Type,
assign func(io.Writer, string) error,
) error {
contract.Requiref(dv.Value != nil || len(dv.Environment) > 0,
"dv", "must have either a value or an environment variable override")
var val string
if dv.Value != nil {
v, err := goPrimitiveValue(dv.Value)
if err != nil {
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
return err
}
val = v
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
switch t.(type) {
case *schema.EnumType:
typeName := strings.TrimSuffix(pkg.typeString(codegen.UnwrapType(t)), "Input")
val = fmt.Sprintf("%s(%s)", typeName, val)
}
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
if len(dv.Environment) == 0 {
// If there's no environment variable override,
// assign and we're done.
return assign(w, val)
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
// For environment variable override, we will assign only
// if the environment variable is set.
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
parser, typ := "nil", "string"
switch codegen.UnwrapType(t).(type) {
case *schema.ArrayType:
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
parser, typ = pkg.internalModuleName+".ParseEnvStringArray", "pulumi.StringArray"
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
}
switch t {
case schema.BoolType:
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
parser, typ = pkg.internalModuleName+".ParseEnvBool", "bool"
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
case schema.IntType:
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
parser, typ = pkg.internalModuleName+".ParseEnvInt", "int"
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
case schema.NumberType:
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
parser, typ = pkg.internalModuleName+".ParseEnvFloat", "float64"
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
if val == "" {
// If there's no explicit default value,
// use nil so that we can assign conditionally.
val = "nil"
}
// Roughly, we generate:
//
// if d := internal.getEnvOrDefault(defaultValue, parser, "ENV_VAR"); d != nil {
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
// $assign(d.(type))
// }
//
// This has the following effect:
//
// - if an environment variable was set, read from that
// - if a default value was specified, use that
// - otherwise, leave the variable unset
fmt.Fprintf(w, "if d := %s.GetEnvOrDefault(%s, %s", pkg.internalModuleName, val, parser)
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
for _, e := range dv.Environment {
fmt.Fprintf(w, ", %q", e)
}
fmt.Fprintf(w, "); d != nil {\n\t")
if err := assign(w, fmt.Sprintf("d.(%v)", typ)); err != nil {
return err
}
fmt.Fprintf(w, "}\n")
return nil
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genResource(
w io.Writer,
r *schema.Resource,
generateResourceContainerTypes bool,
useGenericVariant bool,
) error {
name := disambiguatedResourceName(r, pkg)
printCommentWithDeprecationMessage(w, r.Comment, r.DeprecationMessage, false)
fmt.Fprintf(w, "type %s struct {\n", name)
switch {
case r.IsProvider:
fmt.Fprintf(w, "\tpulumi.ProviderResourceState\n\n")
case r.IsComponent:
fmt.Fprintf(w, "\tpulumi.ResourceState\n\n")
default:
fmt.Fprintf(w, "\tpulumi.CustomResourceState\n\n")
}
var secretProps []*schema.Property
var secretInputProps []*schema.Property
for _, p := range r.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
outputType := pkg.outputType(p.Type)
if useGenericVariant {
outputType = pkg.genericOutputType(p.Type)
}
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), outputType, p.Name)
if p.Secret {
secretProps = append(secretProps, p)
}
}
fmt.Fprintf(w, "}\n\n")
// Create a constructor function that registers a new instance of this resource.
fmt.Fprintf(w, "// New%s registers a new resource with the given unique name, arguments, and options.\n", name)
fmt.Fprintf(w, "func New%s(ctx *pulumi.Context,\n", name)
fmt.Fprintf(w, "\tname string, args *%[1]sArgs, opts ...pulumi.ResourceOption) (*%[1]s, error) {\n", name)
// Ensure required arguments are present.
2020-11-03 07:02:56 +00:00
hasRequired := false
for _, p := range r.InputProperties {
if p.IsRequired() {
2020-11-03 07:02:56 +00:00
hasRequired = true
}
}
// Various validation checks
fmt.Fprintf(w, "\tif args == nil {\n")
2020-11-03 07:02:56 +00:00
if !hasRequired {
fmt.Fprintf(w, "\t\targs = &%sArgs{}\n", name)
} else {
fmt.Fprintln(w, "\t\treturn nil, errors.New(\"missing one or more required arguments\")")
}
fmt.Fprintf(w, "\t}\n\n")
2020-11-03 07:02:56 +00:00
// Produce the inputs.
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
// Check all required inputs are present
2020-11-03 07:02:56 +00:00
for _, p := range r.InputProperties {
if p.IsRequired() && isNilType(p.Type) && p.DefaultValue == nil {
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\tif args.%s == nil {\n", pkg.fieldName(r, p))
fmt.Fprintf(w, "\t\treturn nil, errors.New(\"invalid value for required argument '%s'\")\n", pkg.fieldName(r, p))
fmt.Fprintf(w, "\t}\n")
2020-11-03 07:02:56 +00:00
}
if p.Secret {
secretInputProps = append(secretInputProps, p)
}
2020-11-03 07:02:56 +00:00
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
assign := func(w io.Writer, p *schema.Property, value string) {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.assignProperty(w, p, "args", value, isNilType(p.Type), useGenericVariant)
}
for _, p := range r.InputProperties {
if p.ConstValue != nil {
v, err := pkg.getConstValue(p.ConstValue)
if err != nil {
return err
}
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
assign(w, p, v)
} else if p.DefaultValue != nil {
if isNilType(p.Type) {
fmt.Fprintf(w, "\tif args.%s == nil {\n", pkg.fieldName(r, p))
} else {
fmt.Fprintf(w, "\tif %s.IsZero(args.%s) {\n", pkg.internalModuleName, pkg.fieldName(r, p))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
err := pkg.setDefaultValue(w, p.DefaultValue, codegen.UnwrapType(p.Type), func(w io.Writer, dv string) error {
assign(w, p, dv)
return nil
})
if err != nil {
return err
}
fmt.Fprintf(w, "\t}\n")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else if name := pkg.provideDefaultsFuncName(p.Type); name != "" && !pkg.disableObjectDefaults {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
optionalDeref := ""
if p.IsRequired() {
optionalDeref = "*"
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
toOutputMethod := pkg.toOutputMethod(p.Type)
outputType := pkg.outputType(p.Type)
resolvedType := pkg.typeString(codegen.ResolvedType(p.Type))
2022-11-04 00:12:20 +00:00
originalValue := fmt.Sprintf("args.%s.%s()", pkg.fieldName(r, p), toOutputMethod)
valueWithDefaults := fmt.Sprintf("%[1]v.ApplyT(func (v %[2]s) %[2]s { return %[3]sv.%[4]s() }).(%[5]s)",
originalValue, resolvedType, optionalDeref, name, outputType)
if p.Plain {
2022-11-04 00:12:20 +00:00
valueWithDefaults = fmt.Sprintf("args.%v.Defaults()", pkg.fieldName(r, p))
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericVariant {
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "if args.%s != nil {\n", pkg.fieldName(r, p))
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
t := p.Type
optionalPointer := ""
if isOptionalType(reduceInputType(t)) && !isArrayType(codegen.UnwrapType(t)) && !isMapType(codegen.UnwrapType(t)) {
optionalPointer = "*"
}
inputType := pkg.genericInputTypeImpl(t)
if strings.HasPrefix(inputType, "*") {
optionalPointer = ""
}
fmt.Fprintf(w, "args.%s = pulumix.Apply(args.%s, func(o %s%s) %s%s { return o.Defaults() })\n",
pkg.fieldName(r, p),
pkg.fieldName(r, p),
optionalPointer,
inputType,
optionalPointer,
inputType)
fmt.Fprintf(w, "}\n")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !p.IsRequired() {
fmt.Fprintf(w, "if args.%s != nil {\n", pkg.fieldName(r, p))
fmt.Fprintf(w, "args.%[1]s = %s\n", pkg.fieldName(r, p), valueWithDefaults)
fmt.Fprint(w, "}\n")
} else {
fmt.Fprintf(w, "args.%[1]s = %s\n", pkg.fieldName(r, p), valueWithDefaults)
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
}
}
// Set any defined aliases.
if len(r.Aliases) > 0 {
fmt.Fprintf(w, "\taliases := pulumi.Aliases([]pulumi.Alias{\n")
for _, alias := range r.Aliases {
s := "\t\t{\n"
if alias.Type != nil {
s += fmt.Sprintf("\t\t\tType: pulumi.String(%q),\n", *alias.Type)
}
s += "\t\t},\n"
fmt.Fprint(w, s)
}
fmt.Fprintf(w, "\t})\n")
fmt.Fprintf(w, "\topts = append(opts, aliases)\n")
}
// Setup secrets
for _, p := range secretInputProps {
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\tif args.%s != nil {\n", pkg.fieldName(r, p))
fix(sdkgen/go): illegal cast in resource constructors when secret-wrapping input arguments Codegen for wrapping input properties as secrets performed an incorrect cast, as seen in Pulumi's AWS classic SDK. Using the sample program and the resource constructor described in #11664 as our test case, from `pulumi-aws/sdk/v5/go/aws/secretmanager/secretVersion.go`: ```go func NewSecretVersion(ctx *pulumi.Context, name string, args *SecretVersionArgs, opts ...pulumi.ResourceOption) (*SecretVersion, error) { if args == nil { return nil, errors.New("missing one or more required arguments") } if args.SecretId == nil { return nil, errors.New("invalid value for required argument 'SecretId'") } if args.SecretBinary != nil { 82: args.SecretBinary = pulumi.ToSecret(args.SecretBinary).(pulumi.StringPtrOutput) } if args.SecretString != nil { 85: args.SecretString = pulumi.ToSecret(args.SecretString).(pulumi.StringPtrOutput) } ``` `args.SecretBinary` is of type `pulumi.StringPtrInput` and `pulumi.ToSecret` returns `pulumi.Output` returns its input as an Output-wrapped value marked secret. As `StringPtrInput` is an interface accepting multiple input types, the return value would be either `pulumi.StringOutput` `pulumi.StringPtrOutput`. These are both concrete types, and casting to the incorrect one would panic. Fortunately we can cast back to the arg's type, as verified by building the new codegen and testing the Pulumi program in #11664. This should handle regular inputs and plain inputs. The new codegen below converts an input type `T` to `pulumi.Output`, then casts back to `T`. ```go func NewSecretVersion(ctx *pulumi.Context, // ... if args.SecretBinary != nil { 82: args.SecretBinary = pulumi.ToSecret(args.SecretBinary).(pulumi.StringPtrInput) } if args.SecretString != nil { 85: args.SecretString = pulumi.ToSecret(args.SecretString).(pulumi.StringPtrInput) } ```
2022-12-16 23:39:54 +00:00
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !useGenericVariant {
fmt.Fprintf(w, "\t\targs.%[1]s = pulumi.ToSecret(args.%[1]s).(%[2]s)\n",
pkg.fieldName(r, p),
pkg.typeString(p.Type))
} else {
fmt.Fprintf(w, "\t\tuntypedSecretValue := pulumi.ToSecret(args.%s.ToOutput(ctx.Context()).Untyped())\n",
pkg.fieldName(r, p))
t := p.Type
optionalPointer := ""
if isOptionalType(reduceInputType(t)) && !isArrayType(codegen.UnwrapType(t)) && !isMapType(codegen.UnwrapType(t)) {
optionalPointer = "*"
}
inputType := pkg.genericInputTypeImpl(t)
if strings.HasPrefix(inputType, "*") {
optionalPointer = ""
}
fmt.Fprintf(w, "\t\targs.%s = pulumix.MustConvertTyped[%s%s](untypedSecretValue)\n",
pkg.fieldName(r, p),
optionalPointer,
inputType)
}
fmt.Fprintf(w, "\t}\n")
}
if len(secretProps) > 0 {
fmt.Fprintf(w, "\tsecrets := pulumi.AdditionalSecretOutputs([]string{\n")
for _, sp := range secretProps {
fmt.Fprintf(w, "\t\t\t%q,\n", sp.Name)
}
fmt.Fprintf(w, "\t})\n")
fmt.Fprintf(w, "\topts = append(opts, secrets)\n")
}
// Setup replaceOnChange
replaceOnChangesProps, errList := r.ReplaceOnChanges()
for _, err := range errList {
cmdutil.Diag().Warningf(&diag.Diag{Message: err.Error()})
}
replaceOnChangesStrings := schema.PropertyListJoinToString(replaceOnChangesProps,
func(x string) string { return x })
if len(replaceOnChangesProps) > 0 {
fmt.Fprint(w, "\treplaceOnChanges := pulumi.ReplaceOnChanges([]string{\n")
for _, p := range replaceOnChangesStrings {
fmt.Fprintf(w, "\t\t%q,\n", p)
}
fmt.Fprint(w, "\t})\n")
fmt.Fprint(w, "\topts = append(opts, replaceOnChanges)\n")
}
err := pkg.GenPkgDefaultsOptsCall(w, false /*invoke*/)
if err != nil {
return err
}
// Finally make the call to registration.
fmt.Fprintf(w, "\tvar resource %s\n", name)
if r.IsComponent {
fmt.Fprintf(w, "\terr := ctx.RegisterRemoteComponentResource(\"%s\", name, args, &resource, opts...)\n", r.Token)
} else {
fmt.Fprintf(w, "\terr := ctx.RegisterResource(\"%s\", name, args, &resource, opts...)\n", r.Token)
}
fmt.Fprintf(w, "\tif err != nil {\n")
fmt.Fprintf(w, "\t\treturn nil, err\n")
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "\treturn &resource, nil\n")
fmt.Fprintf(w, "}\n\n")
// Emit a factory function that reads existing instances of this resource.
if !r.IsProvider && !r.IsComponent {
fmt.Fprintf(w, "// Get%[1]s gets an existing %[1]s resource's state with the given name, ID, and optional\n", name)
fmt.Fprintf(w, "// state properties that are used to uniquely qualify the lookup (nil if not required).\n")
fmt.Fprintf(w, "func Get%s(ctx *pulumi.Context,\n", name)
fmt.Fprintf(w, "\tname string, id pulumi.IDInput, state *%[1]sState, opts ...pulumi.ResourceOption) (*%[1]s, error) {\n", name)
fmt.Fprintf(w, "\tvar resource %s\n", name)
fmt.Fprintf(w, "\terr := ctx.ReadResource(\"%s\", name, id, state, &resource, opts...)\n", r.Token)
fmt.Fprintf(w, "\tif err != nil {\n")
fmt.Fprintf(w, "\t\treturn nil, err\n")
fmt.Fprintf(w, "\t}\n")
fmt.Fprintf(w, "\treturn &resource, nil\n")
fmt.Fprintf(w, "}\n\n")
// Emit the state types for get methods.
fmt.Fprintf(w, "// Input properties used for looking up and filtering %s resources.\n", name)
fmt.Fprintf(w, "type %sState struct {\n", cgstrings.Camel(name))
if r.StateInputs != nil {
for _, p := range r.StateInputs.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
2022-11-04 00:12:20 +00:00
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), pkg.typeString(codegen.ResolvedType(codegen.OptionalType(p))), p.Name)
}
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "type %sState struct {\n", name)
if r.StateInputs != nil {
for _, p := range r.StateInputs.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputType := pkg.inputType(p.Type)
if useGenericVariant {
inputType = pkg.genericInputType(codegen.OptionalType(p))
}
fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(r, p), inputType)
}
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (%sState) ElementType() reflect.Type {\n", name)
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%sState)(nil)).Elem()\n", cgstrings.Camel(name))
fmt.Fprintf(w, "}\n\n")
}
// Emit the args types.
fmt.Fprintf(w, "type %sArgs struct {\n", cgstrings.Camel(name))
for _, p := range r.InputProperties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputTypeName := pkg.typeString(codegen.ResolvedType(p.Type))
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), inputTypeName, p.Name)
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "// The set of arguments for constructing a %s resource.\n", name)
fmt.Fprintf(w, "type %sArgs struct {\n", name)
for _, p := range r.InputProperties {
typ := p.Type
if p.Plain {
typ = codegen.MapOptionalType(typ, func(typ schema.Type) schema.Type {
if input, ok := typ.(*schema.InputType); ok {
return input.ElementType
}
return typ
})
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputTypeName := pkg.inputType(typ)
if p.Plain {
inputTypeName = pkg.typeString(typ)
}
if useGenericVariant {
if p.Plain {
inputTypeName = pkg.typeString(codegen.ResolvedType(typ))
} else {
inputTypeName = pkg.genericInputType(typ)
}
}
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(r, p), inputTypeName)
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (%sArgs) ElementType() reflect.Type {\n", name)
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%sArgs)(nil)).Elem()\n", cgstrings.Camel(name))
fmt.Fprintf(w, "}\n")
// Emit resource methods.
for _, method := range r.Methods {
methodName := Title(method.Name)
f := method.Function
var objectReturnType *schema.ObjectType
if f.ReturnType != nil {
if objectType, ok := f.ReturnType.(*schema.ObjectType); ok && objectType != nil {
objectReturnType = objectType
}
}
liftReturn := pkg.liftSingleValueMethodReturns && objectReturnType != nil && len(objectReturnType.Properties) == 1
var args []*schema.Property
if f.Inputs != nil {
for _, arg := range f.Inputs.InputShape.Properties {
if arg.Name == "__self__" {
continue
}
args = append(args, arg)
}
}
// Now emit the method signature.
argsig := "ctx *pulumi.Context"
if len(args) > 0 {
argsig = fmt.Sprintf("%s, args *%s%sArgs", argsig, name, methodName)
}
var retty string
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
if f.ReturnTypePlain {
if objectReturnType == nil {
t := pkg.typeString(codegen.ResolvedType(f.ReturnType))
retty = fmt.Sprintf("(o %s, e error)", t)
} else {
retty = fmt.Sprintf("(o %s%sResult, e error)", name, methodName)
}
} else if objectReturnType == nil {
retty = "error"
} else if liftReturn {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericVariant {
retty = fmt.Sprintf("(%s, error)", pkg.genericOutputType(objectReturnType.Properties[0].Type))
} else {
retty = fmt.Sprintf("(%s, error)", pkg.outputType(objectReturnType.Properties[0].Type))
}
} else {
retty = fmt.Sprintf("(%s%sResultOutput, error)", name, methodName)
}
fmt.Fprintf(w, "\n")
printCommentWithDeprecationMessage(w, f.Comment, f.DeprecationMessage, false)
fmt.Fprintf(w, "func (r *%s) %s(%s) %s {\n", name, methodName, argsig, retty)
resultVar := "_"
if objectReturnType != nil {
resultVar = "out"
}
// Make a map of inputs to pass to the runtime function.
inputsVar := "nil"
if len(args) > 0 {
inputsVar = "args"
}
// Now simply invoke the runtime function with the arguments.
outputsType := "pulumi.AnyOutput"
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
if objectReturnType != nil || f.ReturnTypePlain {
if liftReturn {
outputsType = fmt.Sprintf("%s%sResultOutput", cgstrings.Camel(name), methodName)
} else {
outputsType = fmt.Sprintf("%s%sResultOutput", name, methodName)
}
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
if !f.ReturnTypePlain {
fmt.Fprintf(w, "\t%s, err := ctx.Call(%q, %s, %s{}, r)\n", resultVar, f.Token, inputsVar, outputsType)
}
if f.ReturnTypePlain {
// single-value returning methods use a magic property "res" on the wire
property := ""
if objectReturnType == nil {
property = cgstrings.UppercaseFirst("res")
}
fmt.Fprintf(w, "\tinternal.CallPlain(ctx, %q, %s, %s{}, r, %q, reflect.ValueOf(&o), &e)\n",
f.Token, inputsVar, outputsType, property)
fmt.Fprintf(w, "\treturn\n")
} else if objectReturnType == nil {
fmt.Fprintf(w, "\treturn err\n")
} else if liftReturn {
// Check the error before proceeding.
fmt.Fprintf(w, "\tif err != nil {\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericVariant {
fmt.Fprint(w, "\t\treturn nil, err\n")
} else {
fmt.Fprintf(w, "\t\treturn %s{}, err\n", pkg.outputType(objectReturnType.Properties[0].Type))
}
fmt.Fprintf(w, "\t}\n")
// Get the name of the method to return the output
fmt.Fprintf(w, "\treturn %s.(%s).%s(), nil\n", resultVar, cgstrings.Camel(outputsType), Title(objectReturnType.Properties[0].Name))
} else {
// Check the error before proceeding.
fmt.Fprintf(w, "\tif err != nil {\n")
fmt.Fprintf(w, "\t\treturn %s{}, err\n", outputsType)
fmt.Fprintf(w, "\t}\n")
// Return the result.
fmt.Fprintf(w, "\treturn %s.(%s), nil\n", resultVar, outputsType)
}
fmt.Fprintf(w, "}\n")
// If there are argument and/or return types, emit them.
if len(args) > 0 {
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "type %s%sArgs struct {\n", cgstrings.Camel(name), methodName)
for _, p := range args {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputTypeName := pkg.typeString(codegen.ResolvedType(p.Type))
if useGenericVariant {
inputTypeName = pkg.genericInputType(codegen.ResolvedType(p.Type))
}
fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), inputTypeName, p.Name)
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "// The set of arguments for the %s method of the %s resource.\n", methodName, name)
fmt.Fprintf(w, "type %s%sArgs struct {\n", name, methodName)
for _, p := range args {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
inputTypeName := pkg.typeString(p.Type)
if useGenericVariant {
inputTypeName = pkg.genericInputType(codegen.ResolvedType(p.Type))
}
fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(nil, p), inputTypeName)
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (%s%sArgs) ElementType() reflect.Type {\n", name, methodName)
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s%sArgs)(nil)).Elem()\n", cgstrings.Camel(name), methodName)
fmt.Fprintf(w, "}\n\n")
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
if objectReturnType != nil || f.ReturnTypePlain {
outputStructName := name
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
var comment string
var properties []*schema.Property
if f.ReturnTypePlain && objectReturnType == nil {
properties = []*schema.Property{
{
Name: "res",
Type: f.ReturnType,
Plain: true,
},
}
} else {
properties = objectReturnType.Properties
comment = objectReturnType.Comment
}
// Don't export the result struct if we're lifting the value
if liftReturn {
outputStructName = cgstrings.Camel(name)
}
fmt.Fprintf(w, "\n")
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
pkg.genPlainType(w, fmt.Sprintf("%s%sResult", outputStructName, methodName), comment, "", properties)
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "type %s%sResultOutput struct{ *pulumi.OutputState }\n\n", outputStructName, methodName)
fmt.Fprintf(w, "func (%s%sResultOutput) ElementType() reflect.Type {\n", outputStructName, methodName)
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s%sResult)(nil)).Elem()\n", outputStructName, methodName)
fmt.Fprintf(w, "}\n")
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
for _, p := range properties {
fmt.Fprintf(w, "\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
outputTypeName := pkg.outputType(p.Type)
if useGenericVariant {
outputTypeName = pkg.genericOutputType(p.Type)
}
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false)
fmt.Fprintf(w, "func (o %s%sResultOutput) %s() %s {\n", outputStructName, methodName, Title(p.Name),
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
outputTypeName)
if !useGenericVariant {
fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s%sResult) %s { return v.%s }).(%s)\n", outputStructName, methodName,
pkg.typeString(codegen.ResolvedType(p.Type)), Title(p.Name), outputTypeName)
} else {
fmt.Fprintf(w, "\treturn pulumix.Apply(o, func(v %s%sResult) %s { return v.%s })\n", outputStructName, methodName,
pkg.typeString(codegen.ResolvedType(p.Type)), Title(p.Name))
}
fmt.Fprintf(w, "}\n")
}
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !useGenericVariant {
// Emit the resource input type.
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "type %sInput interface {\n", name)
fmt.Fprintf(w, "\tpulumi.Input\n\n")
fmt.Fprintf(w, "\tTo%[1]sOutput() %[1]sOutput\n", name)
fmt.Fprintf(w, "\tTo%[1]sOutputWithContext(ctx context.Context) %[1]sOutput\n", name)
fmt.Fprintf(w, "}\n\n")
pkg.genInputImplementation(w, name, "*"+name, "*"+name, false, false)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if generateResourceContainerTypes && !r.IsProvider {
// Generate the resource array input.
pkg.genInputInterface(w, name+"Array")
fmt.Fprintf(w, "type %[1]sArray []%[1]sInput\n\n", name)
pkg.genInputImplementation(w, name+"Array", name+"Array", "[]*"+name, false, false)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// Generate the resource map input.
pkg.genInputInterface(w, name+"Map")
fmt.Fprintf(w, "type %[1]sMap map[string]%[1]sInput\n\n", name)
pkg.genInputImplementation(w, name+"Map", name+"Map", "map[string]*"+name, false, false)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
outputElementType := "*" + name
if useGenericVariant {
outputElementType = name
}
pkg.genOutputType(w, name, outputElementType, false, useGenericVariant)
// Emit chaining methods for the resource output type.
for _, p := range r.Properties {
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false)
outputType := pkg.outputType(p.Type)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericVariant {
outputType = pkg.genericOutputType(p.Type)
}
2022-11-04 00:12:20 +00:00
propName := pkg.fieldName(r, p)
switch strings.ToLower(p.Name) {
case "elementtype", "issecret":
propName = "Get" + propName
}
fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, propName, outputType)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !useGenericVariant {
fmt.Fprintf(w, "\treturn o.ApplyT(func (v *%s) %s { return v.%s }).(%s)\n",
name, outputType, pkg.fieldName(r, p), outputType)
} else {
needsCast := genericTypeNeedsExplicitCasting(outputType)
elementType := pkg.typeString(codegen.ResolvedType(p.Type))
if strings.HasPrefix(outputType, "pulumix.GPtrOutput") && !strings.HasPrefix(elementType, "*") {
elementType = "*" + elementType
}
isOptionalAssetOrArchive := isOptionalType(reduceInputType(p.Type)) &&
isAssetOrArchive(codegen.UnwrapType(p.Type))
if isOptionalAssetOrArchive && !strings.HasPrefix(elementType, "*") {
elementType = "*" + elementType
}
if needsCast {
// needs an explicit cast operation to align the types
fmt.Fprintf(w, "\tvalue := pulumix.Apply[%s](o, func (v %s) %s { return v.%s })\n",
name, name, outputType, pkg.fieldName(r, p))
fmt.Fprintf(w, "\tunwrapped := pulumix.Flatten[%s, %s](value)\n",
elementType, outputType)
fmt.Fprintf(w, "\treturn %s{OutputState: unwrapped.OutputState}\n", outputType)
} else {
fmt.Fprintf(w, "\tvalue := pulumix.Apply[%s](o, func (v %s) %s { return v.%s })\n",
name, name, outputType, pkg.fieldName(r, p))
if !p.Plain {
fmt.Fprintf(w, "\treturn pulumix.Flatten[%s, %s](value)\n",
elementType, outputType)
} else {
fmt.Fprintf(w, "\treturn value\n")
}
}
}
fmt.Fprintf(w, "}\n\n")
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if generateResourceContainerTypes && !r.IsProvider && !useGenericVariant {
pkg.genArrayOutput(w, name, "*"+name)
pkg.genMapOutput(w, name, "*"+name)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.genResourceRegistrations(w, r, generateResourceContainerTypes, useGenericVariant)
return nil
}
func goPackageInfo(packageReference schema.PackageReference) GoPackageInfo {
if packageReference == nil {
return GoPackageInfo{}
}
def, err := packageReference.Definition()
contract.AssertNoErrorf(err, "Could not load definition for %q", packageReference.Name())
contract.AssertNoErrorf(def.ImportLanguages(map[string]schema.Language{"go": Importer}),
"Could not import languages")
if info, ok := def.Language["go"].(GoPackageInfo); ok {
return info
}
return GoPackageInfo{}
}
func NeedsGoOutputVersion(f *schema.Function) bool {
goInfo := goPackageInfo(f.PackageReference)
if goInfo.DisableFunctionOutputVersions {
return false
}
return f.ReturnType != nil
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
func (pkg *pkgContext) genFunctionCodeFile(f *schema.Function) (string, error) {
importsAndAliases := map[string]string{}
pkg.getImports(f, importsAndAliases)
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumi"] = ""
importsAndAliases[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
buffer := &bytes.Buffer{}
goInfo := goPackageInfo(pkg.pkg)
var imports []string
if f.ReturnType != nil {
imports = []string{"context", "reflect"}
if goInfo.Generics == GenericsSettingSideBySide {
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
}
}
2023-07-06 20:20:04 +00:00
pkg.genHeader(buffer, imports, importsAndAliases, false /* isUtil */)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
emitGenericVariant := false
if err := pkg.genFunction(buffer, f, emitGenericVariant); err != nil {
return "", err
}
pkg.genFunctionOutputVersion(buffer, f, emitGenericVariant)
return buffer.String(), nil
}
func (pkg *pkgContext) genGenericVariantFunctionCodeFile(f *schema.Function) (string, error) {
importsAndAliases := map[string]string{}
pkg.getImports(f, importsAndAliases)
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumi"] = ""
if f.NeedsOutputVersion() {
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
}
importsAndAliases[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
buffer := &bytes.Buffer{}
var imports []string
if NeedsGoOutputVersion(f) {
imports = []string{"context", "reflect"}
}
pkg.genHeader(buffer, imports, importsAndAliases, false /* isUtil */)
useGenericTypes := true
if err := pkg.genFunction(buffer, f, useGenericTypes); err != nil {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return "", err
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.genFunctionOutputVersion(buffer, f, useGenericTypes)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return buffer.String(), nil
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genFunction(w io.Writer, f *schema.Function, useGenericTypes bool) error {
name := pkg.functionName(f)
if f.MultiArgumentInputs {
return fmt.Errorf("go SDK-gen does not implement MultiArgumentInputs for function '%s'", f.Token)
}
var objectReturnType *schema.ObjectType
if f.ReturnType != nil {
if objectType, ok := f.ReturnType.(*schema.ObjectType); ok {
objectReturnType = objectType
} else {
// TODO: remove when we add support for generalized return type for go
return fmt.Errorf("go sdk-gen doesn't support non-Object return types for function %s", f.Token)
}
}
printCommentWithDeprecationMessage(w, f.Comment, f.DeprecationMessage, false)
// Now, emit the function signature.
argsig := "ctx *pulumi.Context"
if f.Inputs != nil {
argsig = fmt.Sprintf("%s, args *%sArgs", argsig, name)
}
var retty string
if objectReturnType == nil {
retty = "error"
} else {
retty = fmt.Sprintf("(*%sResult, error)", name)
}
fmt.Fprintf(w, "func %s(%s, opts ...pulumi.InvokeOption) %s {\n", name, argsig, retty)
// Make a map of inputs to pass to the runtime function.
var inputsVar string
if f.Inputs == nil {
inputsVar = "nil"
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
} else if codegen.IsProvideDefaultsFuncRequired(f.Inputs) && !pkg.disableObjectDefaults {
inputsVar = "args.Defaults()"
} else {
inputsVar = "args"
}
// Now simply invoke the runtime function with the arguments.
var outputsType string
if objectReturnType == nil {
outputsType = "struct{}"
} else {
outputsType = name + "Result"
}
err := pkg.GenPkgDefaultsOptsCall(w, true /*invoke*/)
if err != nil {
return err
}
fmt.Fprintf(w, "\tvar rv %s\n", outputsType)
fmt.Fprintf(w, "\terr := ctx.Invoke(\"%s\", %s, &rv, opts...)\n", f.Token, inputsVar)
if objectReturnType == nil {
fmt.Fprintf(w, "\treturn err\n")
} else {
// Check the error before proceeding.
fmt.Fprintf(w, "\tif err != nil {\n")
fmt.Fprintf(w, "\t\treturn nil, err\n")
fmt.Fprintf(w, "\t}\n")
// Return the result.
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
var retValue string
if codegen.IsProvideDefaultsFuncRequired(objectReturnType) && !pkg.disableObjectDefaults {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
retValue = "rv.Defaults()"
} else {
retValue = "&rv"
}
fmt.Fprintf(w, "\treturn %s, nil\n", retValue)
}
fmt.Fprintf(w, "}\n")
// If there are argument and/or return types, emit them.
if f.Inputs != nil {
fmt.Fprintf(w, "\n")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
fnInputsName := pkg.functionArgsTypeName(f)
pkg.genPlainType(w, fnInputsName, f.Inputs.Comment, "", f.Inputs.Properties)
if codegen.IsProvideDefaultsFuncRequired(f.Inputs) && !pkg.disableObjectDefaults {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genObjectDefaultFunc(w, fnInputsName, f.Inputs.Properties, useGenericTypes); err != nil {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return err
}
}
}
if objectReturnType != nil {
fmt.Fprintf(w, "\n")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
fnOutputsName := pkg.functionResultTypeName(f)
pkg.genPlainType(w, fnOutputsName, objectReturnType.Comment, "", objectReturnType.Properties)
if codegen.IsProvideDefaultsFuncRequired(objectReturnType) && !pkg.disableObjectDefaults {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genObjectDefaultFunc(w, fnOutputsName, objectReturnType.Properties, useGenericTypes); err != nil {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return err
}
}
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return nil
}
func (pkg *pkgContext) functionName(f *schema.Function) string {
// If the function starts with New or Get, it will conflict; so rename them.
name, hasName := pkg.functionNames[f]
if !hasName {
panic(fmt.Sprintf("No function name found for %v", f))
}
return name
}
func (pkg *pkgContext) functionArgsTypeName(f *schema.Function) string {
name := pkg.functionName(f)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return name + "Args"
}
func (pkg *pkgContext) functionResultTypeName(f *schema.Function) string {
name := pkg.functionName(f)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
return name + "Result"
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func genericTypeNeedsExplicitCasting(outputType string) bool {
return strings.HasPrefix(outputType, "pulumix.ArrayOutput") ||
strings.HasPrefix(outputType, "pulumix.MapOutput") ||
strings.HasPrefix(outputType, "pulumix.GPtrOutput") ||
strings.HasPrefix(outputType, "pulumix.GArrayOutput") ||
strings.HasPrefix(outputType, "pulumix.GMapOutput")
}
func (pkg *pkgContext) genFunctionOutputGenericVersion(w io.Writer, f *schema.Function) {
originalName := pkg.functionName(f)
name := originalName + "Output"
originalResultTypeName := pkg.functionResultTypeName(f)
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
resultTypeName := originalResultTypeName + "Output"
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
code := ""
if f.Inputs != nil {
code = `
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func ${fn}Output(ctx *pulumi.Context, args ${fn}OutputArgs, opts ...pulumi.InvokeOption) ${outputType} {
outputResult := pulumix.ApplyErr[*${fn}Args](args.ToOutput(), func(plainArgs *${fn}Args) (*${fn}Result, error) {
return ${fn}(ctx, plainArgs, opts...)
})
return pulumix.Cast[${outputType}, *${fn}Result](outputResult)
}
`
} else {
code = `
func ${fn}Output(ctx *pulumi.Context, opts ...pulumi.InvokeOption) ${outputType} {
outputResult := pulumix.ApplyErr[int](pulumix.Val(0), func(_ int) (*${fn}Result, error) {
return ${fn}(ctx, opts...)
})
return pulumix.Cast[${outputType}, *${fn}Result](outputResult)
}
`
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
code = strings.ReplaceAll(code, "${fn}", originalName)
code = strings.ReplaceAll(code, "${outputType}", resultTypeName)
fmt.Fprint(w, code)
if f.Inputs != nil {
useGenericTypes := true
pkg.genInputArgsStruct(w, name+"Args", f.Inputs.InputShape, useGenericTypes)
receiverType := name + "Args"
plainType := originalName + "Args"
fmt.Fprintf(w, "func (args %s) ToOutput() pulumix.Output[*%s] {\n", receiverType, plainType)
fmt.Fprint(w, "\tallArgs := pulumix.All(\n")
for i, p := range f.Inputs.Properties {
fmt.Fprintf(w, "\t\targs.%s.ToOutput(context.Background()).AsAny()", pkg.fieldName(nil, p))
if i < len(f.Inputs.Properties)-1 {
fmt.Fprint(w, ",\n")
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
}
fmt.Fprint(w, ")\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
fmt.Fprintf(w, "\treturn pulumix.Apply[[]any](allArgs, func(resolvedArgs []interface{}) *%s {\n", plainType)
fmt.Fprintf(w, "\t\treturn &%s{\n", plainType)
for i, p := range f.Inputs.Properties {
fmt.Fprintf(w, "\t\t\t%s: resolvedArgs[%d].(%s),\n",
pkg.fieldName(nil, p),
i,
pkg.typeString(p.Type))
}
fmt.Fprintf(w, "\t\t}\n")
fmt.Fprintf(w, "\t})\n")
fmt.Fprintf(w, "}\n\n")
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
}
var objectReturnType *schema.ObjectType
if f.ReturnType != nil {
if objectType, ok := f.ReturnType.(*schema.ObjectType); ok && objectType != nil {
objectReturnType = objectType
}
}
if objectReturnType != nil {
fmt.Fprintf(w, "type %sOutput struct { *pulumi.OutputState }\n\n", originalResultTypeName)
fmt.Fprintf(w, "func (%sOutput) ElementType() reflect.Type {\n", originalResultTypeName)
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s)(nil)).Elem()\n", originalResultTypeName)
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (o %sOutput) ToOutput(context.Context) pulumix.Output[*%s] {\n",
originalResultTypeName,
originalResultTypeName)
fmt.Fprintf(w, "\treturn pulumix.Output[*%s]{\n", originalResultTypeName)
fmt.Fprint(w, "\t\tOutputState: o.OutputState,\n")
fmt.Fprint(w, "\t}\n")
fmt.Fprint(w, "}\n\n")
// generate accessors for each property of the output
for _, p := range objectReturnType.Properties {
outputType := pkg.genericOutputType(p.Type)
fmt.Fprintf(w, "func (o %s) %s() %s {\n", resultTypeName, pkg.fieldName(nil, p), outputType)
needsCast := genericTypeNeedsExplicitCasting(outputType)
if !needsCast {
fmt.Fprintf(w, "\treturn pulumix.Apply[*%s](o, func (v *%s) %s { return v.%s })\n",
originalResultTypeName,
originalResultTypeName,
pkg.typeString(p.Type),
pkg.fieldName(nil, p))
} else {
fmt.Fprintf(w, "\tvalue := pulumix.Apply[*%s](o, func (v *%s) %s { return v.%s })\n",
originalResultTypeName,
originalResultTypeName,
pkg.typeString(p.Type),
pkg.fieldName(nil, p))
fmt.Fprintf(w, "\treturn %s{\n", outputType)
fmt.Fprintf(w, "\t\tOutputState: value.OutputState,\n")
fmt.Fprintf(w, "\t}\n")
}
fmt.Fprintf(w, "}\n\n")
}
}
}
func (pkg *pkgContext) genFunctionOutputVersion(w io.Writer, f *schema.Function, useGenericTypes bool) {
if f.ReturnType == nil {
return
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericTypes {
pkg.genFunctionOutputGenericVersion(w, f)
return
}
originalName := pkg.functionName(f)
name := originalName + "Output"
originalResultTypeName := pkg.functionResultTypeName(f)
resultTypeName := originalResultTypeName + "Output"
code := ""
if f.Inputs != nil {
code = `
func ${fn}Output(ctx *pulumi.Context, args ${fn}OutputArgs, opts ...pulumi.InvokeOption) ${outputType} {
return pulumi.ToOutputWithContext(context.Background(), args).
ApplyT(func(v interface{}) (${fn}Result, error) {
args := v.(${fn}Args)
r, err := ${fn}(ctx, &args, opts...)
[codegen/go] Update Go SDK function output to check for errors (#9274) * [codegen/go] Update Go SDK function output to check for errors Fixes https://github.com/pulumi/pulumi-aws/issues/1872. This should result in the following sample output in the Go SDK: ``` func GetPolicyDocumentOutput(ctx *pulumi.Context, args GetPolicyDocumentOutputArgs, opts ...pulumi.InvokeOption) GetPolicyDocumentResultOutput { return pulumi.ToOutputWithContext(context.Background(), args). ApplyT(func(v interface{}) (GetPolicyDocumentResult, error) { args := v.(GetPolicyDocumentArgs) r, err := GetPolicyDocument(ctx, &args, opts...) if err != nil { return nil, err } if r == nil { return nil, fmt.Errorf("expected either result or error to be nil, not both") } return *r, err }).(GetPolicyDocumentResultOutput) } ``` * Fix generated code panic on *nil (#9284) * [codegen/go] Update Go SDK function output to check for errors Fixes https://github.com/pulumi/pulumi-aws/issues/1872. This should result in the following sample output in the Go SDK: ``` func GetPolicyDocumentOutput(ctx *pulumi.Context, args GetPolicyDocumentOutputArgs, opts ...pulumi.InvokeOption) GetPolicyDocumentResultOutput { return pulumi.ToOutputWithContext(context.Background(), args). ApplyT(func(v interface{}) (GetPolicyDocumentResult, error) { args := v.(GetPolicyDocumentArgs) r, err := GetPolicyDocument(ctx, &args, opts...) if r != nil { s = *r } return s, err }).(GetPolicyDocumentResultOutput) } ``` * Alternate fix to safeguard dereferencing nil * Accept codegen changes in the test suite Co-authored-by: Guinevere Saenger <guinevere@pulumi.com> * Update CHANGELOG_PENDING.md Co-authored-by: Anton Tayanovskyy <anton@pulumi.com>
2022-03-25 03:11:53 +00:00
var s ${fn}Result
if r != nil {
s = *r
}
return s, err
}).(${outputType})
}
`
} else {
code = `
func ${fn}Output(ctx *pulumi.Context, opts ...pulumi.InvokeOption) ${outputType} {
return pulumi.ToOutput(0).ApplyT(func(int) (${fn}Result, error) {
r, err := ${fn}(ctx, opts...)
var s ${fn}Result
if r != nil {
s = *r
}
return s, err
}).(${outputType})
}
`
}
[codegen/go] Update Go SDK function output to check for errors (#9274) * [codegen/go] Update Go SDK function output to check for errors Fixes https://github.com/pulumi/pulumi-aws/issues/1872. This should result in the following sample output in the Go SDK: ``` func GetPolicyDocumentOutput(ctx *pulumi.Context, args GetPolicyDocumentOutputArgs, opts ...pulumi.InvokeOption) GetPolicyDocumentResultOutput { return pulumi.ToOutputWithContext(context.Background(), args). ApplyT(func(v interface{}) (GetPolicyDocumentResult, error) { args := v.(GetPolicyDocumentArgs) r, err := GetPolicyDocument(ctx, &args, opts...) if err != nil { return nil, err } if r == nil { return nil, fmt.Errorf("expected either result or error to be nil, not both") } return *r, err }).(GetPolicyDocumentResultOutput) } ``` * Fix generated code panic on *nil (#9284) * [codegen/go] Update Go SDK function output to check for errors Fixes https://github.com/pulumi/pulumi-aws/issues/1872. This should result in the following sample output in the Go SDK: ``` func GetPolicyDocumentOutput(ctx *pulumi.Context, args GetPolicyDocumentOutputArgs, opts ...pulumi.InvokeOption) GetPolicyDocumentResultOutput { return pulumi.ToOutputWithContext(context.Background(), args). ApplyT(func(v interface{}) (GetPolicyDocumentResult, error) { args := v.(GetPolicyDocumentArgs) r, err := GetPolicyDocument(ctx, &args, opts...) if r != nil { s = *r } return s, err }).(GetPolicyDocumentResultOutput) } ``` * Alternate fix to safeguard dereferencing nil * Accept codegen changes in the test suite Co-authored-by: Guinevere Saenger <guinevere@pulumi.com> * Update CHANGELOG_PENDING.md Co-authored-by: Anton Tayanovskyy <anton@pulumi.com>
2022-03-25 03:11:53 +00:00
code = strings.ReplaceAll(code, "${fn}", originalName)
code = strings.ReplaceAll(code, "${outputType}", resultTypeName)
fmt.Fprint(w, code)
if f.Inputs != nil {
pkg.genInputArgsStruct(w, name+"Args", f.Inputs.InputShape, false /*emitGenericVariant*/)
genInputImplementationWithArgs(w, genInputImplementationArgs{
name: name + "Args",
receiverType: name + "Args",
elementType: pkg.functionArgsTypeName(f),
usingGenericTypes: useGenericTypes,
})
}
if f.ReturnType != nil {
if objectType, ok := f.ReturnType.(*schema.ObjectType); ok && objectType != nil {
pkg.genOutputTypes(w, genOutputTypesArgs{
t: objectType,
name: originalResultTypeName,
output: true,
})
}
}
// Assuming the file represented by `w` only has one function,
// generate an `init()` for Output type init.
initCode := `
func init() {
pulumi.RegisterOutputType(${outputType}{})
}
`
initCode = strings.ReplaceAll(initCode, "${outputType}", resultTypeName)
fmt.Fprint(w, initCode)
}
type objectProperty struct {
object *schema.ObjectType
property *schema.Property
}
// When computing the type name for a field of an object type, we must ensure that we do not generate invalid recursive
// struct types. A struct type T contains invalid recursion if the closure of its fields and its struct-typed fields'
// fields includes a field of type T. A few examples:
//
// Directly invalid:
//
2022-09-14 02:12:02 +00:00
// type T struct {
// Invalid T
// }
//
// Indirectly invalid:
//
2022-09-14 02:12:02 +00:00
// type T struct {
// Invalid S
// }
//
2022-09-14 02:12:02 +00:00
// type S struct {
// Invalid T
// }
//
// In order to avoid generating invalid struct types, we replace all references to types involved in a cyclical
// definition with *T. The examples above therefore become:
//
// (1)
2022-09-14 02:12:02 +00:00
//
// type T struct {
// Valid *T
// }
//
// (2)
//
2022-09-14 02:12:02 +00:00
// type T struct {
// Valid *S
// }
//
// type S struct {
// Valid *T
// }
//
// We do this using a rewriter that turns all fields involved in reference cycles into optional fields.
func rewriteCyclicField(rewritten codegen.Set, path []objectProperty, op objectProperty) {
// If this property refers to an Input<> type, unwrap the type. This ensures that the plain and input shapes of an
// object type remain identical.
t := op.property.Type
if inputType, isInputType := op.property.Type.(*schema.InputType); isInputType {
t = inputType.ElementType
}
// If this property does not refer to an object type, it cannot be involved in a cycle. Skip it.
objectType, isObjectType := t.(*schema.ObjectType)
if !isObjectType {
return
}
path = append(path, op)
// Check the current path for cycles by crawling backwards until reaching the start of the path
// or finding a property that is a member of the current object type.
var cycle []objectProperty
for i := len(path) - 1; i > 0; i-- {
if path[i].object == objectType {
cycle = path[i:]
break
}
}
// If the current path does not involve a cycle, recur into the current object type.
if len(cycle) == 0 {
rewriteCyclicFields(rewritten, path, objectType)
return
}
// If we've found a cycle, mark each property involved in the cycle as optional.
//
// NOTE: this overestimates the set of properties that must be marked as optional. For example, in case (2) above,
// only one of T.Invalid or S.Invalid needs to be marked as optional in order to break the cycle. However, choosing
// a minimal set of properties that is also deterministic and resilient to changes in visit order is difficult and
// seems to add little value.
for _, p := range cycle {
p.property.Type = codegen.OptionalType(p.property)
}
}
func rewriteCyclicFields(rewritten codegen.Set, path []objectProperty, obj *schema.ObjectType) {
if !rewritten.Has(obj) {
rewritten.Add(obj)
for _, property := range obj.Properties {
rewriteCyclicField(rewritten, path, objectProperty{obj, property})
}
}
}
func rewriteCyclicObjectFields(pkg *schema.Package) {
rewritten := codegen.Set{}
for _, t := range pkg.Types {
if obj, ok := t.(*schema.ObjectType); ok && !obj.IsInputShape() {
rewriteCyclicFields(rewritten, nil, obj)
rewriteCyclicFields(rewritten, nil, obj.InputShape)
}
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genType(w io.Writer, obj *schema.ObjectType, usingGenericTypes bool) error {
contract.Assertf(!obj.IsInputShape(), "Object type must not have input shape")
if obj.IsOverlay {
// This type is generated by the provider, so no further action is required.
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return nil
}
plainName := pkg.tokenToType(obj.Token)
[go/sdk-gen] Fixes plain and optional properties for generated types for Go SDKs using generics (#14616) # Description While working on on #14585 I tried to add a test schema for assets and archives that generate a `generics-only` go SDK but the the output didn't compile. At first I thought the issue was specific to asset and archive types but actually it was a broader issue where the function`pkg.genPlainType(InputObjectType)` would always reduce `Input[T]` and `Optional[T]` to just `T` on each property of `InputObjectType`. It is probably fine to reduce `Input[T]` because we are generating a plain type after all. However, reducing `Optional[T]` to `T` is incorrect because the generic variant of go sdks are more strict about optionality of types. > It probably works in non-generic SDKs today because it relies on a runtime cast Example type `TypeWithAssets` from schema that has a plain and optional property called `plainAsset`: ❌ Before it was the following and it didn't compile for generic go sdks ```go type TypeWithAssets struct { PlainAsset pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset pulumix.Input[*pulumi.AssetOrArchive] `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) pulumi.AssetOrArchive { return v.PlainAsset }) } ``` ✅ Now it generates: ```go type TypeWithAssets struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } type TypeWithAssetsArgs struct { PlainAsset *pulumi.AssetOrArchive `pulumi:"plainAsset"` } func (o TypeWithAssetsOutput) PlainAsset() pulumix.Output[*pulumi.AssetOrArchive] { return pulumix.Apply[TypeWithAssets](o, func(v TypeWithAssets) *pulumi.AssetOrArchive { return v.PlainAsset }) } ``` Which is correct and compiles The behavior for current non-generic SDKs remains unchanged ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-21 16:43:51 +00:00
if !usingGenericTypes {
pkg.genPlainType(w, plainName, obj.Comment, "", obj.Properties)
} else {
pkg.genGenericPlainType(w, plainName, obj.Comment, "", obj.Properties)
}
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
if !pkg.disableObjectDefaults {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genObjectDefaultFunc(w, plainName, obj.Properties, usingGenericTypes); err != nil {
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return err
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genInputTypes(w, obj.InputShape, pkg.detailsForType(obj), usingGenericTypes); err != nil {
return err
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.genOutputTypes(w, genOutputTypesArgs{
t: obj,
usingGenericTypes: usingGenericTypes,
})
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
return nil
2020-11-03 07:02:56 +00:00
}
2021-03-11 05:04:30 +00:00
func (pkg *pkgContext) addSuffixesToName(typ schema.Type, name string) []string {
var names []string
details := pkg.detailsForType(typ)
if details.arrayInput {
names = append(names, name+"ArrayInput")
2021-03-11 05:04:30 +00:00
}
if details.arrayOutput || details.arrayInput {
names = append(names, name+"ArrayOutput")
}
if details.mapInput {
names = append(names, name+"MapInput")
}
if details.mapOutput || details.mapInput {
names = append(names, name+"MapOutput")
2021-03-11 05:04:30 +00:00
}
return names
}
type nestedTypeInfo struct {
resolvedElementType string
names map[string]bool
}
// collectNestedCollectionTypes builds a deduped mapping of element types -> associated collection types.
// different shapes of known types can resolve to the same element type. by collecting types in one step and emitting types
// in a second step, we avoid collision and redeclaration.
func (pkg *pkgContext) collectNestedCollectionTypes(types map[string]*nestedTypeInfo, typ schema.Type) {
2021-03-11 05:04:30 +00:00
var elementTypeName string
var names []string
switch t := typ.(type) {
case *schema.ArrayType:
// Builtins already cater to primitive arrays
if schema.IsPrimitiveType(t.ElementType) {
return
}
2021-03-15 06:44:21 +00:00
elementTypeName = pkg.nestedTypeToType(t.ElementType)
elementTypeName = strings.TrimSuffix(elementTypeName, "Args") + "Array"
// We make sure that subsidiary elements are marked for array as well
details := pkg.detailsForType(t)
pkg.detailsForType(t.ElementType).markArray(details.arrayInput, details.arrayOutput)
2021-03-11 05:04:30 +00:00
names = pkg.addSuffixesToName(t, elementTypeName)
defer pkg.collectNestedCollectionTypes(types, t.ElementType)
2021-03-11 05:04:30 +00:00
case *schema.MapType:
// Builtins already cater to primitive maps
if schema.IsPrimitiveType(t.ElementType) {
return
}
2021-03-15 06:44:21 +00:00
elementTypeName = pkg.nestedTypeToType(t.ElementType)
elementTypeName = strings.TrimSuffix(elementTypeName, "Args") + "Map"
// We make sure that subsidiary elements are marked for map as well
details := pkg.detailsForType(t)
pkg.detailsForType(t.ElementType).markMap(details.mapInput, details.mapOutput)
2021-03-11 05:04:30 +00:00
names = pkg.addSuffixesToName(t, elementTypeName)
defer pkg.collectNestedCollectionTypes(types, t.ElementType)
default:
return
2021-03-11 05:04:30 +00:00
}
nti, ok := types[elementTypeName]
if !ok {
nti = &nestedTypeInfo{
names: map[string]bool{},
resolvedElementType: pkg.typeString(codegen.ResolvedType(typ)),
}
types[elementTypeName] = nti
}
for _, n := range names {
nti.names[n] = true
}
}
2021-03-11 05:04:30 +00:00
// genNestedCollectionTypes emits nested collection types given the deduped mapping of element types -> associated collection types.
// different shapes of known types can resolve to the same element type. by collecting types in one step and emitting types
// in a second step, we avoid collision and redeclaration.
func (pkg *pkgContext) genNestedCollectionTypes(w io.Writer, types map[string]*nestedTypeInfo) []string {
var names []string
// map iteration is unstable so sort items for deterministic codegen
sortedElems := []string{}
for k := range types {
sortedElems = append(sortedElems, k)
}
sort.Strings(sortedElems)
for _, elementTypeName := range sortedElems {
info := types[elementTypeName]
collectionTypes := []string{}
for k := range info.names {
collectionTypes = append(collectionTypes, k)
}
sort.Strings(collectionTypes)
for _, name := range collectionTypes {
names = append(names, name)
switch {
case strings.HasSuffix(name, "ArrayInput"):
name = strings.TrimSuffix(name, "Input")
fmt.Fprintf(w, "type %s []%sInput\n\n", name, elementTypeName)
pkg.genInputImplementation(w, name, name, "[]"+info.resolvedElementType, false, false)
pkg.genInputInterface(w, name)
case strings.HasSuffix(name, "ArrayOutput"):
pkg.genArrayOutput(w, strings.TrimSuffix(name, "ArrayOutput"), info.resolvedElementType)
case strings.HasSuffix(name, "MapInput"):
name = strings.TrimSuffix(name, "Input")
fmt.Fprintf(w, "type %s map[string]%sInput\n\n", name, elementTypeName)
pkg.genInputImplementation(w, name, name, "map[string]"+info.resolvedElementType, false, false)
2021-03-11 05:04:30 +00:00
pkg.genInputInterface(w, name)
case strings.HasSuffix(name, "MapOutput"):
pkg.genMapOutput(w, strings.TrimSuffix(name, "MapOutput"), info.resolvedElementType)
}
2021-03-11 05:04:30 +00:00
}
}
return names
}
2021-03-15 06:44:21 +00:00
func (pkg *pkgContext) nestedTypeToType(typ schema.Type) string {
switch t := codegen.UnwrapType(typ).(type) {
2021-03-11 05:04:30 +00:00
case *schema.ArrayType:
return pkg.nestedTypeToType(t.ElementType) + "Array"
2021-03-11 05:04:30 +00:00
case *schema.MapType:
return pkg.nestedTypeToType(t.ElementType) + "Map"
case *schema.ObjectType:
return pkg.resolveObjectType(t)
case *schema.EnumType:
return pkg.resolveEnumType(t)
2021-03-11 05:04:30 +00:00
}
return strings.TrimSuffix(pkg.tokenToType(typ.String()), "Args")
2021-03-11 05:04:30 +00:00
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genTypeRegistrations(
w io.Writer,
objTypes []*schema.ObjectType,
usingGenericTypes bool,
types ...string,
) {
fmt.Fprintf(w, "func init() {\n")
// Input types.
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !pkg.disableInputTypeRegistrations && !usingGenericTypes {
for _, obj := range objTypes {
if obj.IsOverlay {
// This type is generated by the provider, so no further action is required.
continue
}
name, details := pkg.tokenToType(obj.Token), pkg.detailsForType(obj)
if details.input {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sInput)(nil)).Elem(), %[1]sArgs{})\n", name)
}
if details.ptrInput {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sPtrInput)(nil)).Elem(), %[1]sArgs{})\n", name)
}
if details.arrayInput && !pkg.names.Has(name+"Array") {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sArrayInput)(nil)).Elem(), %[1]sArray{})\n", name)
}
if details.mapInput && !pkg.names.Has(name+"Map") {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sMapInput)(nil)).Elem(), %[1]sMap{})\n", name)
}
}
for _, t := range types {
if strings.HasSuffix(t, "Input") {
fmt.Fprintf(w, "\tpulumi.RegisterInputType(reflect.TypeOf((*%s)(nil)).Elem(), %s{})\n", t, strings.TrimSuffix(t, "Input"))
}
}
}
// Output types.
2021-03-11 05:04:30 +00:00
for _, obj := range objTypes {
if obj.IsOverlay {
// This type is generated by the provider, so no further action is required.
continue
}
2020-11-03 07:02:56 +00:00
name, details := pkg.tokenToType(obj.Token), pkg.detailsForType(obj)
if details.output {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sOutput{})\n", name)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.ptrOutput && !usingGenericTypes {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sPtrOutput{})\n", name)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.arrayOutput && !usingGenericTypes {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sArrayOutput{})\n", name)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if details.mapOutput && !usingGenericTypes {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sMapOutput{})\n", name)
}
}
2021-03-11 05:04:30 +00:00
for _, t := range types {
if strings.HasSuffix(t, "Output") {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%s{})\n", t)
}
2021-03-11 05:04:30 +00:00
}
fmt.Fprintf(w, "}\n")
}
func (pkg *pkgContext) genEnumRegistrations(w io.Writer) {
fmt.Fprintf(w, "func init() {\n")
// Register all input types
if !pkg.disableInputTypeRegistrations {
for _, e := range pkg.enums {
// Enums are guaranteed to have at least one element when they are
// bound into a schema.
contract.Assertf(len(e.Elements) > 0, "Enum must have at least one element")
name, details := pkg.tokenToEnum(e.Token), pkg.detailsForType(e)
instance := fmt.Sprintf("%#v", e.Elements[0].Value)
if details.input || details.ptrInput {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sInput)(nil)).Elem(), %[1]s(%[2]s))\n",
name, instance)
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sPtrInput)(nil)).Elem(), %[1]s(%[2]s))\n",
name, instance)
}
if details.arrayInput {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sArrayInput)(nil)).Elem(), %[1]sArray{})\n",
name)
}
if details.mapInput {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sMapInput)(nil)).Elem(), %[1]sMap{})\n",
name)
}
}
}
// Register all output types
for _, e := range pkg.enums {
name, details := pkg.tokenToEnum(e.Token), pkg.detailsForType(e)
if details.output || details.ptrOutput {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sOutput{})\n", name)
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sPtrOutput{})\n", name)
}
if details.arrayOutput {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sArrayOutput{})\n", name)
}
if details.mapOutput {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sMapOutput{})\n", name)
}
}
fmt.Fprintf(w, "}\n\n")
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func (pkg *pkgContext) genResourceRegistrations(
w io.Writer,
r *schema.Resource,
generateResourceContainerTypes bool,
usingGenericTypes bool,
) {
name := disambiguatedResourceName(r, pkg)
fmt.Fprintf(w, "func init() {\n")
// Register input type
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if !pkg.disableInputTypeRegistrations && !usingGenericTypes {
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sInput)(nil)).Elem(), &%[1]s{})\n",
name)
[codegen/go] Remove ResourcePtr input/output types (#8449) These changes remove the `Ptr` variants of input/ouptut types for resources. A `TPtr` input or output is normally generated for `T` if `T` is present in an `optional(input(T))` or `optional(output(T))` and if the Go representation for `T` is not nilable. The generation of `Ptr` variants for resource types breaks the latter rule: the canonical representation of a resource type named `Foo` is a pointer to a struct type named `Foo` (i.e. `*Foo`). `Foo` itself is not a resource, as it does not implement the Go `Resource` interface. Because this representation already accommodates `nil` to indicate the lack of a value, we need not generate `FooPtr{Input,Output}` types. Besides being unnecessary, the implementation of `Ptr` types for resources was incorrect. Rather than using `**Foo` as their element type, these types use `*Foo`--identical to the element type used for the normal input/output types. Furthermore, the generated code for at least `FooOutput.ToFooPtrOutputWithContext` and `FooPtrOutput.Elem` was incorrect, making these types virtually unusable in practice. Finally, these `Ptr` types should never appear on input/output properties in practice, as the logic we use to generate input and output type references never generates them for `optional({input,output}(T)). Instead, it generates references to the standard input/output types. Though this is _technically_ a breaking change--it changes the set of exported types for any package that defines resources--I believe that in practice it will be invisible to users for the reasons stated above. These types are not usable, and were never referenced. This is preparatory work for #7943.
2021-11-23 18:24:56 +00:00
if generateResourceContainerTypes && !r.IsProvider {
fmt.Fprintf(w,
[codegen/go] Remove ResourcePtr input/output types (#8449) These changes remove the `Ptr` variants of input/ouptut types for resources. A `TPtr` input or output is normally generated for `T` if `T` is present in an `optional(input(T))` or `optional(output(T))` and if the Go representation for `T` is not nilable. The generation of `Ptr` variants for resource types breaks the latter rule: the canonical representation of a resource type named `Foo` is a pointer to a struct type named `Foo` (i.e. `*Foo`). `Foo` itself is not a resource, as it does not implement the Go `Resource` interface. Because this representation already accommodates `nil` to indicate the lack of a value, we need not generate `FooPtr{Input,Output}` types. Besides being unnecessary, the implementation of `Ptr` types for resources was incorrect. Rather than using `**Foo` as their element type, these types use `*Foo`--identical to the element type used for the normal input/output types. Furthermore, the generated code for at least `FooOutput.ToFooPtrOutputWithContext` and `FooPtrOutput.Elem` was incorrect, making these types virtually unusable in practice. Finally, these `Ptr` types should never appear on input/output properties in practice, as the logic we use to generate input and output type references never generates them for `optional({input,output}(T)). Instead, it generates references to the standard input/output types. Though this is _technically_ a breaking change--it changes the set of exported types for any package that defines resources--I believe that in practice it will be invisible to users for the reasons stated above. These types are not usable, and were never referenced. This is preparatory work for #7943.
2021-11-23 18:24:56 +00:00
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sArrayInput)(nil)).Elem(), %[1]sArray{})\n",
name)
fmt.Fprintf(w,
"\tpulumi.RegisterInputType(reflect.TypeOf((*%[1]sMapInput)(nil)).Elem(), %[1]sMap{})\n",
name)
}
}
// Register all output types
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sOutput{})\n", name)
for _, method := range r.Methods {
var objectReturnType *schema.ObjectType
if method.Function.ReturnType != nil {
if objectType, ok := method.Function.ReturnType.(*schema.ObjectType); ok && objectType != nil {
objectReturnType = objectType
}
}
if objectReturnType != nil {
if pkg.liftSingleValueMethodReturns && len(objectReturnType.Properties) == 1 {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%s%sResultOutput{})\n", cgstrings.Camel(name), Title(method.Name))
} else {
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%s%sResultOutput{})\n", name, Title(method.Name))
}
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if generateResourceContainerTypes && !r.IsProvider && !usingGenericTypes {
[codegen/go] Remove ResourcePtr input/output types (#8449) These changes remove the `Ptr` variants of input/ouptut types for resources. A `TPtr` input or output is normally generated for `T` if `T` is present in an `optional(input(T))` or `optional(output(T))` and if the Go representation for `T` is not nilable. The generation of `Ptr` variants for resource types breaks the latter rule: the canonical representation of a resource type named `Foo` is a pointer to a struct type named `Foo` (i.e. `*Foo`). `Foo` itself is not a resource, as it does not implement the Go `Resource` interface. Because this representation already accommodates `nil` to indicate the lack of a value, we need not generate `FooPtr{Input,Output}` types. Besides being unnecessary, the implementation of `Ptr` types for resources was incorrect. Rather than using `**Foo` as their element type, these types use `*Foo`--identical to the element type used for the normal input/output types. Furthermore, the generated code for at least `FooOutput.ToFooPtrOutputWithContext` and `FooPtrOutput.Elem` was incorrect, making these types virtually unusable in practice. Finally, these `Ptr` types should never appear on input/output properties in practice, as the logic we use to generate input and output type references never generates them for `optional({input,output}(T)). Instead, it generates references to the standard input/output types. Though this is _technically_ a breaking change--it changes the set of exported types for any package that defines resources--I believe that in practice it will be invisible to users for the reasons stated above. These types are not usable, and were never referenced. This is preparatory work for #7943.
2021-11-23 18:24:56 +00:00
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sArrayOutput{})\n", name)
fmt.Fprintf(w, "\tpulumi.RegisterOutputType(%sMapOutput{})\n", name)
}
fmt.Fprintf(w, "}\n\n")
}
func (pkg *pkgContext) getTypeImports(t schema.Type, recurse bool, importsAndAliases map[string]string, seen map[schema.Type]struct{}) {
if _, ok := seen[t]; ok {
return
}
seen[t] = struct{}{}
// Import an external type with `token` and return true.
// If the type is not external, return false.
importExternal := func(token string) bool {
if pkg.isExternalReference(t) {
extPkgCtx, _ := pkg.contextForExternalReference(t)
mod := extPkgCtx.tokenToPackage(token)
imp := path.Join(extPkgCtx.importBasePath, mod)
importsAndAliases[imp] = extPkgCtx.pkgImportAliases[imp]
return true
}
return false
}
switch t := t.(type) {
case *schema.OptionalType:
pkg.getTypeImports(t.ElementType, recurse, importsAndAliases, seen)
case *schema.InputType:
pkg.getTypeImports(t.ElementType, recurse, importsAndAliases, seen)
2021-02-26 06:05:02 +00:00
case *schema.EnumType:
if importExternal(t.Token) {
break
}
2021-02-26 06:05:02 +00:00
mod := pkg.tokenToPackage(t.Token)
if mod != pkg.mod {
p := path.Join(pkg.importBasePath, mod)
importsAndAliases[path.Join(pkg.importBasePath, mod)] = pkg.pkgImportAliases[p]
}
case *schema.ArrayType:
pkg.getTypeImports(t.ElementType, recurse, importsAndAliases, seen)
case *schema.MapType:
pkg.getTypeImports(t.ElementType, recurse, importsAndAliases, seen)
case *schema.ObjectType:
if importExternal(t.Token) {
break
}
mod := pkg.tokenToPackage(t.Token)
if mod != pkg.mod {
p := path.Join(pkg.importBasePath, mod)
importsAndAliases[path.Join(pkg.importBasePath, mod)] = pkg.pkgImportAliases[p]
}
if recurse {
for _, p := range t.Properties {
// We only recurse one level into objects, since we need to name
// their properties but not the properties named in their
// properties.
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
}
}
case *schema.ResourceType:
if importExternal(t.Token) {
break
}
mod := pkg.tokenToPackage(t.Token)
if mod != pkg.mod {
p := path.Join(pkg.importBasePath, mod)
importsAndAliases[path.Join(pkg.importBasePath, mod)] = pkg.pkgImportAliases[p]
}
case *schema.UnionType:
for _, e := range t.ElementTypes {
pkg.getTypeImports(e, recurse, importsAndAliases, seen)
}
}
}
func extractImportBasePath(extPkg schema.PackageReference) string {
version := extPkg.Version().Major
var vPath string
if version > 1 {
vPath = fmt.Sprintf("/v%d", version)
}
return fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s", extPkg.Name(), vPath, extPkg.Name())
}
func (pkg *pkgContext) getImports(member interface{}, importsAndAliases map[string]string) {
seen := map[schema.Type]struct{}{}
switch member := member.(type) {
case *schema.ObjectType:
pkg.getTypeImports(member, true, importsAndAliases, seen)
case *schema.ResourceType:
pkg.getTypeImports(member, true, importsAndAliases, seen)
case *schema.Resource:
for _, p := range member.Properties {
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
}
for _, p := range member.InputProperties {
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
if p.IsRequired() {
importsAndAliases["errors"] = ""
}
}
for _, method := range member.Methods {
if method.Function.Inputs != nil {
for _, p := range method.Function.Inputs.InputShape.Properties {
if p.Name == "__self__" {
continue
}
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
}
}
if method.Function.ReturnType != nil {
if objectType, ok := method.Function.ReturnType.(*schema.ObjectType); ok && objectType != nil {
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
for _, p := range objectType.Properties {
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
}
} else if method.Function.ReturnTypePlain {
pkg.getTypeImports(method.Function.ReturnType, false, importsAndAliases, seen)
}
}
}
case *schema.Function:
if member.Inputs != nil {
pkg.getTypeImports(member.Inputs, true, importsAndAliases, seen)
}
var returnType *schema.ObjectType
if member.ReturnType != nil {
if objectType, ok := member.ReturnType.(*schema.ObjectType); ok && objectType != nil {
returnType = objectType
}
}
if returnType != nil {
pkg.getTypeImports(returnType, true, importsAndAliases, seen)
}
case []*schema.Property:
for _, p := range member {
pkg.getTypeImports(p.Type, false, importsAndAliases, seen)
}
default:
return
}
}
func (pkg *pkgContext) genHeader(w io.Writer, goImports []string, importsAndAliases map[string]string, isUtil bool) {
fmt.Fprintf(w, "// Code generated by %v DO NOT EDIT.\n", pkg.tool)
fmt.Fprintf(w, "// *** WARNING: Do not edit by hand unless you're certain you know what you are doing! ***\n\n")
var pkgName string
if pkg.mod == "" {
if isUtil {
// we place pulumiVersion and pulumiUtilities in an ./internal folder
// the name of the folder can be overridden by the schema
// so we use the computed internalModuleName which defaults to "internal" if not set
pkgName = pkg.internalModuleName
} else {
def, err := pkg.pkg.Definition()
contract.AssertNoErrorf(err, "Could not retrieve definition")
pkgName = packageName(def)
}
} else {
pkgName = path.Base(pkg.mod)
}
fmt.Fprintf(w, "package %s\n\n", pkgName)
var imports []string
if len(importsAndAliases) > 0 {
for k := range importsAndAliases {
imports = append(imports, k)
}
sort.Strings(imports)
for i, k := range imports {
if alias := importsAndAliases[k]; alias != "" {
imports[i] = fmt.Sprintf(`%s "%s"`, alias, k)
}
}
}
if len(goImports) > 0 {
if len(imports) > 0 {
goImports = append(goImports, "")
}
imports = append(goImports, imports...)
}
if len(imports) > 0 {
fmt.Fprintf(w, "import (\n")
for _, i := range imports {
if i == "" {
fmt.Fprintf(w, "\n")
} else {
if strings.Contains(i, `"`) { // Imports with aliases already include quotes.
fmt.Fprintf(w, "\t%s\n", i)
} else {
fmt.Fprintf(w, "\t%q\n", i)
}
}
}
fmt.Fprintf(w, ")\n\n")
}
}
func (pkg *pkgContext) genConfig(w io.Writer, variables []*schema.Property) error {
importsAndAliases := map[string]string{
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config": "",
"github.com/pulumi/pulumi/sdk/v3/go/pulumi": "",
}
pkg.getImports(variables, importsAndAliases)
importsAndAliases[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
2023-07-06 20:20:04 +00:00
pkg.genHeader(w, nil, importsAndAliases, false /* isUtil */)
// in case we're not using the internal package, assign to a blank var
fmt.Fprintf(w, "var _ = %s.GetEnvOrDefault\n", pkg.internalModuleName)
for _, p := range variables {
getfunc := "Get"
var getType string
var funcType string
switch codegen.UnwrapType(p.Type) {
case schema.BoolType:
getType, funcType = "bool", "Bool"
case schema.IntType:
getType, funcType = "int", "Int"
case schema.NumberType:
getType, funcType = "float64", "Float64"
default:
getType, funcType = "string", ""
}
printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false)
configKey := fmt.Sprintf("\"%s:%s\"", pkg.pkg.Name(), cgstrings.Camel(p.Name))
fmt.Fprintf(w, "func Get%s(ctx *pulumi.Context) %s {\n", Title(p.Name), getType)
if p.DefaultValue != nil {
fmt.Fprintf(w, "\tv, err := config.Try%s(ctx, %s)\n", funcType, configKey)
fmt.Fprintf(w, "\tif err == nil {\n")
fmt.Fprintf(w, "\t\treturn v\n")
fmt.Fprintf(w, "\t}\n")
fix(sdkgen/go): Don't set default to zero if env is empty sdkgen has a discrepancy in behavior for default values. There are three scenarios: - default value - default value and an environment variable fallback - only an environment variable fallback We handle the first two correctly: the value is set only if there was something to set it to. But in the third case, we set variables to their zero value when the environment variable is empty. // Current implementation effectively does: if v := os.Getenv("whatever"); v != "" { out.Field = pointerOf(v) } else { out.Field = pointerOf("") } To fix this, we generate code to set these values only if the environment variable is non-empty. Implementation notes: Previosly, getDefaultValue generated an expression holding the default value. For fixed default values, it was just the value. For default values with environment variable fallback, it took the form: getEnvOrDefault($default, $parser, $env1, $env2, ...).($type) For example: getEnvOrDefault("", nil, "ITEM_NAME").(string) Given that getDefaultValue returned an expression, its consumers were able to do something like: if result == nil { result = getEnvOrDefault(...).(string) } As part of this fix, we need to stop assinging to result if the environment variable is unset, so we want getDefaultValue to generate: if result == nil { if d := getEnvOrDefault(...); d != nil { result = d } } To accomplish this, we switch getDefaultValue to setDefaultValue. Instead of returning an expression, it accepts a callback. It generates the blocks it needs to, and invokes the callback with an expression holding the default value if necessary. Resolves #12971
2023-05-18 18:31:24 +00:00
fmt.Fprintf(w, "\tvar value %s\n", getType)
err := pkg.setDefaultValue(w, p.DefaultValue, codegen.UnwrapType(p.Type), func(w io.Writer, dv string) error {
_, err := fmt.Fprintf(w, "\tvalue = %s\n", dv)
return err
})
if err != nil {
return err
}
fmt.Fprintf(w, "\treturn value\n")
} else {
fmt.Fprintf(w, "\treturn config.%s%s(ctx, %s)\n", getfunc, funcType, configKey)
}
fmt.Fprintf(w, "}\n")
}
return nil
}
// genResourceModule generates a ResourceModule definition and the code to register an instance thereof with the
// Pulumi runtime. The generated ResourceModule supports the deserialization of resource references into fully-
// hydrated Resource instances. If this is the root module, this function also generates a ResourcePackage
// definition and its registration to support rehydrating providers.
func (pkg *pkgContext) genResourceModule(w io.Writer) error {
contract.Assertf(len(pkg.resources) != 0, "Package must have at least one resource")
allResourcesAreOverlays := true
for _, r := range pkg.resources {
if !r.IsOverlay {
allResourcesAreOverlays = false
break
}
}
if allResourcesAreOverlays {
// If all resources in this module are overlays, skip further code generation.
return nil
}
imports := map[string]string{
"github.com/blang/semver": "",
"github.com/pulumi/pulumi/sdk/v3/go/pulumi": "",
}
imports[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
// If there are any internal dependencies, include them as blank imports.
def, err := pkg.pkg.Definition()
if err != nil {
return err
}
if goInfo, ok := def.Language["go"].(GoPackageInfo); ok {
for _, dep := range goInfo.InternalDependencies {
imports[dep] = "_"
}
}
2023-07-06 20:20:04 +00:00
pkg.genHeader(w, []string{"fmt"}, imports, false /* isUtil */)
var provider *schema.Resource
registrations := codegen.StringSet{}
if providerOnly := len(pkg.resources) == 1 && pkg.resources[0].IsProvider; providerOnly {
provider = pkg.resources[0]
} else {
fmt.Fprintf(w, "type module struct {\n")
fmt.Fprintf(w, "\tversion semver.Version\n")
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (m *module) Version() semver.Version {\n")
fmt.Fprintf(w, "\treturn m.version\n")
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi.Resource, err error) {\n")
fmt.Fprintf(w, "\tswitch typ {\n")
for _, r := range pkg.resources {
if r.IsOverlay {
// This resource code is generated by the provider, so no further action is required.
continue
}
if r.IsProvider {
contract.Assertf(provider == nil, "Provider must not be specified for Provider resources")
provider = r
continue
}
registrations.Add(tokenToModule(r.Token))
fmt.Fprintf(w, "\tcase %q:\n", r.Token)
fmt.Fprintf(w, "\t\tr = &%s{}\n", disambiguatedResourceName(r, pkg))
}
fmt.Fprintf(w, "\tdefault:\n")
fmt.Fprintf(w, "\t\treturn nil, fmt.Errorf(\"unknown resource type: %%s\", typ)\n")
fmt.Fprintf(w, "\t}\n\n")
fmt.Fprintf(w, "\terr = ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn))\n")
fmt.Fprintf(w, "\treturn\n")
fmt.Fprintf(w, "}\n\n")
}
if provider != nil {
fmt.Fprintf(w, "type pkg struct {\n")
fmt.Fprintf(w, "\tversion semver.Version\n")
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (p *pkg) Version() semver.Version {\n")
fmt.Fprintf(w, "\treturn p.version\n")
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "func (p *pkg) ConstructProvider(ctx *pulumi.Context, name, typ, urn string) (pulumi.ProviderResource, error) {\n")
fmt.Fprintf(w, "\tif typ != \"pulumi:providers:%s\" {\n", pkg.pkg.Name())
fmt.Fprintf(w, "\t\treturn nil, fmt.Errorf(\"unknown provider type: %%s\", typ)\n")
fmt.Fprintf(w, "\t}\n\n")
fmt.Fprintf(w, "\tr := &Provider{}\n")
fmt.Fprintf(w, "\terr := ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn))\n")
fmt.Fprintf(w, "\treturn r, err\n")
fmt.Fprintf(w, "}\n\n")
}
fmt.Fprintf(w, "func init() {\n")
fmt.Fprintf(w, "\tversion, err := %s.PkgVersion()\n", pkg.internalModuleName)
// To avoid breaking compatibility, we don't change the function
// signature. We instead just ignore the error.
fmt.Fprintf(w, "\tif err != nil {\n")
fmt.Fprintf(w, "\t\tversion = semver.Version{Major: 1}\n")
fmt.Fprintf(w, "\t}\n")
if len(registrations) > 0 {
for _, mod := range registrations.SortedValues() {
fmt.Fprintf(w, "\tpulumi.RegisterResourceModule(\n")
fmt.Fprintf(w, "\t\t%q,\n", pkg.pkg.Name())
fmt.Fprintf(w, "\t\t%q,\n", mod)
fmt.Fprintf(w, "\t\t&module{version},\n")
fmt.Fprintf(w, "\t)\n")
}
}
if provider != nil {
fmt.Fprintf(w, "\tpulumi.RegisterResourcePackage(\n")
fmt.Fprintf(w, "\t\t%q,\n", pkg.pkg.Name())
fmt.Fprintf(w, "\t\t&pkg{version},\n")
fmt.Fprintf(w, "\t)\n")
}
_, err = fmt.Fprintf(w, "}\n")
return err
}
// generatePackageContextMap groups resources, types, and functions into Go packages.
func generatePackageContextMap(tool string, pkg schema.PackageReference, goInfo GoPackageInfo, externalPkgs *Cache) (map[string]*pkgContext, error) {
packages := map[string]*pkgContext{}
// Share the cache
if externalPkgs == nil {
externalPkgs = globalCache
}
getPkg := func(mod string) *pkgContext {
pack, ok := packages[mod]
if !ok {
internalModuleName := "internal"
if goInfo.InternalModuleName != "" {
internalModuleName = goInfo.InternalModuleName
}
pack = &pkgContext{
pkg: pkg,
mod: mod,
importBasePath: goInfo.ImportBasePath,
rootPackageName: goInfo.RootPackageName,
typeDetails: map[schema.Type]*typeDetails{},
names: codegen.NewStringSet(),
schemaNames: codegen.NewStringSet(),
renamed: map[string]string{},
duplicateTokens: map[string]bool{},
functionNames: map[*schema.Function]string{},
tool: tool,
modToPkg: goInfo.ModuleToPackage,
pkgImportAliases: goInfo.PackageImportAliases,
packages: packages,
liftSingleValueMethodReturns: goInfo.LiftSingleValueMethodReturns,
disableInputTypeRegistrations: goInfo.DisableInputTypeRegistrations,
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
disableObjectDefaults: goInfo.DisableObjectDefaults,
internalModuleName: internalModuleName,
externalPackages: externalPkgs,
}
packages[mod] = pack
}
return pack
}
getPkgFromToken := func(token string) *pkgContext {
return getPkg(tokenToPackage(pkg, goInfo.ModuleToPackage, token))
}
2021-03-11 05:04:30 +00:00
var getPkgFromType func(schema.Type) *pkgContext
getPkgFromType = func(typ schema.Type) *pkgContext {
switch t := codegen.UnwrapType(typ).(type) {
2021-03-11 05:04:30 +00:00
case *schema.ArrayType:
return getPkgFromType(t.ElementType)
case *schema.MapType:
return getPkgFromType(t.ElementType)
case *schema.ObjectType:
return getPkgFromToken(t.Token)
case *schema.EnumType:
return getPkgFromToken(t.Token)
2021-03-11 05:04:30 +00:00
default:
return getPkgFromToken(t.String())
}
}
config, err := pkg.Config()
if err != nil {
return nil, err
}
if len(config) > 0 {
_ = getPkg("config")
}
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
// For any optional properties, we must generate a pointer type for the corresponding property type.
// In addition, if the optional property's type is itself an object type, we also need to generate pointer
// types corresponding to all of it's nested properties, as our accessor methods will lift `nil` into
// those nested types.
var populateDetailsForPropertyTypes func(seen codegen.StringSet, props []*schema.Property, optional, input, output bool)
var populateDetailsForTypes func(seen codegen.StringSet, schemaType schema.Type, optional, input, output bool)
2021-03-11 05:04:30 +00:00
seenKey := func(t schema.Type, optional, input, output bool) string {
var key string
switch t := t.(type) {
case *schema.ObjectType:
key = t.Token
case *schema.EnumType:
key = t.Token
default:
key = t.String()
}
if optional {
key += ",optional"
}
if input {
key += ",input"
}
if output {
key += ",output"
}
return key
}
populateDetailsForPropertyTypes = func(seen codegen.StringSet, props []*schema.Property, optional, input, output bool) {
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
for _, p := range props {
if obj, ok := codegen.UnwrapType(p.Type).(*schema.ObjectType); ok && p.Plain {
pkg := getPkgFromToken(obj.Token)
details := pkg.detailsForType(obj)
details.mark(true, false)
input = true
_, hasOptional := p.Type.(*schema.OptionalType)
details.markPtr(hasOptional, false)
}
populateDetailsForTypes(seen, p.Type, !p.IsRequired() || optional, input, output)
2021-03-11 05:04:30 +00:00
}
}
populateDetailsForTypes = func(seen codegen.StringSet, schemaType schema.Type, optional, input, output bool) {
key := seenKey(schemaType, optional, input, output)
if seen.Has(key) {
return
}
seen.Add(key)
2021-03-11 05:04:30 +00:00
switch typ := schemaType.(type) {
case *schema.InputType:
populateDetailsForTypes(seen, typ.ElementType, optional, true, false)
case *schema.OptionalType:
populateDetailsForTypes(seen, typ.ElementType, true, input, output)
2021-03-11 05:04:30 +00:00
case *schema.ObjectType:
2021-03-31 05:23:04 +00:00
pkg := getPkgFromToken(typ.Token)
pkg.detailsForType(typ).mark(input || goInfo.GenerateExtraInputTypes, output)
if optional {
pkg.detailsForType(typ).markPtr(input || goInfo.GenerateExtraInputTypes, output)
2020-11-03 07:02:56 +00:00
}
2021-03-31 05:23:04 +00:00
pkg.schemaNames.Add(tokenToName(typ.Token))
populateDetailsForPropertyTypes(seen, typ.Properties, optional, input, output)
[sdk-gen/go] Generate non-plain type variants for types used as inputs inside unions (#14679) # Description When using types in union cases (using `oneOf` in the schema) then Go SDK-gen doesn't detect these types as being used as inputs and only emits the plain version of a type. That is unless `generateExtraInputTypes: true` is specified in which case Go SDK-gen will emit the non-plain types as well. In the case of azure-native modules, `generateExtraInputTypes` is currently set to `false` (default) as of latest v2.19.0 and is missing a few non-plain type variants (for example `FirewallPolicyFilterRuleCollection` from [this file](https://raw.githubusercontent.com/pulumi/pulumi-azure-native-sdk/master/network/pulumiTypes.go)). There no single plain type in azure-native and yet it is missing these non-plain variants. This PR fixes that by also traversing the element types of schema union definitions when determining plain-ness of types and how they are used. I added an example schema with an array of unions (common case in azure-native) and confirmed that the change actually results in the non-plain types being generated when `generateExtraInputTypes` is set to `false` Fixes https://github.com/pulumi/pulumi-azure-native/issues/1922 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-29 12:37:53 +00:00
case *schema.UnionType:
for _, e := range typ.ElementTypes {
populateDetailsForTypes(seen, e, optional, input, output)
}
2021-03-11 05:04:30 +00:00
case *schema.EnumType:
2021-03-31 05:23:04 +00:00
pkg := getPkgFromToken(typ.Token)
pkg.detailsForType(typ).mark(input || goInfo.GenerateExtraInputTypes, output)
if optional {
pkg.detailsForType(typ).markPtr(input || goInfo.GenerateExtraInputTypes, output)
2021-03-11 05:04:30 +00:00
}
2021-03-31 05:23:04 +00:00
pkg.schemaNames.Add(tokenToName(typ.Token))
2021-03-11 05:04:30 +00:00
case *schema.ArrayType:
details := getPkgFromType(typ.ElementType).detailsForType(codegen.UnwrapType(typ.ElementType))
details.markArray(input || goInfo.GenerateExtraInputTypes, output)
populateDetailsForTypes(seen, typ.ElementType, false, input, output)
2021-03-11 05:04:30 +00:00
case *schema.MapType:
details := getPkgFromType(typ.ElementType).detailsForType(codegen.UnwrapType(typ.ElementType))
details.markMap(input || goInfo.GenerateExtraInputTypes, output)
populateDetailsForTypes(seen, typ.ElementType, false, input, output)
[codegen/go] Fix accessors on struct ptr outputs (#4456) * [codegen/go] Fix accessors on struct ptr outputs The accesor methods on nestred struct Ptr outputs were previously not accepting pointer typed inputs as they should, and would thus always panic if used. The "simple" fix would be to just accept the pointer type and blindly dereference it. But this doesn't seem like the right experience - it would make these accessors very unsafe to use in practice. Instead, this PR implements the accessors on pointer-typed outputs as nil-coaslescing, always lifting the output type into a pointer type and flowing a nil value into the result type. This ensures the accessor will not nil-deref, and that user code can handle the `nil` value itself (or use `.Apply` directly to implement more specialized behaviour). Before: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringOutput { return o.ApplyT(func(v BuildStorageLocation) string { return v.Bucket }).(pulumi.StringOutput) } ``` After: ```go // Name of your S3 bucket. func (o BuildStorageLocationPtrOutput) Bucket() pulumi.StringPtrOutput { return o.ApplyT(func(v *BuildStorageLocation) *string { if v == nil { return nil } return &v.Bucket }).(pulumi.StringPtrOutput) } ``` However, due to the decision to have this more usable behaviour, this is a breaking change, as some/many accessors now return a pointer type when they previously did not. Fixes pulumi/pulumi-azure#530. * Mark nested property types as requiring ptr types * Add CHANGELOG * More fixes
2020-04-21 20:33:38 +00:00
}
}
// Rewrite cyclic types. See the docs on rewriteCyclicFields for the motivation.
def, err := pkg.Definition()
if err != nil {
return nil, err
}
rewriteCyclicObjectFields(def)
// Use a string set to track object types that have already been processed.
// This avoids recursively processing the same type. For example, in the
// Kubernetes package, JSONSchemaProps have properties whose type is itself.
seenMap := codegen.NewStringSet()
for _, t := range def.Types {
2020-11-03 07:02:56 +00:00
switch typ := t.(type) {
case *schema.ArrayType:
details := getPkgFromType(typ.ElementType).detailsForType(codegen.UnwrapType(typ.ElementType))
details.markArray(goInfo.GenerateExtraInputTypes, false)
case *schema.MapType:
details := getPkgFromType(typ.ElementType).detailsForType(codegen.UnwrapType(typ.ElementType))
details.markMap(goInfo.GenerateExtraInputTypes, false)
case *schema.ObjectType:
2020-11-03 07:02:56 +00:00
pkg := getPkgFromToken(typ.Token)
if !typ.IsInputShape() {
pkg.types = append(pkg.types, typ)
}
populateDetailsForTypes(seenMap, typ, false, false, false)
2020-11-03 07:02:56 +00:00
case *schema.EnumType:
if !typ.IsOverlay {
pkg := getPkgFromToken(typ.Token)
pkg.enums = append(pkg.enums, typ)
populateDetailsForTypes(seenMap, typ, false, false, false)
}
}
}
resSeen := map[string]bool{}
typeSeen := map[string]bool{}
// compute set of names generated by a resource
// handling any potential collisions via remapping along the way
scanResource := func(r *schema.Resource) {
if resSeen[strings.ToLower(r.Token)] {
return
}
resSeen[strings.ToLower(r.Token)] = true
pkg := getPkgFromToken(r.Token)
pkg.resources = append(pkg.resources, r)
2021-03-31 05:23:04 +00:00
pkg.schemaNames.Add(tokenToName(r.Token))
getNames := func(suffix string) []string {
names := []string{}
names = append(names, rawResourceName(r)+suffix)
names = append(names, rawResourceName(r)+suffix+"Input")
names = append(names, rawResourceName(r)+suffix+"Output")
names = append(names, rawResourceName(r)+suffix+"Args")
names = append(names, cgstrings.Camel(rawResourceName(r))+suffix+"Args")
names = append(names, "New"+rawResourceName(r)+suffix)
if !r.IsProvider && !r.IsComponent {
names = append(names, rawResourceName(r)+suffix+"State")
names = append(names, cgstrings.Camel(rawResourceName(r))+suffix+"State")
names = append(names, "Get"+rawResourceName(r)+suffix)
}
if goInfo.GenerateResourceContainerTypes && !r.IsProvider {
names = append(names, rawResourceName(r)+suffix+"Array")
names = append(names, rawResourceName(r)+suffix+"Map")
}
return names
}
suffixes := []string{"", "Resource", "Res"}
suffix := ""
suffixIndex := 0
canGenerate := false
for !canGenerate && suffixIndex <= len(suffixes) {
suffix = suffixes[suffixIndex]
candidates := getNames(suffix)
conflict := false
for _, c := range candidates {
if pkg.names.Has(c) {
conflict = true
}
}
if !conflict {
canGenerate = true
break
}
suffixIndex++
}
if !canGenerate {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
panic("unable to generate Go SDK, schema has unresolvable overlapping resource: " + rawResourceName(r))
}
names := getNames(suffix)
originalNames := getNames("")
for i, n := range names {
pkg.names.Add(n)
if suffix != "" {
pkg.renamed[originalNames[i]] = names[i]
}
}
populateDetailsForPropertyTypes(seenMap, r.InputProperties, r.IsProvider, false, false)
populateDetailsForPropertyTypes(seenMap, r.Properties, r.IsProvider, false, true)
if r.StateInputs != nil {
populateDetailsForPropertyTypes(seenMap, r.StateInputs.Properties,
r.IsProvider, false /*input*/, false /*output*/)
}
for _, method := range r.Methods {
if method.Function.Inputs != nil {
pkg.names.Add(rawResourceName(r) + Title(method.Name) + "Args")
}
if method.Function.ReturnType != nil {
if _, ok := method.Function.ReturnType.(*schema.ObjectType); ok {
pkg.names.Add(rawResourceName(r) + Title(method.Name) + "Result")
}
}
}
}
scanResource(def.Provider)
for _, r := range def.Resources {
scanResource(r)
}
// compute set of names generated by a type
// handling any potential collisions via remapping along the way
scanType := func(t schema.Type) {
getNames := func(name, suffix string) []string {
return []string{name + suffix, name + suffix + "Input", name + suffix + "Output"}
}
switch t := t.(type) {
case *schema.ObjectType:
pkg := getPkgFromToken(t.Token)
// maintain support for duplicate tokens for types and resources in Kubernetes
if resSeen[strings.ToLower(t.Token)] {
pkg.duplicateTokens[strings.ToLower(t.Token)] = true
}
if typeSeen[strings.ToLower(t.Token)] {
return
}
typeSeen[strings.ToLower(t.Token)] = true
name := pkg.tokenToType(t.Token)
suffixes := []string{"", "Type", "Typ"}
suffix := ""
suffixIndex := 0
canGenerate := false
for !canGenerate && suffixIndex <= len(suffixes) {
suffix = suffixes[suffixIndex]
candidates := getNames(name, suffix)
conflict := false
for _, c := range candidates {
if pkg.names.Has(c) {
conflict = true
}
}
if !conflict {
canGenerate = true
break
}
suffixIndex++
}
if !canGenerate {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
panic("unable to generate Go SDK, schema has unresolvable overlapping type: " + name)
}
names := getNames(name, suffix)
originalNames := getNames(name, "")
for i, n := range names {
pkg.names.Add(n)
if suffix != "" {
pkg.renamed[originalNames[i]] = names[i]
}
}
case *schema.EnumType:
pkg := getPkgFromToken(t.Token)
if resSeen[t.Token] {
pkg.duplicateTokens[strings.ToLower(t.Token)] = true
}
if typeSeen[t.Token] {
return
}
typeSeen[t.Token] = true
name := pkg.tokenToEnum(t.Token)
suffixes := []string{"", "Enum"}
suffix := ""
suffixIndex := 0
canGenerate := false
for !canGenerate && suffixIndex <= len(suffixes) {
suffix = suffixes[suffixIndex]
candidates := getNames(name, suffix)
conflict := false
for _, c := range candidates {
if pkg.names.Has(c) {
conflict = true
}
}
if !conflict {
canGenerate = true
break
}
suffixIndex++
}
if !canGenerate {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
panic("unable to generate Go SDK, schema has unresolvable overlapping type: " + name)
}
names := getNames(name, suffix)
originalNames := getNames(name, "")
for i, n := range names {
pkg.names.Add(n)
if suffix != "" {
pkg.renamed[originalNames[i]] = names[i]
}
}
default:
return
}
}
for _, t := range def.Types {
scanType(t)
}
// For fnApply function versions, we need to register any
// input or output property type metadata, in case they have
// types used in array or pointer element positions.
if !goInfo.DisableFunctionOutputVersions || goInfo.GenerateExtraInputTypes {
for _, f := range def.Functions {
if f.NeedsOutputVersion() || goInfo.GenerateExtraInputTypes {
optional := false
if f.Inputs != nil {
populateDetailsForPropertyTypes(seenMap, f.Inputs.InputShape.Properties, optional, false, false)
}
if f.ReturnType != nil {
populateDetailsForTypes(seenMap, f.ReturnType, optional, false, true)
}
}
}
}
for _, f := range def.Functions {
if f.IsMethod {
continue
}
pkg := getPkgFromToken(f.Token)
pkg.functions = append(pkg.functions, f)
name := tokenToName(f.Token)
if pkg.names.Has(name) ||
pkg.names.Has(name+"Args") ||
pkg.names.Has(name+"Result") {
switch {
case strings.HasPrefix(name, "New"):
name = "Create" + name[3:]
case strings.HasPrefix(name, "Get"):
name = "Lookup" + name[3:]
}
}
pkg.names.Add(name)
pkg.functionNames[f] = name
if f.Inputs != nil && !f.MultiArgumentInputs {
pkg.names.Add(name + "Args")
}
if f.ReturnType != nil {
if objectType, ok := f.ReturnType.(*schema.ObjectType); ok && objectType != nil {
pkg.names.Add(name + "Result")
}
}
}
return packages, nil
}
// LanguageResource is derived from the schema and can be used by downstream codegen.
type LanguageResource struct {
*schema.Resource
Alias string // The package alias (e.g. appsv1)
Name string // The resource name (e.g. Deployment)
Package string // The package name (e.g. github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/apps/v1)
}
// LanguageResources returns a map of resources that can be used by downstream codegen. The map
// key is the resource schema token.
func LanguageResources(tool string, pkg *schema.Package) (map[string]LanguageResource, error) {
resources := map[string]LanguageResource{}
if err := pkg.ImportLanguages(map[string]schema.Language{"go": Importer}); err != nil {
return nil, err
}
2020-08-19 20:58:13 +00:00
var goPkgInfo GoPackageInfo
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
goPkgInfo = goInfo
}
packages, err := generatePackageContextMap(tool, pkg.Reference(), goPkgInfo, globalCache)
if err != nil {
return nil, err
}
// emit each package
pkgMods := slice.Prealloc[string](len(packages))
for mod := range packages {
pkgMods = append(pkgMods, mod)
}
sort.Strings(pkgMods)
for _, mod := range pkgMods {
if mod == "" {
continue
}
pkg := packages[mod]
for _, r := range pkg.resources {
if r.IsOverlay {
// This resource code is generated by the provider, so no further action is required.
continue
}
2020-08-19 20:58:13 +00:00
packagePath := path.Join(goPkgInfo.ImportBasePath, pkg.mod)
resources[r.Token] = LanguageResource{
Resource: r,
2020-08-19 20:58:13 +00:00
Alias: goPkgInfo.PackageImportAliases[packagePath],
Name: tokenToName(r.Token),
Package: packagePath,
}
}
}
return resources, nil
}
// packageRoot is the relative root file for go code. That means that every go
// source file should be under this root. For example:
//
// root = aws => sdk/go/aws/*.go
func packageRoot(pkg schema.PackageReference) (string, error) {
def, err := pkg.Definition()
if err != nil {
return "", err
}
var info GoPackageInfo
if goInfo, ok := def.Language["go"].(GoPackageInfo); ok {
info = goInfo
}
if info.RootPackageName != "" {
// package structure is flat
return "", nil
}
if info.ImportBasePath != "" {
return path.Base(info.ImportBasePath), nil
}
return goPackage(pkg.Name()), nil
}
// packageName is the go package name for the generated package.
func packageName(pkg *schema.Package) string {
var info GoPackageInfo
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
info = goInfo
}
if info.RootPackageName != "" {
return info.RootPackageName
}
root, err := packageRoot(pkg.Reference())
contract.AssertNoErrorf(err, "We generated the ref from a pkg, so we know its a valid ref")
return goPackage(root)
}
func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error) {
if err := pkg.ImportLanguages(map[string]schema.Language{"go": Importer}); err != nil {
return nil, err
}
2020-08-19 20:58:13 +00:00
var goPkgInfo GoPackageInfo
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
goPkgInfo = goInfo
}
packages, err := generatePackageContextMap(tool, pkg.Reference(), goPkgInfo, NewCache())
if err != nil {
return nil, err
}
// emit each package
pkgMods := slice.Prealloc[string](len(packages))
for mod := range packages {
pkgMods = append(pkgMods, mod)
}
sort.Strings(pkgMods)
name := packageName(pkg)
pathPrefix, err := packageRoot(pkg.Reference())
if err != nil {
return nil, err
}
files := codegen.Fs{}
// Generate pulumi-plugin.json
pulumiPlugin := &plugin.PulumiPluginJSON{
Resource: true,
Name: pkg.Name,
Server: pkg.PluginDownloadURL,
}
if goPkgInfo.RespectSchemaVersion && pkg.Version != nil {
pulumiPlugin.Version = pkg.Version.String()
}
pulumiPluginJSON, err := pulumiPlugin.JSON()
if err != nil {
return nil, fmt.Errorf("Failed to format pulumi-plugin.json: %w", err)
}
files.Add(path.Join(pathPrefix, "pulumi-plugin.json"), pulumiPluginJSON)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
setFileContent := func(root, relPath, contents string) {
relPath = path.Join(root, relPath)
// Run Go formatter on the code before saving to disk
formattedSource, err := format.Source([]byte(contents))
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid content:\n%s\n%s\n", relPath, contents)
panic(fmt.Errorf("invalid Go source code:\n\n%s\n: %w", relPath, err))
}
files.Add(relPath, formattedSource)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if goPkgInfo.Generics == "" {
// default is emitting the non-generic variant only
goPkgInfo.Generics = GenericsSettingNone
}
emitOnlyGenericVariant := goPkgInfo.Generics == GenericsSettingGenericsOnly
emitOnlyLegacyVariant := goPkgInfo.Generics == GenericsSettingNone
setFile := func(relPath, contents string) {
if emitOnlyGenericVariant {
// if we only want the generic variant to be emitted
// skip generating the default "legacy" variant
return
}
setFileContent(pathPrefix, relPath, contents)
}
setGenericVariantFile := func(relPath, contents string) {
if emitOnlyLegacyVariant {
// if we only want the legacy variant to be emitted
// skip generating the generic variant
return
}
root := path.Join(pathPrefix, "x")
if emitOnlyGenericVariant {
// if we only want the generic variant to be emitted
// emit it at the root of the package as the default package
root = pathPrefix
}
setFileContent(root, relPath, contents)
}
for _, mod := range pkgMods {
pkg := packages[mod]
// Config, description
switch mod {
case "":
buffer := &bytes.Buffer{}
if pkg.pkg.Description() != "" {
printComment(buffer, pkg.pkg.Description(), false)
} else {
fmt.Fprintf(buffer, "// Package %[1]s exports types, functions, subpackages for provisioning %[1]s resources.\n", name)
}
fmt.Fprintf(buffer, "package %s\n", name)
setFile(path.Join(mod, "doc.go"), buffer.String())
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
setGenericVariantFile(path.Join(mod, "doc.go"), buffer.String())
// Version
versionBuf := &bytes.Buffer{}
importsAndAliases := map[string]string{}
2023-07-06 20:20:04 +00:00
pkg.genHeader(versionBuf, []string{"github.com/blang/semver"}, importsAndAliases, true /* isUtil */)
err = pkg.GenVersionFile(versionBuf)
if err != nil {
return nil, err
}
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
versionFilePath := pkg.internalModuleName + "/pulumiVersion.go"
setFile(path.Join(mod, versionFilePath), versionBuf.String())
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if emitOnlyGenericVariant {
setGenericVariantFile(path.Join(mod, versionFilePath), versionBuf.String())
}
case "config":
config, err := pkg.pkg.Config()
if err != nil {
return nil, err
}
if len(config) > 0 {
buffer := &bytes.Buffer{}
if err := pkg.genConfig(buffer, config); err != nil {
return nil, err
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
configFilePath := path.Join(mod, "config.go")
setFile(configFilePath, buffer.String())
setGenericVariantFile(configFilePath, buffer.String())
}
}
// Resources
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
for _, resource := range pkg.resources {
if resource.IsOverlay {
// This resource code is generated by the provider, so no further action is required.
continue
}
importsAndAliases := map[string]string{}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.getImports(resource, importsAndAliases)
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumi"] = ""
importsAndAliases[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
if goPkgInfo.Generics == GenericsSettingSideBySide {
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
}
buffer := &bytes.Buffer{}
2023-07-06 20:20:04 +00:00
pkg.genHeader(buffer, []string{"context", "reflect"}, importsAndAliases, false /* isUtil */)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genResource(
buffer,
resource,
goPkgInfo.GenerateResourceContainerTypes,
false /* useGenericVariant */); err != nil {
return nil, err
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
resourceFilePath := path.Join(mod, cgstrings.Camel(rawResourceName(resource))+".go")
setFile(resourceFilePath, buffer.String())
genericVariantBuffer := &bytes.Buffer{}
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
pkg.genHeader(genericVariantBuffer, []string{"context", "reflect"}, importsAndAliases, false /* isUtil */)
if err := pkg.genResource(
genericVariantBuffer,
resource,
goPkgInfo.GenerateResourceContainerTypes,
true /* useGenericVariant */); err != nil {
return nil, err
}
setGenericVariantFile(resourceFilePath, genericVariantBuffer.String())
}
// Functions
for _, f := range pkg.functions {
if f.IsOverlay {
// This function code is generated by the provider, so no further action is required.
continue
}
fileName := path.Join(mod, cgstrings.Camel(tokenToName(f.Token))+".go")
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
code, err := pkg.genFunctionCodeFile(f)
if err != nil {
return nil, err
}
setFile(fileName, code)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
genericCodeVariant, err := pkg.genGenericVariantFunctionCodeFile(f)
if err != nil {
return nil, err
}
setGenericVariantFile(fileName, genericCodeVariant)
}
2021-03-11 05:04:30 +00:00
knownTypes := make(map[schema.Type]struct{}, len(pkg.typeDetails))
for t := range pkg.typeDetails {
knownTypes[t] = struct{}{}
}
2020-11-03 07:02:56 +00:00
// Enums
if len(pkg.enums) > 0 {
hasOutputs, imports := false, map[string]string{}
2020-11-03 07:02:56 +00:00
for _, e := range pkg.enums {
pkg.getImports(e, imports)
hasOutputs = hasOutputs || pkg.detailsForType(e).hasOutputs()
}
var goImports []string
if hasOutputs {
goImports = []string{"context", "reflect"}
imports["github.com/pulumi/pulumi/sdk/v3/go/pulumi"] = ""
imports["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
2020-11-03 07:02:56 +00:00
}
buffer := &bytes.Buffer{}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
genericVariantBuffer := &bytes.Buffer{}
2023-07-06 20:20:04 +00:00
pkg.genHeader(buffer, goImports, imports, false /* isUtil */)
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// we do not need any imports for the generic variant
pkg.genHeader(genericVariantBuffer, []string{}, map[string]string{}, false /* isUtil */)
2020-11-03 07:02:56 +00:00
for _, e := range pkg.enums {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
// generate enums for legacy variant
if err := pkg.genEnum(buffer, e, false); err != nil {
return nil, err
}
// generate enums for generic variant
if err := pkg.genEnum(genericVariantBuffer, e, true); err != nil {
2020-11-18 18:57:01 +00:00
return nil, err
}
2021-03-11 05:04:30 +00:00
delete(knownTypes, e)
2020-11-03 07:02:56 +00:00
}
pkg.genEnumRegistrations(buffer)
2020-11-03 07:02:56 +00:00
setFile(path.Join(mod, "pulumiEnums.go"), buffer.String())
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
setGenericVariantFile(path.Join(mod, "pulumiEnums.go"), genericVariantBuffer.String())
2020-11-03 07:02:56 +00:00
}
2021-03-11 05:04:30 +00:00
// Types
sortedKnownTypes := slice.Prealloc[schema.Type](len(knownTypes))
for k := range knownTypes {
sortedKnownTypes = append(sortedKnownTypes, k)
}
sort.Slice(sortedKnownTypes, func(i, j int) bool {
return sortedKnownTypes[i].String() < sortedKnownTypes[j].String()
})
if len(pkg.types) == 0 && len(pkg.enums) > 0 {
// If there are no types, but there are enums, we still need to generate the types file.
// with the associated nested collection enum types such as arrays of enums, maps of enums etc.
collectionTypes := map[string]*nestedTypeInfo{}
for _, t := range sortedKnownTypes {
pkg.collectNestedCollectionTypes(collectionTypes, t)
}
if len(collectionTypes) > 0 {
buffer := &bytes.Buffer{}
useGenericVariant := false
err := generateTypes(buffer, pkg, []*schema.ObjectType{}, sortedKnownTypes, useGenericVariant)
if err != nil {
return nil, err
}
typeFilePath := path.Join(mod, "pulumiTypes.go")
setFile(typeFilePath, buffer.String())
genericVariantBuffer := &bytes.Buffer{}
useGenericVariant = true
err = generateTypes(genericVariantBuffer, pkg, []*schema.ObjectType{}, sortedKnownTypes, useGenericVariant)
if err != nil {
return nil, err
}
setGenericVariantFile(typeFilePath, genericVariantBuffer.String())
}
}
for types, i := pkg.types, 0; len(types) > 0; i++ {
// 500 types corresponds to approximately 5M or 40_000 lines of code.
const chunkSize = 500
chunk := types
if len(chunk) > chunkSize {
chunk = chunk[:chunkSize]
2021-03-11 05:04:30 +00:00
}
types = types[len(chunk):]
2021-03-11 05:04:30 +00:00
// To avoid duplicating collection types into every chunk, only pass known to chunk i=0.
known := sortedKnownTypes
if i != 0 {
known = nil
}
2021-03-11 05:04:30 +00:00
buffer := &bytes.Buffer{}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
useGenericVariant := false
err := generateTypes(buffer, pkg, chunk, known, useGenericVariant)
if err != nil {
return nil, err
2021-03-11 05:04:30 +00:00
}
typePath := "pulumiTypes"
if i != 0 {
typePath = fmt.Sprintf("%s%d", typePath, i)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
typeFilePath := path.Join(mod, typePath+".go")
setFile(typeFilePath, buffer.String())
genericVariantBuffer := &bytes.Buffer{}
useGenericVariant = true
err = generateTypes(genericVariantBuffer, pkg, chunk, known, useGenericVariant)
if err != nil {
return nil, err
}
setGenericVariantFile(typeFilePath, genericVariantBuffer.String())
2021-03-11 05:04:30 +00:00
}
// Utilities
if len(mod) == 0 {
buffer := &bytes.Buffer{}
importsAndAliases := map[string]string{
"github.com/blang/semver": "",
"github.com/pulumi/pulumi/sdk/v3/go/pulumi": "",
}
2023-07-06 20:20:04 +00:00
pkg.genHeader(buffer, []string{"fmt", "os", "reflect", "regexp", "strconv", "strings"}, importsAndAliases, true /* isUtil */)
packageRegex := fmt.Sprintf("^.*/pulumi-%s/sdk(/v\\d+)?", pkg.pkg.Name())
if pkg.rootPackageName != "" {
packageRegex = fmt.Sprintf("^%s(/v\\d+)?", pkg.importBasePath)
}
err := pkg.GenUtilitiesFile(buffer, packageRegex)
if err != nil {
return nil, err
}
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
utilFilePath := pkg.internalModuleName + "/pulumiUtilities.go"
setFile(path.Join(mod, utilFilePath), buffer.String())
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if emitOnlyGenericVariant {
setGenericVariantFile(path.Join(mod, utilFilePath), buffer.String())
}
}
// If there are resources in this module, register the module with the runtime.
if len(pkg.resources) != 0 && !allResourcesAreOverlays(pkg.resources) {
buffer := &bytes.Buffer{}
err := pkg.genResourceModule(buffer)
if err != nil {
return nil, err
}
setFile(path.Join(mod, "init.go"), buffer.String())
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
genericVariantBuffer := &bytes.Buffer{}
if err := pkg.genResourceModule(genericVariantBuffer); err != nil {
return nil, err
}
setGenericVariantFile(path.Join(mod, "init.go"), genericVariantBuffer.String())
}
}
return files, nil
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
func generateTypes(
w io.Writer,
pkg *pkgContext,
types []*schema.ObjectType,
knownTypes []schema.Type,
useGenericTypes bool,
) error {
hasOutputs, importsAndAliases := false, map[string]string{}
for _, t := range types {
pkg.getImports(t, importsAndAliases)
hasOutputs = hasOutputs || pkg.detailsForType(t).hasOutputs()
}
collectionTypes := map[string]*nestedTypeInfo{}
for _, t := range knownTypes {
pkg.collectNestedCollectionTypes(collectionTypes, t)
}
// All collection types have Outputs
if len(collectionTypes) > 0 {
hasOutputs = true
}
goInfo := goPackageInfo(pkg.pkg)
var goImports []string
if hasOutputs {
goImports = []string{"context", "reflect"}
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumi"] = ""
if goInfo.Generics == GenericsSettingSideBySide {
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if useGenericTypes && hasOutputs {
importsAndAliases["github.com/pulumi/pulumi/sdk/v3/go/pulumix"] = ""
}
importsAndAliases[path.Join(pkg.importBasePath, pkg.internalModuleName)] = ""
2023-07-06 20:20:04 +00:00
pkg.genHeader(w, goImports, importsAndAliases, false /* isUtil */)
// in case we're not using the internal package, assign to a blank var
fmt.Fprintf(w, "var _ = %s.GetEnvOrDefault\n", pkg.internalModuleName)
for _, t := range types {
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
if err := pkg.genType(w, t, useGenericTypes); err != nil {
return err
}
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
typeNames := []string{}
if !useGenericTypes {
typeNames = pkg.genNestedCollectionTypes(w, collectionTypes)
}
[go/sdk-gen] Generating SDK with generics (#13828) # Description This PR implements generating the generic variant of a go SDK from Pulumi schemas. Currently the idea is to generate a directory `x` inside the root directory of the go SDK which will contain the same SDK except using generics and generating far less code than its current counter part. Also implements an enum option `$.language.go.generics` which can be set to the following: - `none` is the default which maintains the current behavior that generates legacy types without generics - `side-by-side` generates the generics sdk variant alongside the current sdk under directory `x` - `generics-only` generates only the new sdk with generics at the root of the package Still a bunch of things to do: - [x] Generating `InvokeResult]Output` type from `Output[InvokeResult]` and generating accessor methods for it - [x] Generating default values for types and using the `pulumix` subpackage to do so - [x] Generating generic SDK variants for all test schemas we have and making sure they compile (currently only testing `simple-resource-schema` as shown below) - [x] Account for plain inputs for components - [x] Combine pulumix.Join with pulumix.Apply to generate resource accessor methods - [x] Problem with `GPtrOutput[T]` and `ArrayOutput[T]` being unwrapped to `Output[*T]` and `Output[[]T]` - [x] Remove excess untyped container types from generated enums - [x] Fix default values for resource methods with lifted single return value - [x] Secret properties Currently the following test schemas have opted for `generics: "side-by-side"`: - [x] output-funcs - [x] simple-enum-schema - [x] secrets - [x] simple-plain-schema - [x] plain-and-default ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-19 10:28:50 +00:00
pkg.genTypeRegistrations(w, types, useGenericTypes, typeNames...)
return nil
}
func allResourcesAreOverlays(resources []*schema.Resource) bool {
for _, r := range resources {
if !r.IsOverlay {
return false
}
}
return true
}
// goPackage returns the suggested package name for the given string.
func goPackage(name string) string {
return strings.ReplaceAll(name, "-", "")
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
//go:embed embeddedUtilities.go
var embeddedUtilities string
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
func (pkg *pkgContext) GenUtilitiesFile(w io.Writer, packageRegex string) error {
subtitutions := map[string]string{
`"${packageRegex}"`: fmt.Sprintf("%q", packageRegex),
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
i := strings.Index(embeddedUtilities, "package utilities")
code := embeddedUtilities[i+len("package utilities"):]
for x, y := range subtitutions {
code = strings.ReplaceAll(code, x, y)
[codegen/go] Call site defaults for Pulumi Object types (#8411) * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add feature flag for go * Add required+default test case * Don't `<any>` cast known types. * Add more flags. I realize this should really wait for PR#8400 to merge. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Add test case * Fix tests * Add test dependencies correctly * Feed through error handling * Include test output * Get types to line up * Add remaining test files * Update changelog * Correctly find type paths * Handle transitive objects * Handle required fields * Add required+default test case * Don't `<any>` cast known types. * Add plain object to env-helper test This test fails right now. My next problem is fixing it. * Handle plain types * Handle function inputs * Fix the indentation * Handle output types correctly * Remove unnecessary `!` * Start on `genPlainObjectDefaultFunc` * Add missing change to fix test * Run tests with merge * Refactor out assign * Merge in next _index.md diff * Change method name to `Defaults` * Handle enums correctly * Another attempt at _index.md * Make module generation deterministic * Add checks for old values * Insert defaults in resources * Fix docs generation Credit to @praneetloke * Progress on adding defaults to Resource arguments * Handle resource argument defaults * Don't create defaults if disableObjectDefaults * Rename test folder * Add test for disable flag * Fix disable test * Update docs * Abstract out nil comparisons * Use reflection to test for empty values * Simplify Ptr and pulumi.Any type handling * Remove unused function * Apply defaults to functions * Update new test with master codegen * Tests + nil check
2021-11-23 23:10:15 +00:00
}
Support returning plain values from methods (#13592) Support returning plain values from methods. Implements Node, Python and Go support. Remaining: - [x] test receiving unknowns - [x] acceptance tests written and passing locally for Node, Python, Go clients against a Go server - [x] acceptance tests passing in CI - [x] tickets filed for remaining languages - [x] https://github.com/pulumi/pulumi-yaml/issues/499 - [x] https://github.com/pulumi/pulumi-java/issues/1193 - [x] https://github.com/pulumi/pulumi-dotnet/issues/170 Known limitations: - this is technically a breaking change in case there is code out there that already uses methods that return Plain: true - struct-wrapping limitation: the provider for the component resource needs to still wrap the plain-returning Method response with a 1-arg struct; by convention the field is named "res", and this is how it travels through the plumbing - resources cannot return plain values yet - the provider for the component resource cannot have unknown configuration, if it does, the methods will not be called - Per Luke https://github.com/pulumi/pulumi/issues/11520 this might not be supported/realizable yet <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/12709 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-18 06:02:06 +00:00
_, err := fmt.Fprintf(w, "%s", code)
if err != nil {
return err
}
return pkg.GenPkgDefaultOpts(w)
}
func (pkg *pkgContext) GenVersionFile(w io.Writer) error {
const versionFile = `var SdkVersion semver.Version = semver.Version{}
2023-06-08 19:15:55 +00:00
var pluginDownloadURL string = ""
`
_, err := fmt.Fprint(w, versionFile)
return err
}
func (pkg *pkgContext) GenPkgDefaultOpts(w io.Writer) error {
p, err := pkg.pkg.Definition()
if err != nil {
return err
}
url := p.PluginDownloadURL
const template string = `
// Pkg%[1]sDefaultOpts provides package level defaults to pulumi.Option%[1]s.
func Pkg%[1]sDefaultOpts(opts []pulumi.%[1]sOption) []pulumi.%[1]sOption {
2023-06-08 22:58:39 +00:00
defaults := []pulumi.%[1]sOption{}
%[2]s
version := %[3]s
if !version.Equals(semver.Version{}){
defaults = append(defaults, pulumi.Version(version.String()))
}
return append(defaults, opts...)
}
`
2023-06-08 22:58:39 +00:00
var pluginDownloadURL string
if url != "" {
pluginDownloadURL = fmt.Sprintf(`defaults = append(defaults, pulumi.PluginDownloadURL("%s"))`, url)
}
2023-06-08 19:15:55 +00:00
versionPackageRef := "SdkVersion"
versionPkgName := strings.ReplaceAll(pkg.pkg.Name(), "-", "")
2023-06-08 19:15:55 +00:00
2023-06-08 22:58:39 +00:00
if pkg.mod != "" {
2023-06-08 19:15:55 +00:00
versionPackageRef = versionPkgName + "." + versionPackageRef
}
if info := p.Language["go"]; info != nil {
if info.(GoPackageInfo).RespectSchemaVersion && pkg.pkg.Version() != nil {
2023-06-08 22:58:39 +00:00
versionPackageRef = fmt.Sprintf("semver.MustParse(%q)", p.Version.String())
}
}
for _, typ := range []string{"Resource", "Invoke"} {
2023-06-08 22:58:39 +00:00
_, err := fmt.Fprintf(w, template, typ, pluginDownloadURL, versionPackageRef)
if err != nil {
return err
}
}
return nil
}
// GenPkgDefaultsOptsCall generates a call to Pkg{TYPE}DefaultsOpts.
func (pkg *pkgContext) GenPkgDefaultsOptsCall(w io.Writer, invoke bool) error {
typ := "Resource"
if invoke {
typ = "Invoke"
}
_, err := fmt.Fprintf(w, "\topts = %s.Pkg%sDefaultOpts(opts)\n", pkg.internalModuleName, typ)
if err != nil {
return err
}
return nil
}