diff --git a/pkg/codegen/docs/gen.go b/pkg/codegen/docs/gen.go
index 5ba0e805a..a57e3411d 100644
--- a/pkg/codegen/docs/gen.go
+++ b/pkg/codegen/docs/gen.go
@@ -26,7 +26,6 @@ import (
"fmt"
"html"
"html/template"
- "io"
"path"
"sort"
"strings"
@@ -148,7 +147,8 @@ type resourceDocArgs struct {
Header header
// Comment represents the introductory resource comment.
- Comment string
+ Comment string
+ DeprecationMessage string
ConstructorParams map[string]string
// ConstructorResource is the resource that is being constructed or
@@ -259,7 +259,7 @@ type propertyCharacteristics struct {
// getLanguageModuleName returns the module name mapped to its language-specific
// equivalent if the schema for this provider has any overrides for that language.
// Otherwise, returns the module name as-is.
-func getLanguageModuleName(lang string, mod string) string {
+func getLanguageModuleName(pkg *schema.Package, mod, lang string) string {
modName := mod
lookupKey := lang + "_" + modName
if v, ok := langModuleNameLookup[lookupKey]; ok {
@@ -281,11 +281,62 @@ func getLanguageModuleName(lang string, mod string) string {
return modName
}
+// cleanTypeString removes any namespaces from the generated type string for all languages.
+// The result of this function should be used display purposes only.
+func (mod *modContext) cleanTypeString(t schema.Type, langTypeString, lang, modName string, isInput bool) string {
+ if lang != "csharp" {
+ parts := strings.Split(langTypeString, ".")
+ return parts[len(parts)-1]
+ }
+
+ // C# types can be wrapped in enumerable types such as List<> or Dictionary<>, so we have to
+ // only replace the namespace between the < and the > characters.
+ qualifier := "Inputs"
+ if !isInput {
+ qualifier = "Outputs"
+ }
+
+ cleanCSharpName := func(pkgName, objModName string) string {
+ var csharpNS string
+ // This type could be at the package-level, so it won't have a module name.
+ if objModName != "" {
+ csharpNS = fmt.Sprintf("Pulumi.%s.%s.%s.", title(pkgName, lang), title(objModName, lang), qualifier)
+ } else {
+ csharpNS = fmt.Sprintf("Pulumi.%s.%s.", title(pkgName, lang), qualifier)
+ }
+ return strings.ReplaceAll(langTypeString, csharpNS, "")
+ }
+
+ if isKubernetesPackage(mod.pkg) {
+ switch t := t.(type) {
+ case *schema.ArrayType:
+ if schema.IsPrimitiveType(t.ElementType) {
+ break
+ }
+ objType := t.ElementType.(*schema.ObjectType)
+ return mod.cleanTypeString(objType, langTypeString, lang, modName, isInput)
+ case *schema.UnionType:
+ for _, e := range t.ElementTypes {
+ if schema.IsPrimitiveType(e) {
+ continue
+ }
+ return mod.cleanTypeString(e.(*schema.ObjectType), langTypeString, lang, modName, isInput)
+ }
+ case *schema.ObjectType:
+ objTypeModName := mod.pkg.TokenToModule(t.Token)
+ if objTypeModName != mod.mod {
+ modName = getLanguageModuleName(mod.pkg, objTypeModName, lang)
+ }
+ }
+ }
+ return cleanCSharpName(mod.pkg.Name, modName)
+}
+
// typeString returns a property type suitable for docs with its display name and the anchor link to
// a type if the type of the property is an array or an object.
func (mod *modContext) typeString(t schema.Type, lang string, characteristics propertyCharacteristics, insertWordBreaks bool) propertyType {
docLanguageHelper := getLanguageDocHelper(lang)
- modName := getLanguageModuleName(lang, mod.mod)
+ modName := getLanguageModuleName(mod.pkg, mod.mod, lang)
langTypeString := docLanguageHelper.GetLanguageTypeString(mod.pkg, modName, t, characteristics.input, characteristics.optional)
// If the type is an object type, let's also wrap it with a link to the supporting type
@@ -297,32 +348,14 @@ func (mod *modContext) typeString(t schema.Type, lang string, characteristics pr
href = elementLangType.Link
case *schema.ObjectType:
tokenName := tokenToName(t.Token)
- // Links to anchor targs on the same page must be lower-cased.
- href = "#" + lower(tokenName)
+ // Links to anchor tags on the same page must be lower-cased.
+ href = "#" + strings.ToLower(tokenName)
}
// Strip the namespace/module prefix for the type's display name.
- var parts []string
- var displayName string
- if lang == "csharp" {
- // C# types can be wrapped in enumerable types such as List<> or Dictionary<>, so we have to
- // only replace the namespace string within the < and the >.
- qualifier := "Inputs"
- if !characteristics.input {
- qualifier = "Outputs"
- }
-
- var csharpNS string
- // This type could be at the package-level, so it won't have a module name.
- if modName != "" {
- csharpNS = fmt.Sprintf("Pulumi.%s.%s.%s.", strings.Title(mod.pkg.Name), strings.Title(modName), qualifier)
- } else {
- csharpNS = fmt.Sprintf("Pulumi.%s.%s.", strings.Title(mod.pkg.Name), qualifier)
- }
- displayName = strings.ReplaceAll(langTypeString, csharpNS, "")
- } else {
- parts = strings.Split(langTypeString, ".")
- displayName = parts[len(parts)-1]
+ displayName := langTypeString
+ if !schema.IsPrimitiveType(t) {
+ displayName = mod.cleanTypeString(t, langTypeString, lang, modName, characteristics.input)
}
// If word-breaks need to be inserted, then the type string
@@ -485,70 +518,72 @@ func (mod *modContext) genNestedTypes(member interface{}, resourceType bool) []d
var objs []docNestedType
for token, tyUsage := range tokens {
for _, t := range mod.pkg.Types {
- if obj, ok := t.(*schema.ObjectType); ok && obj.Token == token {
- if len(obj.Properties) == 0 {
- continue
- }
-
- // Create maps to hold the per-language properties of this object and links to
- // the API doc for each language.
- props := make(map[string][]property)
- apiDocLinks := make(map[string]apiTypeDocLinks)
- for _, lang := range supportedLanguages {
- // The nested type may be under a different package in a language.
- // For example, in k8s, common types are in the core/v1 module and can appear in
- // nested types elsewhere. So we use the appropriate name of that type,
- // as well as its language-specific name. For example, module name for use as a C# namespace
- // or as a Go package name.
- modName := getLanguageModuleName(lang, mod.mod)
- nestedTypeModName := mod.pkg.TokenToModule(token)
- if nestedTypeModName != mod.mod {
- modName = getLanguageModuleName(lang, nestedTypeModName)
- }
-
- docLangHelper := getLanguageDocHelper(lang)
- inputCharacteristics := propertyCharacteristics{
- input: true,
- optional: true,
- }
- outputCharacteristics := propertyCharacteristics{
- input: false,
- optional: true,
- }
- inputObjLangType := mod.typeString(t, lang, inputCharacteristics, false /*insertWordBreaks*/)
- outputObjLangType := mod.typeString(t, lang, outputCharacteristics, false /*insertWordBreaks*/)
-
- // Get the doc link for this nested type based on whether the type is for a Function or a Resource.
- var inputTypeDocLink string
- var outputTypeDocLink string
- if resourceType {
- if tyUsage.Input {
- inputTypeDocLink = docLangHelper.GetDocLinkForResourceInputOrOutputType(mod.pkg.Name, modName, inputObjLangType.Name, true)
- }
- if tyUsage.Output {
- outputTypeDocLink = docLangHelper.GetDocLinkForResourceInputOrOutputType(mod.pkg.Name, modName, outputObjLangType.Name, false)
- }
- } else {
- if tyUsage.Input {
- inputTypeDocLink = docLangHelper.GetDocLinkForFunctionInputOrOutputType(mod.pkg.Name, modName, inputObjLangType.Name, true)
- }
- if tyUsage.Output {
- outputTypeDocLink = docLangHelper.GetDocLinkForFunctionInputOrOutputType(mod.pkg.Name, modName, outputObjLangType.Name, false)
- }
- }
- apiDocLinks[lang] = apiTypeDocLinks{
- InputType: inputTypeDocLink,
- OutputType: outputTypeDocLink,
- }
- props[lang] = mod.getProperties(obj.Properties, lang, true, true)
- }
-
- objs = append(objs, docNestedType{
- Name: wbr(tokenToName(obj.Token)),
- APIDocLinks: apiDocLinks,
- Properties: props,
- })
+ obj, ok := t.(*schema.ObjectType)
+ if !ok || obj.Token != token {
+ continue
}
+ if len(obj.Properties) == 0 {
+ continue
+ }
+
+ // Create maps to hold the per-language properties of this object and links to
+ // the API doc for each language.
+ props := make(map[string][]property)
+ apiDocLinks := make(map[string]apiTypeDocLinks)
+ for _, lang := range supportedLanguages {
+ // The nested type may be under a different package in a language.
+ // For example, in k8s, common types are in the core/v1 module and can appear in
+ // nested types elsewhere. So we use the appropriate name of that type,
+ // as well as its language-specific name. For example, module name for use as a C# namespace
+ // or as a Go package name.
+ modName := getLanguageModuleName(mod.pkg, mod.mod, lang)
+ nestedTypeModName := mod.pkg.TokenToModule(token)
+ if nestedTypeModName != mod.mod {
+ modName = getLanguageModuleName(mod.pkg, nestedTypeModName, lang)
+ }
+
+ docLangHelper := getLanguageDocHelper(lang)
+ inputCharacteristics := propertyCharacteristics{
+ input: true,
+ optional: true,
+ }
+ outputCharacteristics := propertyCharacteristics{
+ input: false,
+ optional: true,
+ }
+ inputObjLangType := mod.typeString(t, lang, inputCharacteristics, false /*insertWordBreaks*/)
+ outputObjLangType := mod.typeString(t, lang, outputCharacteristics, false /*insertWordBreaks*/)
+
+ // Get the doc link for this nested type based on whether the type is for a Function or a Resource.
+ var inputTypeDocLink string
+ var outputTypeDocLink string
+ if resourceType {
+ if tyUsage.Input {
+ inputTypeDocLink = docLangHelper.GetDocLinkForResourceInputOrOutputType(mod.pkg.Name, modName, inputObjLangType.Name, true)
+ }
+ if tyUsage.Output {
+ outputTypeDocLink = docLangHelper.GetDocLinkForResourceInputOrOutputType(mod.pkg.Name, modName, outputObjLangType.Name, false)
+ }
+ } else {
+ if tyUsage.Input {
+ inputTypeDocLink = docLangHelper.GetDocLinkForFunctionInputOrOutputType(mod.pkg.Name, modName, inputObjLangType.Name, true)
+ }
+ if tyUsage.Output {
+ outputTypeDocLink = docLangHelper.GetDocLinkForFunctionInputOrOutputType(mod.pkg.Name, modName, outputObjLangType.Name, false)
+ }
+ }
+ apiDocLinks[lang] = apiTypeDocLinks{
+ InputType: inputTypeDocLink,
+ OutputType: outputTypeDocLink,
+ }
+ props[lang] = mod.getProperties(obj.Properties, lang, true, true)
+ }
+
+ objs = append(objs, docNestedType{
+ Name: wbr(tokenToName(obj.Token)),
+ APIDocLinks: apiDocLinks,
+ Properties: props,
+ })
}
}
@@ -565,12 +600,17 @@ func (mod *modContext) getProperties(properties []*schema.Property, lang string,
if len(properties) == 0 {
return nil
}
-
+ isK8s := isKubernetesPackage(mod.pkg)
docProperties := make([]property, 0, len(properties))
for _, prop := range properties {
if prop == nil {
continue
}
+ // In k8s, apiVersion and kind are hard-coded in the SDK and not really
+ // user-provided input properties, so skip them.
+ if isK8s && (prop.Name == "apiVersion" || prop.Name == "kind") {
+ continue
+ }
characteristics := propertyCharacteristics{
input: input,
@@ -646,7 +686,13 @@ func (mod *modContext) genConstructors(r *schema.Resource, allOptionalInputs boo
// The input properties for a resource needs to be exploded as
// individual constructor params.
params = make([]formalParam, 0, len(r.InputProperties))
+ isK8s := isKubernetesPackage(mod.pkg)
for _, p := range r.InputProperties {
+ // In k8s, apiVersion and kind are hard-coded in the SDK and not really
+ // user-provided input properties, so skip them.
+ if isK8s && (p.Name == "apiVersion" || p.Name == "kind") {
+ continue
+ }
params = append(params, formalParam{
Name: python.PyName(p.Name),
DefaultValue: "=None",
@@ -685,7 +731,7 @@ func (mod *modContext) getConstructorResourceInfo(resourceTypeName string) map[s
case "nodejs", "go":
// Intentionally left blank.
case "csharp":
- resourceTypeName = fmt.Sprintf("Pulumi.%s.%s.%s", strings.Title(mod.pkg.Name), strings.Title(mod.mod), resourceTypeName)
+ resourceTypeName = fmt.Sprintf("Pulumi.%s.%s.%s", title(mod.pkg.Name, "csharp"), title(mod.mod, "csharp"), resourceTypeName)
case "python":
// Pulumi's Python language SDK does not have "types" yet, so we will skip it for now.
continue
@@ -787,7 +833,7 @@ func (mod *modContext) getGoLookupParams(r *schema.Resource, stateParam string)
}
func (mod *modContext) getCSLookupParams(r *schema.Resource, stateParam string) []formalParam {
- stateParamFQDN := fmt.Sprintf("Pulumi.%s.%s.%s", strings.Title(mod.pkg.Name), strings.Title(mod.mod), stateParam)
+ stateParamFQDN := fmt.Sprintf("Pulumi.%s.%s.%s", title(mod.pkg.Name, "csharp"), title(mod.mod, "csharp"), stateParam)
docLangHelper := getLanguageDocHelper("csharp")
return []formalParam{
@@ -924,7 +970,8 @@ func (mod *modContext) genResource(r *schema.Resource) resourceDocArgs {
Title: name,
},
- Comment: r.Comment,
+ Comment: r.Comment,
+ DeprecationMessage: r.DeprecationMessage,
ConstructorParams: mod.genConstructors(r, allOptionalInputs),
ConstructorResource: mod.getConstructorResourceInfo(name),
@@ -1016,34 +1063,6 @@ func (mod *modContext) getTypes(member interface{}, types nestedTypeUsageInfo) {
}
}
-func (mod *modContext) genHeader(w io.Writer, title string, menu bool) {
- // TODO: Generate the actual front matter we want for these pages.
- // Example:
- // title: "Package @pulumi/aws"
- // title_tag: "Package @pulumi/aws | Node.js SDK"
- // linktitle: "@pulumi/aws"
- // meta_desc: "Explore members of the @pulumi/aws package."
- // menu:
- // reference:
- // parent: API Reference
- // identifier: Server
-
- fmt.Fprintf(w, "---\n")
- fmt.Fprintf(w, "title: %q\n", title)
- fmt.Fprintf(w, "block_external_search_index: true\n")
-
- // Only add the menu section for pages that should be in the TOC.
- if menu {
- fmt.Fprintf(w, "menu:\n")
- fmt.Fprintf(w, " reference:\n")
- fmt.Fprintf(w, " parent: API Reference\n")
- }
-
- fmt.Fprintf(w, "---\n\n")
- fmt.Fprintf(w, "\n", mod.tool)
- fmt.Fprintf(w, "\n\n")
-}
-
type fs map[string][]byte
func (fs fs) add(path string, contents []byte) {
@@ -1052,20 +1071,32 @@ func (fs fs) add(path string, contents []byte) {
fs[path] = contents
}
+func (mod *modContext) getModuleFileName() string {
+ if !isKubernetesPackage(mod.pkg) {
+ return mod.mod
+ }
+
+ if override, ok := goPkgInfo.ModuleToPackage[mod.mod]; ok {
+ return override
+ }
+ return mod.mod
+}
+
func (mod *modContext) gen(fs fs) error {
+ modName := mod.getModuleFileName()
var files []string
for p := range fs {
d := path.Dir(p)
if d == "." {
d = ""
}
- if d == mod.mod {
+ if d == modName {
files = append(files, p)
}
}
addFile := func(name, contents string) {
- p := path.Join(mod.mod, name)
+ p := path.Join(modName, name)
files = append(files, p)
fs.add(p, []byte(contents))
}
@@ -1078,9 +1109,10 @@ func (mod *modContext) gen(fs fs) error {
buffer := &bytes.Buffer{}
err := templates.ExecuteTemplate(buffer, "resource.tmpl", data)
if err != nil {
- panic(err)
+ return err
}
- addFile(lower(title)+".md", buffer.String())
+
+ addFile(strings.ToLower(title)+".md", buffer.String())
}
// Functions
@@ -1090,100 +1122,152 @@ func (mod *modContext) gen(fs fs) error {
buffer := &bytes.Buffer{}
err := templates.ExecuteTemplate(buffer, "function.tmpl", data)
if err != nil {
- panic(err)
+ return err
}
- addFile(lower(tokenToName(f.Token))+".md", buffer.String())
+
+ addFile(strings.ToLower(tokenToName(f.Token))+".md", buffer.String())
}
- // Index
- fs.add(path.Join(mod.mod, "_index.md"), []byte(mod.genIndex(files)))
+ // Generate the index files.
+ idxData := mod.genIndex()
+ buffer := &bytes.Buffer{}
+ err := templates.ExecuteTemplate(buffer, "index.tmpl", idxData)
+ if err != nil {
+ return err
+ }
+
+ fs.add(path.Join(modName, "_index.md"), []byte(buffer.String()))
return nil
}
+// indexEntry represents an individual entry on an index page.
+type indexEntry struct {
+ Link string
+ DisplayName string
+}
+
+// indexData represents the index file data to be rendered as _index.md.
+type indexData struct {
+ Tool string
+
+ Title string
+ PackageDescription string
+ // Menu indicates if an index page should be part of the TOC menu.
+ Menu bool
+
+ Functions []indexEntry
+ Resources []indexEntry
+ Modules []indexEntry
+ PackageDetails packageDetails
+}
+
+// indexEntrySorter implements the sort.Interface for sorting
+// a slice of indexEntry struct types.
+type indexEntrySorter struct {
+ entries []indexEntry
+}
+
+// Len is part of sort.Interface. Returns the length of the
+// entries slice.
+func (s *indexEntrySorter) Len() int {
+ return len(s.entries)
+}
+
+// Swap is part of sort.Interface.
+func (s *indexEntrySorter) Swap(i, j int) {
+ s.entries[i], s.entries[j] = s.entries[j], s.entries[i]
+}
+
+// Less is part of sort.Interface. It sorts the entries by their
+// display name in an ascending order.
+func (s *indexEntrySorter) Less(i, j int) bool {
+ return s.entries[i].DisplayName < s.entries[j].DisplayName
+}
+
+func sortIndexEntries(entries []indexEntry) {
+ if len(entries) == 0 {
+ return
+ }
+
+ sorter := &indexEntrySorter{
+ entries: entries,
+ }
+
+ sort.Sort(sorter)
+}
+
// genIndex emits an _index.md file for the module.
-func (mod *modContext) genIndex(exports []string) string {
- w := &bytes.Buffer{}
+func (mod *modContext) genIndex() indexData {
+ glog.V(4).Infoln("genIndex for", mod.mod)
+ modules := make([]indexEntry, 0, len(mod.children))
+ resources := make([]indexEntry, 0, len(mod.resources))
+ functions := make([]indexEntry, 0, len(mod.functions))
- name := mod.mod
+ modName := mod.getModuleFileName()
+ title := modName
menu := false
- if name == "" {
- name = mod.pkg.Name
-
+ if title == "" {
+ title = mod.pkg.Name
// Flag top-level entries for inclusion in the table-of-contents menu.
menu = true
}
- mod.genHeader(w, name, menu)
+ // If there are submodules, list them.
+ for _, mod := range mod.children {
+ modName := mod.getModuleFileName()
+ parts := strings.Split(modName, "/")
+ modName = parts[len(parts)-1]
+ modules = append(modules, indexEntry{
+ Link: modName + "/",
+ DisplayName: modName,
+ })
+ }
+ sortIndexEntries(modules)
+
+ // If there are resources in the root, list them.
+ for _, r := range mod.resources {
+ name := resourceName(r)
+ resources = append(resources, indexEntry{
+ Link: strings.ToLower(name),
+ DisplayName: name,
+ })
+ }
+ sortIndexEntries(resources)
+
+ // If there are functions in the root, list them.
+ for _, f := range mod.functions {
+ name := tokenToName(f.Token)
+ functions = append(functions, indexEntry{
+ Link: strings.ToLower(name),
+ DisplayName: name,
+ })
+ }
+ sortIndexEntries(functions)
+
+ packageDetails := packageDetails{
+ Repository: mod.pkg.Repository,
+ License: mod.pkg.License,
+ Notes: mod.pkg.Attribution,
+ }
+
+ data := indexData{
+ Tool: mod.tool,
+
+ Title: title,
+ Menu: menu,
+
+ Resources: resources,
+ Functions: functions,
+ Modules: modules,
+ PackageDetails: packageDetails,
+ }
// If this is the root module, write out the package description.
if mod.mod == "" {
- description := mod.pkg.Description
- if description != "" {
- description += "\n\n"
- }
- fmt.Fprint(w, description)
+ data.PackageDescription = mod.pkg.Description
}
- // If there are submodules, list them.
- var children []string
- for _, mod := range mod.children {
- children = append(children, mod.mod)
- }
- if len(children) > 0 {
- sort.Strings(children)
- fmt.Fprintf(w, "
Modules
\n")
- fmt.Fprintf(w, "\n")
- for _, mod := range children {
- fmt.Fprintf(w, " - %s
\n", mod, mod)
- }
- fmt.Fprintf(w, "
\n\n")
- }
-
- // If there are resources in the root, list them.
- var resources []string
- for _, r := range mod.resources {
- resources = append(resources, resourceName(r))
- }
- if len(resources) > 0 {
- sort.Strings(resources)
- fmt.Fprintf(w, "Resources
\n")
- fmt.Fprintf(w, "\n")
- for _, r := range resources {
- fmt.Fprintf(w, " - %s
\n", lower(r), r)
- }
- fmt.Fprintf(w, "
\n\n")
- }
-
- // If there are functions in the root, list them.
- var functions []string
- for _, f := range mod.functions {
- functions = append(functions, tokenToName(f.Token))
- }
- if len(functions) > 0 {
- sort.Strings(functions)
- fmt.Fprintf(w, "Functions
\n")
- fmt.Fprintf(w, "\n")
- for _, f := range functions {
- // TODO: We want to use "function" rather than "data source" terminology. Need to add a
- // "function" class in the docs repo to replace "datasource".
- fmt.Fprintf(w, " - %s
\n", lower(f), f)
- }
- fmt.Fprintf(w, "
\n\n")
- }
-
- fmt.Fprintf(w, "Package Details
\n")
- fmt.Fprintf(w, "\n")
- fmt.Fprintf(w, " - Repository
\n")
- fmt.Fprintf(w, " - %s
\n", mod.pkg.Repository)
- fmt.Fprintf(w, " - License
\n")
- fmt.Fprintf(w, " - %s
\n", mod.pkg.License)
- if mod.pkg.Attribution != "" {
- fmt.Fprintf(w, " - Notes
\n")
- fmt.Fprintf(w, " - %s
\n", mod.pkg.Attribution)
- }
- fmt.Fprintf(w, "
\n\n")
-
- return w.String()
+ return data
}
func decodeLangSpecificInfo(pkg *schema.Package, lang string, obj interface{}) error {
@@ -1195,35 +1279,35 @@ func decodeLangSpecificInfo(pkg *schema.Package, lang string, obj interface{}) e
return nil
}
+func getMod(pkg *schema.Package, token string, modules map[string]*modContext, tool string) *modContext {
+ modName := pkg.TokenToModule(token)
+ mod, ok := modules[modName]
+ if !ok {
+ mod = &modContext{
+ pkg: pkg,
+ mod: modName,
+ tool: tool,
+ }
+
+ if modName != "" {
+ parentName := path.Dir(modName)
+ // If the parent name is blank, it means this is the package-level.
+ if parentName == "." || parentName == "" {
+ parentName = ":index:"
+ }
+ parent := getMod(pkg, parentName, modules, tool)
+ parent.children = append(parent.children, mod)
+ }
+
+ modules[modName] = mod
+ }
+ return mod
+}
+
func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[string]*modContext {
// Group resources, types, and functions into modules.
modules := map[string]*modContext{}
- var getMod func(token string) *modContext
- getMod = func(token string) *modContext {
- modName := pkg.TokenToModule(token)
- mod, ok := modules[modName]
- if !ok {
- mod = &modContext{
- pkg: pkg,
- mod: modName,
- tool: tool,
- }
-
- if modName != "" {
- parentName := path.Dir(modName)
- if parentName == "." || parentName == "" {
- parentName = ":index:"
- }
- parent := getMod(parentName)
- parent.children = append(parent.children, mod)
- }
-
- modules[modName] = mod
- }
- return mod
- }
-
// Decode Go-specific language info.
if err := decodeLangSpecificInfo(pkg, "go", &goPkgInfo); err != nil {
panic(errors.Wrap(err, "error decoding go language info"))
@@ -1242,7 +1326,7 @@ func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[stri
pyLangHelper := getLanguageDocHelper("python").(*python.DocLanguageHelper)
scanResource := func(r *schema.Resource) {
- mod := getMod(r.Token)
+ mod := getMod(pkg, r.Token, modules, tool)
mod.resources = append(mod.resources, r)
for _, p := range r.Properties {
@@ -1255,7 +1339,7 @@ func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[stri
}
scanK8SResource := func(r *schema.Resource) {
- mod := getMod(r.Token)
+ mod := getK8SMod(pkg, r.Token, modules, tool)
mod.resources = append(mod.resources, r)
// For k8s, all nested properties will use a snake_case,
@@ -1277,7 +1361,7 @@ func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[stri
}
glog.V(3).Infoln("scanning resources")
- if pkg.Name == "kubernetes" {
+ if isKubernetesPackage(pkg) {
scanK8SResource(pkg.Provider)
for _, r := range pkg.Resources {
scanK8SResource(r)
@@ -1291,7 +1375,7 @@ func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[stri
glog.V(3).Infoln("done scanning resources")
for _, f := range pkg.Functions {
- mod := getMod(f.Token)
+ mod := getMod(pkg, f.Token, modules, tool)
mod.functions = append(mod.functions, f)
}
return modules
diff --git a/pkg/codegen/docs/gen_function.go b/pkg/codegen/docs/gen_function.go
index 942fdc300..32872a6ba 100644
--- a/pkg/codegen/docs/gen_function.go
+++ b/pkg/codegen/docs/gen_function.go
@@ -1,5 +1,3 @@
-//go:generate go run bundler.go
-
// Copyright 2016-2020, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/pkg/codegen/docs/gen_kubernetes.go b/pkg/codegen/docs/gen_kubernetes.go
new file mode 100644
index 000000000..a0f782537
--- /dev/null
+++ b/pkg/codegen/docs/gen_kubernetes.go
@@ -0,0 +1,70 @@
+//go:generate go run bundler.go
+
+// Copyright 2016-2020, 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.
+//
+// nolint: lll, goconst
+package docs
+
+import (
+ "path"
+ "strings"
+
+ "github.com/pulumi/pulumi/pkg/codegen/schema"
+)
+
+func isKubernetesPackage(pkg *schema.Package) bool {
+ return pkg.Name == "kubernetes"
+}
+
+func getK8SMod(pkg *schema.Package, token string, modules map[string]*modContext, tool string) *modContext {
+ modName := pkg.TokenToModule(token)
+ // Kubernetes' moduleFormat in the schema will match everything
+ // in the token. This prevents us from adding the "Provider"
+ // resource as a child module of the package level :index: module.
+ if modName == "providers" {
+ modName = ""
+ } else {
+ modName = strings.TrimSuffix(modName, ".k8s.io")
+ modName = strings.TrimSuffix(modName, ".apiserver")
+ modName = strings.TrimSuffix(modName, ".authorization")
+ }
+
+ mod, ok := modules[modName]
+ if !ok {
+ mod = &modContext{
+ pkg: pkg,
+ mod: modName,
+ tool: tool,
+ }
+
+ if modName != "" {
+ parentName := path.Dir(modName)
+ // If the parent name is blank, it means this is the package-level.
+ if parentName == "." || parentName == "" {
+ parentName = ":index:"
+ } else {
+ parentName = ":" + parentName + ":"
+ }
+ parent := getK8SMod(pkg, parentName, modules, tool)
+ parent.children = append(parent.children, mod)
+ }
+
+ modules[modName] = mod
+ }
+ return mod
+}
diff --git a/pkg/codegen/docs/templates/header.tmpl b/pkg/codegen/docs/templates/header.tmpl
index 47cd87e84..abe105dbf 100644
--- a/pkg/codegen/docs/templates/header.tmpl
+++ b/pkg/codegen/docs/templates/header.tmpl
@@ -4,4 +4,4 @@ title: "{{ .Title }}"
block_external_search_index: true
---
-{{- end }}
+{{ end }}
diff --git a/pkg/codegen/docs/templates/index.tmpl b/pkg/codegen/docs/templates/index.tmpl
new file mode 100644
index 000000000..e5302a29a
--- /dev/null
+++ b/pkg/codegen/docs/templates/index.tmpl
@@ -0,0 +1,28 @@
+---
+title: "{{ .Title }}"
+block_external_search_index: true
+{{- if .Menu }}
+menu:
+ reference:
+ parent: API Reference
+{{- end }}
+---
+
+{{ htmlSafe "" }}
+{{ htmlSafe "" }}
+
+{{ htmlSafe .PackageDescription }}
+
+{{- if ne (len .Modules) 0 -}}
+{{ template "index_modules" .Modules }}
+{{ end }}
+
+{{- if ne (len .Resources) 0 -}}
+{{ template "index_resources" .Resources }}
+{{ end }}
+
+{{- if ne (len .Functions) 0 -}}
+{{ template "index_functions" .Functions }}
+{{ end }}
+
+{{- template "package_details" .PackageDetails }}
diff --git a/pkg/codegen/docs/templates/index_categories.tmpl b/pkg/codegen/docs/templates/index_categories.tmpl
new file mode 100644
index 000000000..aef0c8d0e
--- /dev/null
+++ b/pkg/codegen/docs/templates/index_categories.tmpl
@@ -0,0 +1,26 @@
+{{- define "index_modules" }}
+Modules
+
+{{- end }}
+
+{{- define "index_resources" }}
+Resources
+
+{{- end }}
+
+{{- define "index_functions" }}
+Functions
+
+{{- end }}
\ No newline at end of file
diff --git a/pkg/codegen/docs/templates/package_details.tmpl b/pkg/codegen/docs/templates/package_details.tmpl
new file mode 100644
index 000000000..4bf38e245
--- /dev/null
+++ b/pkg/codegen/docs/templates/package_details.tmpl
@@ -0,0 +1,13 @@
+{{ define "package_details" }}
+Package Details
+
+ - Repository
+ - {{ htmlSafe .Repository }}
+ - License
+ - {{ htmlSafe .License }}
+ {{ if ne .Notes "" -}}
+ - Notes
+ - {{ htmlSafe .Notes }}
+ {{- end }}
+
+{{ end }}
\ No newline at end of file
diff --git a/pkg/codegen/docs/templates/resource.tmpl b/pkg/codegen/docs/templates/resource.tmpl
index bfcd7d905..1686272be 100644
--- a/pkg/codegen/docs/templates/resource.tmpl
+++ b/pkg/codegen/docs/templates/resource.tmpl
@@ -1,5 +1,7 @@
{{ template "header" .Header }}
+{{- htmlSafe .DeprecationMessage }}
+
{{ htmlSafe .Comment }}
@@ -138,14 +140,4 @@ The following state arguments are supported:
{{ end }}
-Package Details
-
- - Repository
- - {{ htmlSafe .PackageDetails.Repository }}
- - License
- - {{ htmlSafe .PackageDetails.License }}
- {{- if ne .PackageDetails.Notes "" -}}
- - Notes
- - {{ htmlSafe .PackageDetails.Notes }}
- {{- end -}}
-
+{{ template "package_details" .PackageDetails }}
diff --git a/pkg/codegen/docs/utils.go b/pkg/codegen/docs/utils.go
index 0ec8a7f58..85938ec2e 100644
--- a/pkg/codegen/docs/utils.go
+++ b/pkg/codegen/docs/utils.go
@@ -22,6 +22,8 @@ import (
"strings"
"unicode"
+ "github.com/pulumi/pulumi/pkg/codegen/dotnet"
+ go_gen "github.com/pulumi/pulumi/pkg/codegen/go"
"github.com/pulumi/pulumi/sdk/go/common/util/contract"
)
@@ -53,13 +55,20 @@ func wbr(s string) string {
return string(runes)
}
-func lower(s string) string {
- return strings.ToLower(s)
-}
-
// tokenToName returns the resource name from a Pulumi token.
func tokenToName(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "malformed token %v", tok)
return strings.Title(components[2])
}
+
+func title(s, lang string) string {
+ switch lang {
+ case "go":
+ return go_gen.Title(s)
+ case "csharp":
+ return dotnet.Title(s)
+ default:
+ return strings.Title(s)
+ }
+}
diff --git a/pkg/codegen/dotnet/doc.go b/pkg/codegen/dotnet/doc.go
index 923d2bba7..924b3e2e5 100644
--- a/pkg/codegen/dotnet/doc.go
+++ b/pkg/codegen/dotnet/doc.go
@@ -38,7 +38,7 @@ func (d DocLanguageHelper) GetDocLinkForResourceType(packageName, _, typeName st
typeName = strings.ReplaceAll(typeName, "?", "")
var packageNamespace string
if packageName != "" {
- packageNamespace = "." + title(packageName)
+ packageNamespace = "." + Title(packageName)
}
return fmt.Sprintf("/docs/reference/pkg/dotnet/Pulumi%s/%s.html", packageNamespace, typeName)
}
diff --git a/pkg/codegen/dotnet/gen.go b/pkg/codegen/dotnet/gen.go
index 78f34f8a9..8558607d1 100644
--- a/pkg/codegen/dotnet/gen.go
+++ b/pkg/codegen/dotnet/gen.go
@@ -56,7 +56,9 @@ type typeDetails struct {
functionType bool
}
-func title(s string) string {
+// Title converts the input string to a title case
+// where only the initial letter is upper-cased.
+func Title(s string) string {
if s == "" {
return ""
}
@@ -105,7 +107,7 @@ func namespaceName(namespaces map[string]string, name string) string {
if ns, ok := namespaces[name]; ok {
return ns
}
- return title(name)
+ return Title(name)
}
type modContext struct {
@@ -126,7 +128,7 @@ func (mod *modContext) propertyName(p *schema.Property) string {
if n, ok := mod.propertyNames[p]; ok {
return n
}
- return title(p.Name)
+ return Title(p.Name)
}
func (mod *modContext) details(t *schema.ObjectType) *typeDetails {
@@ -144,7 +146,7 @@ func tokenToName(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "malformed token %v", tok)
- return title(components[2])
+ return Title(components[2])
}
func resourceName(r *schema.Resource) string {
@@ -158,7 +160,7 @@ func (mod *modContext) tokenToNamespace(tok string) string {
components := strings.Split(tok, ":")
contract.Assertf(len(components) == 3, "malformed token %v", tok)
- pkg, nsName := "Pulumi."+title(components[0]), mod.pkg.TokenToModule(tok)
+ pkg, nsName := "Pulumi."+Title(components[0]), mod.pkg.TokenToModule(tok)
if nsName == "" {
return pkg
}
diff --git a/pkg/codegen/go/doc.go b/pkg/codegen/go/doc.go
index 63e11deb5..e313abdfa 100644
--- a/pkg/codegen/go/doc.go
+++ b/pkg/codegen/go/doc.go
@@ -78,6 +78,9 @@ func GetDocLinkForBuiltInType(typeName string) string {
// GetLanguageTypeString returns the Go-specific type given a Pulumi schema type.
func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName string, t schema.Type, input, optional bool) string {
+ if moduleName == "" && pkg.Name == "kubernetes" {
+ moduleName = "providers"
+ }
modPkg, ok := d.packages[moduleName]
if !ok {
glog.Errorf("cannot calculate type string for type %q. could not find a package for module %q", t.String(), moduleName)
diff --git a/pkg/codegen/go/gen.go b/pkg/codegen/go/gen.go
index 4dfd3dc05..84cdebade 100644
--- a/pkg/codegen/go/gen.go
+++ b/pkg/codegen/go/gen.go
@@ -63,7 +63,9 @@ type typeDetails struct {
mapElement bool
}
-func title(s string) string {
+// Title converts the input string to a title case
+// where only the initial letter is upper-cased.
+func Title(s string) string {
if s == "" {
return ""
}
@@ -136,7 +138,7 @@ func (pkg *pkgContext) tokenToType(tok string) string {
// 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)
+ name = Title(name)
if modPkg.names.has(name) {
name += "Type"
}
@@ -150,7 +152,7 @@ func (pkg *pkgContext) tokenToType(tok string) string {
func tokenToName(tok string) string {
components := strings.Split(tok, ":")
contract.Assert(len(components) == 3)
- return title(components[2])
+ return Title(components[2])
}
func resourceName(r *schema.Resource) string {
@@ -320,8 +322,8 @@ func genInputInterface(w io.Writer, name string) {
printComment(w, 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, "\tTo%sOutput() %sOutput\n", Title(name), name)
+ fmt.Fprintf(w, "\tTo%sOutputWithContext(context.Context) %sOutput\n", Title(name), name)
fmt.Fprintf(w, "}\n\n")
}
@@ -378,20 +380,20 @@ func genInputMethods(w io.Writer, name, receiverType, elementType string, ptrMet
fmt.Fprintf(w, "\treturn reflect.TypeOf((*%s)(nil)).Elem()\n", elementType)
fmt.Fprintf(w, "}\n\n")
- 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, "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, "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")
if ptrMethods {
- 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, "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)
+ fmt.Fprintf(w, "func (i %s) To%sPtrOutputWithContext(ctx context.Context) %sPtrOutput {\n", receiverType, Title(name), name)
fmt.Fprintf(w, "\treturn pulumi.ToOutputWithContext(ctx, i).(%[1]sOutput).To%[1]sPtrOutputWithContext(ctx)\n", name)
fmt.Fprintf(w, "}\n\n")
}
@@ -402,7 +404,7 @@ func (pkg *pkgContext) genPlainType(w io.Writer, name, comment string, propertie
fmt.Fprintf(w, "type %s struct {\n", name)
for _, p := range properties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", title(p.Name), pkg.plainType(p.Type, !p.IsRequired), p.Name)
+ fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.plainType(p.Type, !p.IsRequired), p.Name)
}
fmt.Fprintf(w, "}\n\n")
}
@@ -417,7 +419,7 @@ func (pkg *pkgContext) genInputTypes(w io.Writer, t *schema.ObjectType, details
fmt.Fprintf(w, "type %sArgs struct {\n", name)
for _, p := range t.Properties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", title(p.Name), pkg.inputType(p.Type, !p.IsRequired), p.Name)
+ fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.inputType(p.Type, !p.IsRequired), p.Name)
}
fmt.Fprintf(w, "}\n\n")
@@ -462,11 +464,11 @@ func genOutputMethods(w io.Writer, name, elementType string) {
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", name, title(name))
+ fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutput() %[1]sOutput {\n", name, Title(name))
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", name, title(name))
+ fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sOutputWithContext(ctx context.Context) %[1]sOutput {\n", name, Title(name))
fmt.Fprintf(w, "\treturn o\n")
fmt.Fprintf(w, "}\n\n")
}
@@ -480,11 +482,11 @@ func (pkg *pkgContext) genOutputTypes(w io.Writer, t *schema.ObjectType, details
genOutputMethods(w, name, name)
if details.ptrElement {
- fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutput() %[1]sPtrOutput {\n", name, title(name))
- fmt.Fprintf(w, "\treturn o.To%sPtrOutputWithContext(context.Background())\n", title(name))
+ fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutput() %[1]sPtrOutput {\n", name, Title(name))
+ fmt.Fprintf(w, "\treturn o.To%sPtrOutputWithContext(context.Background())\n", Title(name))
fmt.Fprintf(w, "}\n\n")
- fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutputWithContext(ctx context.Context) %[1]sPtrOutput {\n", name, title(name))
+ fmt.Fprintf(w, "func (o %[1]sOutput) To%[2]sPtrOutputWithContext(ctx context.Context) %[1]sPtrOutput {\n", name, Title(name))
fmt.Fprintf(w, "\treturn o.ApplyT(func(v %[1]s) *%[1]s {\n", name)
fmt.Fprintf(w, "\t\treturn &v\n")
fmt.Fprintf(w, "\t}).(%sPtrOutput)\n", name)
@@ -495,8 +497,8 @@ func (pkg *pkgContext) genOutputTypes(w io.Writer, t *schema.ObjectType, details
printComment(w, p.Comment, false)
outputType, applyType := pkg.outputType(p.Type, !p.IsRequired), pkg.plainType(p.Type, !p.IsRequired)
- fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, title(p.Name), outputType)
- fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n", name, applyType, title(p.Name), outputType)
+ fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, Title(p.Name), outputType)
+ fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n", name, applyType, Title(p.Name), outputType)
fmt.Fprintf(w, "}\n\n")
}
@@ -513,8 +515,8 @@ func (pkg *pkgContext) genOutputTypes(w io.Writer, t *schema.ObjectType, details
printComment(w, p.Comment, false)
outputType, applyType := pkg.outputType(p.Type, !p.IsRequired), pkg.plainType(p.Type, !p.IsRequired)
- fmt.Fprintf(w, "func (o %sPtrOutput) %s() %s {\n", name, title(p.Name), outputType)
- fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n", name, applyType, title(p.Name), outputType)
+ fmt.Fprintf(w, "func (o %sPtrOutput) %s() %s {\n", name, Title(p.Name), outputType)
+ fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n", name, applyType, Title(p.Name), outputType)
fmt.Fprintf(w, "}\n\n")
}
}
@@ -619,7 +621,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
}
for _, p := range r.Properties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", title(p.Name), pkg.outputType(p.Type, !p.IsRequired), p.Name)
+ fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.outputType(p.Type, !p.IsRequired), p.Name)
}
fmt.Fprintf(w, "}\n\n")
@@ -631,8 +633,8 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
// Ensure required arguments are present.
for _, p := range r.InputProperties {
if p.IsRequired {
- fmt.Fprintf(w, "\tif args == nil || args.%s == nil {\n", title(p.Name))
- fmt.Fprintf(w, "\t\treturn nil, errors.New(\"missing required argument '%s'\")\n", title(p.Name))
+ fmt.Fprintf(w, "\tif args == nil || args.%s == nil {\n", Title(p.Name))
+ fmt.Fprintf(w, "\t\treturn nil, errors.New(\"missing required argument '%s'\")\n", Title(p.Name))
fmt.Fprintf(w, "\t}\n")
}
}
@@ -653,8 +655,8 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
t = "pulumi.Any"
}
- fmt.Fprintf(w, "\tif args.%s == nil {\n", title(p.Name))
- fmt.Fprintf(w, "\t\targs.%s = %s(%s)\n", title(p.Name), t, v)
+ fmt.Fprintf(w, "\tif args.%s == nil {\n", Title(p.Name))
+ fmt.Fprintf(w, "\t\targs.%s = %s(%s)\n", Title(p.Name), t, v)
fmt.Fprintf(w, "\t}\n")
}
}
@@ -708,14 +710,14 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
fmt.Fprintf(w, "type %sState struct {\n", camel(name))
for _, p := range r.Properties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", title(p.Name), pkg.plainType(p.Type, true), p.Name)
+ fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.plainType(p.Type, true), p.Name)
}
fmt.Fprintf(w, "}\n\n")
fmt.Fprintf(w, "type %sState struct {\n", name)
for _, p := range r.Properties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s\n", title(p.Name), pkg.inputType(p.Type, true))
+ fmt.Fprintf(w, "\t%s %s\n", Title(p.Name), pkg.inputType(p.Type, true))
}
fmt.Fprintf(w, "}\n\n")
@@ -728,7 +730,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
fmt.Fprintf(w, "type %sArgs struct {\n", camel(name))
for _, p := range r.InputProperties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", title(p.Name), pkg.plainType(p.Type, !p.IsRequired), p.Name)
+ fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.plainType(p.Type, !p.IsRequired), p.Name)
}
fmt.Fprintf(w, "}\n\n")
@@ -736,7 +738,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
fmt.Fprintf(w, "type %sArgs struct {\n", name)
for _, p := range r.InputProperties {
printComment(w, p.Comment, true)
- fmt.Fprintf(w, "\t%s %s\n", title(p.Name), pkg.inputType(p.Type, !p.IsRequired))
+ fmt.Fprintf(w, "\t%s %s\n", Title(p.Name), pkg.inputType(p.Type, !p.IsRequired))
}
fmt.Fprintf(w, "}\n\n")
@@ -973,7 +975,7 @@ func (pkg *pkgContext) genConfig(w io.Writer, variables []*schema.Property) erro
printComment(w, p.Comment, false)
configKey := fmt.Sprintf("\"%s:%s\"", pkg.pkg.Name, camel(p.Name))
- fmt.Fprintf(w, "func Get%s(ctx *pulumi.Context) %s {\n", title(p.Name), getType)
+ fmt.Fprintf(w, "func Get%s(ctx *pulumi.Context) %s {\n", Title(p.Name), getType)
if p.DefaultValue != nil {
defaultValue, err := pkg.getDefaultValue(p.DefaultValue, p.Type)
if err != nil {