Merge branch 'master' of https://github.com/pulumi/pulumi into evan/gomod
This commit is contained in:
commit
ce1928988b
|
@ -787,11 +787,16 @@ func (b *cloudBackend) RenameStack(ctx context.Context, stack backend.Stack, new
|
|||
return err
|
||||
}
|
||||
|
||||
// Transferring stack ownership is available to Pulumi admins, but isn't quite ready
|
||||
// for general use yet.
|
||||
if stackID.Owner != newIdentity.Owner {
|
||||
url := "."
|
||||
|
||||
if consoleURL, err := b.StackConsoleURL(stack.Ref()); err == nil {
|
||||
url = ":\n" + consoleURL + "/settings/options"
|
||||
}
|
||||
errMsg := "You cannot transfer stack ownership via a rename. If you wish to transfer ownership\n" +
|
||||
"of a stack to another organization, please contact support@pulumi.com."
|
||||
"of a stack to another organization, you can do so in the Pulumi Console by going to the\n" +
|
||||
"\"Settings\" page of the stack and then clicking the \"Transfer Stack\" button" + url
|
||||
|
||||
return errors.Errorf(errMsg)
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,12 @@ var (
|
|||
templates *template.Template
|
||||
packagedTemplates map[string][]byte
|
||||
docHelpers map[string]codegen.DocLanguageHelper
|
||||
|
||||
// The following property case maps are for rendering property
|
||||
// names of nested properties in Python language with the correct
|
||||
// casing.
|
||||
snakeCaseToCamelCase map[string]string
|
||||
camelCaseToSnakeCase map[string]string
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -62,6 +68,9 @@ func init() {
|
|||
docHelpers[lang] = python.DocLanguageHelper{}
|
||||
}
|
||||
}
|
||||
|
||||
snakeCaseToCamelCase = map[string]string{}
|
||||
camelCaseToSnakeCase = map[string]string{}
|
||||
}
|
||||
|
||||
// header represents the header of each resource markdown file.
|
||||
|
@ -446,7 +455,7 @@ func (mod *modContext) genNestedTypes(member interface{}, resourceType bool) []d
|
|||
InputType: inputTypeDocLink,
|
||||
OutputType: outputTypeDocLink,
|
||||
}
|
||||
props[lang] = mod.getProperties(obj.Properties, lang, true)
|
||||
props[lang] = mod.getProperties(obj.Properties, lang, true, true)
|
||||
}
|
||||
|
||||
objs = append(objs, docNestedType{
|
||||
|
@ -467,7 +476,7 @@ func (mod *modContext) genNestedTypes(member interface{}, resourceType bool) []d
|
|||
|
||||
// getProperties returns a slice of properties that can be rendered for docs for
|
||||
// the provided slice of properties in the schema.
|
||||
func (mod *modContext) getProperties(properties []*schema.Property, lang string, isInput bool) []property {
|
||||
func (mod *modContext) getProperties(properties []*schema.Property, lang string, input, nested bool) []property {
|
||||
if len(properties) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -479,15 +488,40 @@ func (mod *modContext) getProperties(properties []*schema.Property, lang string,
|
|||
}
|
||||
|
||||
characteristics := propertyCharacteristics{
|
||||
input: isInput,
|
||||
input: input,
|
||||
optional: !prop.IsRequired,
|
||||
}
|
||||
|
||||
propLangName := prop.Name
|
||||
switch lang {
|
||||
case "python":
|
||||
pyName := python.PyName(prop.Name)
|
||||
// The default casing for a Python property name is snake_case unless
|
||||
// it is a property of a nested object, in which case, we should check the property
|
||||
// case maps.
|
||||
propLangName = pyName
|
||||
|
||||
if nested {
|
||||
if snakeCase, ok := camelCaseToSnakeCase[prop.Name]; ok {
|
||||
propLangName = snakeCase
|
||||
} else if camelCase, ok := snakeCaseToCamelCase[pyName]; ok {
|
||||
propLangName = camelCase
|
||||
} else {
|
||||
// If neither of the property case maps have the property
|
||||
// then use the default name of the property.
|
||||
propLangName = prop.Name
|
||||
}
|
||||
}
|
||||
case "go", "csharp":
|
||||
propLangName = strings.Title(prop.Name)
|
||||
}
|
||||
|
||||
docProperties = append(docProperties, property{
|
||||
Name: getLanguagePropertyName(prop.Name, lang, true),
|
||||
Name: wbr(propLangName),
|
||||
Comment: prop.Comment,
|
||||
DeprecationMessage: prop.DeprecationMessage,
|
||||
IsRequired: prop.IsRequired,
|
||||
IsInput: isInput,
|
||||
IsInput: input,
|
||||
Type: mod.typeString(prop.Type, lang, characteristics, true),
|
||||
})
|
||||
}
|
||||
|
@ -765,13 +799,13 @@ func (mod *modContext) genResource(r *schema.Resource) resourceDocArgs {
|
|||
outputProps := make(map[string][]property)
|
||||
stateInputs := make(map[string][]property)
|
||||
for _, lang := range supportedLanguages {
|
||||
inputProps[lang] = mod.getProperties(r.InputProperties, lang, true)
|
||||
inputProps[lang] = mod.getProperties(r.InputProperties, lang, true, false)
|
||||
if r.IsProvider {
|
||||
continue
|
||||
}
|
||||
outputProps[lang] = mod.getProperties(r.Properties, lang, false)
|
||||
outputProps[lang] = mod.getProperties(r.Properties, lang, false, false)
|
||||
if r.StateInputs != nil {
|
||||
stateInputs[lang] = mod.getProperties(r.StateInputs.Properties, lang, true)
|
||||
stateInputs[lang] = mod.getProperties(r.StateInputs.Properties, lang, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,6 +910,7 @@ func (mod *modContext) genHeader(w io.Writer, title string) {
|
|||
|
||||
fmt.Fprintf(w, "---\n")
|
||||
fmt.Fprintf(w, "title: %q\n", title)
|
||||
fmt.Fprintf(w, "block_external_search_index: true\n")
|
||||
fmt.Fprintf(w, "---\n\n")
|
||||
|
||||
fmt.Fprintf(w, "<!-- WARNING: this file was generated by %v. -->\n", mod.tool)
|
||||
|
@ -1064,6 +1099,8 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
}
|
||||
|
||||
types := &modContext{pkg: pkg, mod: "types", tool: tool}
|
||||
docHelper := getLanguageDocHelper("python")
|
||||
pyHelper := docHelper.(python.DocLanguageHelper)
|
||||
|
||||
for _, v := range pkg.Config {
|
||||
visitObjectTypes(v.Type, func(t *schema.ObjectType) { types.details(t).outputType = true })
|
||||
|
@ -1072,10 +1109,16 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
scanResource := func(r *schema.Resource) {
|
||||
mod := getMod(r.Token)
|
||||
mod.resources = append(mod.resources, r)
|
||||
|
||||
for _, p := range r.Properties {
|
||||
pyHelper.GenPropertyCaseMap(mod.pkg, mod.mod, tool, p, snakeCaseToCamelCase, camelCaseToSnakeCase)
|
||||
|
||||
visitObjectTypes(p.Type, func(t *schema.ObjectType) { types.details(t).outputType = true })
|
||||
}
|
||||
|
||||
for _, p := range r.InputProperties {
|
||||
pyHelper.GenPropertyCaseMap(mod.pkg, mod.mod, tool, p, snakeCaseToCamelCase, camelCaseToSnakeCase)
|
||||
|
||||
visitObjectTypes(p.Type, func(t *schema.ObjectType) {
|
||||
if r.IsProvider {
|
||||
types.details(t).outputType = true
|
||||
|
@ -1083,6 +1126,7 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
types.details(t).inputType = true
|
||||
})
|
||||
}
|
||||
|
||||
if r.StateInputs != nil {
|
||||
visitObjectTypes(r.StateInputs, func(t *schema.ObjectType) { types.details(t).inputType = true })
|
||||
}
|
||||
|
|
|
@ -285,10 +285,10 @@ func (mod *modContext) genFunction(f *schema.Function) functionDocArgs {
|
|||
outputProps := make(map[string][]property)
|
||||
for _, lang := range supportedLanguages {
|
||||
if f.Inputs != nil {
|
||||
inputProps[lang] = mod.getProperties(f.Inputs.Properties, lang, true)
|
||||
inputProps[lang] = mod.getProperties(f.Inputs.Properties, lang, true, false)
|
||||
}
|
||||
if f.Outputs != nil {
|
||||
outputProps[lang] = mod.getProperties(f.Outputs.Properties, lang, false)
|
||||
outputProps[lang] = mod.getProperties(f.Outputs.Properties, lang, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3
pkg/codegen/docs/templates/header.tmpl
vendored
3
pkg/codegen/docs/templates/header.tmpl
vendored
|
@ -1,8 +1,9 @@
|
|||
{{ define "header" }}
|
||||
---
|
||||
title: "{{ .Title }}"
|
||||
block_external_search_index: true
|
||||
---
|
||||
<style>
|
||||
table td p { margin-top: 0; margin-bottom: 0; }
|
||||
</style>
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/codegen/python"
|
||||
"github.com/pulumi/pulumi/sdk/go/common/util/contract"
|
||||
)
|
||||
|
||||
|
@ -64,19 +63,3 @@ func tokenToName(tok string) string {
|
|||
contract.Assertf(len(components) == 3, "malformed token %v", tok)
|
||||
return strings.Title(components[2])
|
||||
}
|
||||
|
||||
// getLanguagePropertyName returns a language-specific representation of a given
|
||||
// property name.
|
||||
func getLanguagePropertyName(name string, lang string, insertWordBreak bool) string {
|
||||
switch lang {
|
||||
case "python":
|
||||
name = python.PyName(name)
|
||||
case "go", "csharp":
|
||||
name = strings.Title(name)
|
||||
}
|
||||
|
||||
if !insertWordBreak {
|
||||
return name
|
||||
}
|
||||
return wbr(name)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"path"
|
||||
"reflect"
|
||||
|
@ -31,6 +32,7 @@ import (
|
|||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/codegen/schema"
|
||||
"github.com/pulumi/pulumi/sdk/go/common/util/contract"
|
||||
)
|
||||
|
@ -96,6 +98,7 @@ type pkgContext struct {
|
|||
functionNames map[*schema.Function]string
|
||||
needsUtils bool
|
||||
tool string
|
||||
packages map[string]*pkgContext
|
||||
|
||||
// Name overrides set in GoInfo
|
||||
modToPkg map[string]string // Module name -> package name
|
||||
|
@ -123,14 +126,18 @@ func (pkg *pkgContext) tokenToType(tok string) string {
|
|||
mod = override
|
||||
}
|
||||
|
||||
// If the package containing the type's token already has a resource with the
|
||||
// same name, add a `Type` suffix.
|
||||
modPkg := pkg.getPkg(mod)
|
||||
name = title(name)
|
||||
if modPkg.names.has(name) {
|
||||
name += "Type"
|
||||
}
|
||||
|
||||
if mod == pkg.mod {
|
||||
name := title(name)
|
||||
if pkg.names.has(name) {
|
||||
name += "Type"
|
||||
}
|
||||
return name
|
||||
}
|
||||
return strings.Replace(mod, "/", "", -1) + "." + title(name)
|
||||
return strings.Replace(mod, "/", "", -1) + "." + name
|
||||
}
|
||||
|
||||
func tokenToName(tok string) string {
|
||||
|
@ -749,16 +756,16 @@ func (pkg *pkgContext) genTypeRegistrations(w io.Writer, types []*schema.ObjectT
|
|||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
|
||||
func (pkg *pkgContext) getTypeImports(t schema.Type, recurse bool, imports stringSet) {
|
||||
func (pkg *pkgContext) getTypeImports(t schema.Type, recurse bool, imports stringSet, seen map[schema.Type]struct{}) {
|
||||
if _, ok := seen[t]; ok {
|
||||
return
|
||||
}
|
||||
seen[t] = struct{}{}
|
||||
switch t := t.(type) {
|
||||
case *schema.ArrayType:
|
||||
if recurse {
|
||||
pkg.getTypeImports(t.ElementType, false, imports)
|
||||
}
|
||||
pkg.getTypeImports(t.ElementType, recurse, imports, seen)
|
||||
case *schema.MapType:
|
||||
if recurse {
|
||||
pkg.getTypeImports(t.ElementType, false, imports)
|
||||
}
|
||||
pkg.getTypeImports(t.ElementType, recurse, imports, seen)
|
||||
case *schema.ObjectType:
|
||||
mod := pkg.pkg.TokenToModule(t.Token)
|
||||
if override, ok := pkg.modToPkg[mod]; ok {
|
||||
|
@ -770,28 +777,27 @@ func (pkg *pkgContext) getTypeImports(t schema.Type, recurse bool, imports strin
|
|||
|
||||
for _, p := range t.Properties {
|
||||
if recurse {
|
||||
pkg.getTypeImports(p.Type, false, imports)
|
||||
pkg.getTypeImports(p.Type, recurse, imports, seen)
|
||||
}
|
||||
}
|
||||
case *schema.UnionType:
|
||||
for _, e := range t.ElementTypes {
|
||||
if recurse {
|
||||
pkg.getTypeImports(e, false, imports)
|
||||
}
|
||||
pkg.getTypeImports(e, recurse, imports, seen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pkg *pkgContext) getImports(member interface{}, imports stringSet) {
|
||||
seen := map[schema.Type]struct{}{}
|
||||
switch member := member.(type) {
|
||||
case *schema.ObjectType:
|
||||
pkg.getTypeImports(member, true, imports)
|
||||
pkg.getTypeImports(member, true, imports, seen)
|
||||
case *schema.Resource:
|
||||
for _, p := range member.Properties {
|
||||
pkg.getTypeImports(p.Type, false, imports)
|
||||
pkg.getTypeImports(p.Type, false, imports, seen)
|
||||
}
|
||||
for _, p := range member.InputProperties {
|
||||
pkg.getTypeImports(p.Type, false, imports)
|
||||
pkg.getTypeImports(p.Type, false, imports, seen)
|
||||
|
||||
if p.IsRequired {
|
||||
imports.add("github.com/pkg/errors")
|
||||
|
@ -799,14 +805,14 @@ func (pkg *pkgContext) getImports(member interface{}, imports stringSet) {
|
|||
}
|
||||
case *schema.Function:
|
||||
if member.Inputs != nil {
|
||||
pkg.getTypeImports(member.Inputs, false, imports)
|
||||
pkg.getTypeImports(member.Inputs, false, imports, seen)
|
||||
}
|
||||
if member.Outputs != nil {
|
||||
pkg.getTypeImports(member.Outputs, false, imports)
|
||||
pkg.getTypeImports(member.Outputs, false, imports, seen)
|
||||
}
|
||||
case []*schema.Property:
|
||||
for _, p := range member {
|
||||
pkg.getTypeImports(p.Type, false, imports)
|
||||
pkg.getTypeImports(p.Type, false, imports, seen)
|
||||
}
|
||||
default:
|
||||
return
|
||||
|
@ -918,6 +924,17 @@ func (pkg *pkgContext) genPackageRegistration(w io.Writer) {
|
|||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
|
||||
func (pkg *pkgContext) getPkg(mod string) *pkgContext {
|
||||
if override, ok := pkg.modToPkg[mod]; ok {
|
||||
mod = override
|
||||
}
|
||||
pack, ok := pkg.packages[mod]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return pack
|
||||
}
|
||||
|
||||
// GoInfo holds information required to generate the Go SDK from a schema.
|
||||
type GoInfo struct {
|
||||
// Base path for package imports
|
||||
|
@ -940,9 +957,10 @@ type GoInfo struct {
|
|||
|
||||
func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error) {
|
||||
var goInfo GoInfo
|
||||
err := json.Unmarshal(pkg.Language["go"], &goInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if golang, ok := pkg.Language["go"]; ok {
|
||||
if err := json.Unmarshal(golang, &goInfo); err != nil {
|
||||
return nil, errors.Wrap(err, "decoding go package info")
|
||||
}
|
||||
}
|
||||
|
||||
// group resources, types, and functions into Go packages
|
||||
|
@ -965,6 +983,7 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
tool: tool,
|
||||
modToPkg: goInfo.ModuleToPackage,
|
||||
pkgImportAliases: goInfo.PackageImportAliases,
|
||||
packages: packages,
|
||||
}
|
||||
packages[mod] = pack
|
||||
}
|
||||
|
@ -1061,7 +1080,14 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
if _, ok := files[relPath]; ok {
|
||||
panic(errors.Errorf("duplicate file: %s", relPath))
|
||||
}
|
||||
files[relPath] = []byte(contents)
|
||||
|
||||
// Run Go formatter on the code before saving to disk
|
||||
formattedSource, err := format.Source([]byte(contents))
|
||||
if err != nil {
|
||||
panic(errors.Errorf("invalid Go source code:\n\n%s", contents))
|
||||
}
|
||||
|
||||
files[relPath] = formattedSource
|
||||
}
|
||||
|
||||
name, registerPackage := pkg.Name, pkg.Provider != nil
|
||||
|
|
|
@ -77,6 +77,21 @@ func (d DocLanguageHelper) GetResourceFunctionResultName(resourceName string) st
|
|||
return ""
|
||||
}
|
||||
|
||||
// GenPropertyCaseMap generates the case maps for a property.
|
||||
func (d DocLanguageHelper) GenPropertyCaseMap(pkg *schema.Package, modName, tool string, prop *schema.Property, snakeCaseToCamelCase, camelCaseToSnakeCase map[string]string) {
|
||||
mod := &modContext{
|
||||
pkg: pkg,
|
||||
mod: modName,
|
||||
tool: tool,
|
||||
snakeCaseToCamelCase: snakeCaseToCamelCase,
|
||||
camelCaseToSnakeCase: camelCaseToSnakeCase,
|
||||
}
|
||||
|
||||
if err := mod.recordProperty(prop); err != nil {
|
||||
fmt.Printf("error building case map for %q in module %q", prop.Name, modName)
|
||||
}
|
||||
}
|
||||
|
||||
// elementTypeToName returns the type name from an element type of the form
|
||||
// package:module:_type, with its leading "_" stripped.
|
||||
func elementTypeToName(el string) string {
|
||||
|
@ -96,13 +111,13 @@ func getListWithTypeName(t string) string {
|
|||
return "List[str]"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("List[%s]", PyName(t))
|
||||
return fmt.Sprintf("List[%s]", strings.Title(t))
|
||||
}
|
||||
|
||||
// getDictWithTypeName returns the Python representation of a dictionary
|
||||
// where each item is of type `t`.
|
||||
func getDictWithTypeName(t string) string {
|
||||
return fmt.Sprintf("Dict[%s]", PyName(t))
|
||||
return fmt.Sprintf("Dict[%s]", strings.Title(t))
|
||||
}
|
||||
|
||||
// getMapWithTypeName returns the Python representation of a dictionary
|
||||
|
@ -114,6 +129,6 @@ func getMapWithTypeName(t string) string {
|
|||
case "any":
|
||||
return "Dict[str, Any]"
|
||||
default:
|
||||
return fmt.Sprintf("Dict[str, %s]", PyName(t))
|
||||
return fmt.Sprintf("Dict[str, %s]", strings.Title(t))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue