Skip to content

Commit 0155477

Browse files
Add automated install instructions using go base import path and package name.
Refactor functionality into new file. Add unit tests.
1 parent 11e23df commit 0155477

File tree

4 files changed

+229
-84
lines changed

4 files changed

+229
-84
lines changed

pkg/tfgen/docs.go

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,47 +2272,3 @@ var (
22722272
func guessIsHCL(code string) bool {
22732273
return guessIsHCLPattern.MatchString(code)
22742274
}
2275-
2276-
func plainDocsParser(docFile *DocFile, g *Generator) ([]byte, error) {
2277-
// Get file content without front matter, and split title
2278-
contentStr, title := getBodyAndTitle(string(docFile.Content))
2279-
// Add pulumi-specific front matter
2280-
contentStr = writeFrontMatter(title) + contentStr
2281-
2282-
//TODO: See https://github.com/pulumi/pulumi-terraform-bridge/issues/2078
2283-
// - translate code blocks with code choosers
2284-
// - apply default edit rules
2285-
// - reformat TF names
2286-
// - Translation for certain headers such as "Arguments Reference" or "Configuration block"
2287-
// - Ability to omit irrelevant sections
2288-
return []byte(contentStr), nil
2289-
}
2290-
2291-
func writeFrontMatter(title string) string {
2292-
return fmt.Sprintf(delimiter+
2293-
"title: %s Installation & Configuration\n"+
2294-
"meta_desc: Provides an overview on how to configure the Pulumi %s.\n"+
2295-
"layout: package\n"+
2296-
delimiter,
2297-
title, title)
2298-
}
2299-
2300-
func writeIndexFrontMatter(displayName string) string {
2301-
return fmt.Sprintf(delimiter+
2302-
"title: %s\n"+
2303-
"meta_desc: The %s provider for Pulumi can be used to provision any of the cloud resources available in %s.\n"+
2304-
"layout: package\n"+
2305-
delimiter,
2306-
displayName, displayName, displayName)
2307-
}
2308-
2309-
func getBodyAndTitle(content string) (string, string) {
2310-
// The first header in `index.md` is the package name, of the format `# Foo Provider`.
2311-
titleIndex := strings.Index(content, "# ")
2312-
// Get the location fo the next newline
2313-
nextNewLine := strings.Index(content[titleIndex:], "\n") + titleIndex
2314-
// Get the title line, without the h1 anchor
2315-
title := content[titleIndex+2 : nextNewLine]
2316-
// strip the title and any front matter
2317-
return content[nextNewLine+1:], title
2318-
}

pkg/tfgen/docs_test.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,43 +2028,3 @@ resource "aws_ami" "example" {
20282028
})
20292029
}
20302030
}
2031-
2032-
func TestPlainDocsParser(t *testing.T) {
2033-
t.Parallel()
2034-
2035-
type testCase struct {
2036-
// The name of the test case.
2037-
name string
2038-
docFile DocFile
2039-
expected []byte
2040-
}
2041-
2042-
tests := []testCase{
2043-
{
2044-
name: "Replaces Upstream Front Matter With Pulumi Front Matter",
2045-
docFile: DocFile{
2046-
Content: []byte("---\nlayout: \"openstack\"\npage_title: \"Provider: OpenStack\"\nsidebar_current: \"docs-openstack-index\"\ndescription: |-\n The OpenStack provider is used to interact with the many resources supported by OpenStack. The provider needs to be configured with the proper credentials before it can be used.\n---\n\n# OpenStack Provider\n\nThe OpenStack provider is used to interact with the\nmany resources supported by OpenStack. The provider needs to be configured\nwith the proper credentials before it can be used.\n\nUse the navigation to the left to read about the available resources."),
2047-
},
2048-
expected: []byte("---\ntitle: OpenStack Provider Installation & Configuration\nmeta_desc: Provides an overview on how to configure the Pulumi OpenStack Provider.\nlayout: package\n---\n\nThe OpenStack provider is used to interact with the\nmany resources supported by OpenStack. The provider needs to be configured\nwith the proper credentials before it can be used.\n\nUse the navigation to the left to read about the available resources."),
2049-
},
2050-
{
2051-
name: "Writes Pulumi Style Front Matter If Not Present",
2052-
docFile: DocFile{
2053-
Content: []byte("# Artifactory Provider\n\nThe [Artifactory](https://jfrog.com/artifactory/) provider is used to interact with the resources supported by Artifactory. The provider needs to be configured with the proper credentials before it can be used.\n\nLinks to documentation for specific resources can be found in the table of contents to the left.\n\nThis provider requires access to Artifactory APIs, which are only available in the _licensed_ pro and enterprise editions. You can determine which license you have by accessing the following the URL `${host}/artifactory/api/system/licenses/`.\n\nYou can either access it via API, or web browser - it require admin level credentials."),
2054-
},
2055-
expected: []byte("---\ntitle: Artifactory Provider Installation & Configuration\nmeta_desc: Provides an overview on how to configure the Pulumi Artifactory Provider.\nlayout: package\n---\n\nThe [Artifactory](https://jfrog.com/artifactory/) provider is used to interact with the resources supported by Artifactory. The provider needs to be configured with the proper credentials before it can be used.\n\nLinks to documentation for specific resources can be found in the table of contents to the left.\n\nThis provider requires access to Artifactory APIs, which are only available in the _licensed_ pro and enterprise editions. You can determine which license you have by accessing the following the URL `${host}/artifactory/api/system/licenses/`.\n\nYou can either access it via API, or web browser - it require admin level credentials."),
2056-
},
2057-
}
2058-
for _, tt := range tests {
2059-
tt := tt
2060-
t.Run(tt.name, func(t *testing.T) {
2061-
t.Parallel()
2062-
g := &Generator{
2063-
sink: mockSink{t},
2064-
}
2065-
actual, err := plainDocsParser(&tt.docFile, g)
2066-
require.NoError(t, err)
2067-
require.Equal(t, string(tt.expected), string(actual))
2068-
})
2069-
}
2070-
}

pkg/tfgen/installation_docs.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package tfgen
2+
3+
import (
4+
"fmt"
5+
"golang.org/x/text/cases"
6+
"golang.org/x/text/language"
7+
"strings"
8+
)
9+
10+
func plainDocsParser(docFile *DocFile, g *Generator) ([]byte, error) {
11+
// Get file content without front matter, and split title
12+
contentStr, title := getBodyAndTitle(string(docFile.Content))
13+
// Add pulumi-specific front matter
14+
// Generate pulumi-specific front matter
15+
frontMatter := writeFrontMatter(title)
16+
17+
// Generate pulumi-specific installation instructions
18+
installationInstructions := writeInstallationInstructions(g.info.Golang.ImportBasePath, g.info.Name)
19+
20+
// Add instructions to top of file
21+
contentStr = frontMatter + installationInstructions + contentStr
22+
23+
//TODO: See https://github.com/pulumi/pulumi-terraform-bridge/issues/2078
24+
// - translate code blocks with code choosers
25+
// - apply default edit rules
26+
// - reformat TF names
27+
// - Translation for certain headers such as "Arguments Reference" or "Configuration block"
28+
// - Ability to omit irrelevant sections
29+
return []byte(contentStr), nil
30+
}
31+
32+
func writeFrontMatter(title string) string {
33+
return fmt.Sprintf(delimiter+
34+
"title: %[1]s Installation & Configuration\n"+
35+
"meta_desc: Provides an overview on how to configure the Pulumi %[1]s.\n"+
36+
"layout: package\n"+
37+
delimiter+
38+
"\n",
39+
title)
40+
}
41+
42+
func writeIndexFrontMatter(displayName string) string {
43+
return fmt.Sprintf(delimiter+
44+
"title: %[1]s\n"+
45+
"meta_desc: The %[1]s provider for Pulumi can be used to provision any of the cloud resources available in %[1]s.\n"+
46+
"layout: package\n"+
47+
delimiter,
48+
displayName)
49+
}
50+
51+
func getBodyAndTitle(content string) (string, string) {
52+
// The first header in `index.md` is the package name, of the format `# Foo Provider`.
53+
titleIndex := strings.Index(content, "# ")
54+
// Get the location fo the next newline
55+
nextNewLine := strings.Index(content[titleIndex:], "\n") + titleIndex
56+
// Get the title line, without the h1 anchor
57+
title := content[titleIndex+2 : nextNewLine]
58+
// strip the title and any front matter
59+
return content[nextNewLine+1:], title
60+
}
61+
62+
// writeInstallationInstructions renders the following for any provider:
63+
// ****
64+
// Installation
65+
// The Foo provider is available as a package in all Pulumi languages:
66+
//
67+
// JavaScript/TypeScript: @pulumi/foo
68+
// Python: pulumi-foo
69+
// Go: github.com/pulumi/pulumi-foo/sdk/v3/go/foo
70+
// .NET: Pulumi.foo
71+
// Java: com.pulumi/foo
72+
// ****
73+
func writeInstallationInstructions(goImportBasePath, providerName string) string {
74+
75+
// Capitalize the package name for C#
76+
capitalize := cases.Title(language.English)
77+
cSharpName := capitalize.String(providerName)
78+
79+
return fmt.Sprintf(
80+
"## Installation\n\n"+
81+
"The %[1]s provider is available as a package in all Pulumi languages:\n\n"+
82+
"* JavaScript/TypeScript: [`@pulumi/%[1]s`](https://www.npmjs.com/package/@pulumi/%[1]s)\n"+
83+
"* Python: [`pulumi-%[1]s`](https://pypi.org/project/pulumi-%[1]s/)\n"+ //TODO: get the Go mod version somehow :blood_sob:
84+
"* Go: [`%[3]s`](https://github.com/pulumi/pulumi-%[1]s)\n"+
85+
"* .NET: [`Pulumi.%[2]s`](https://www.nuget.org/packages/Pulumi.%[2]s)\n"+ //TODO: use capitalized
86+
"* Java: [`com.pulumi/%[1]s`](https://central.sonatype.com/artifact/com.pulumi/%[1]s)\n\n",
87+
providerName,
88+
cSharpName,
89+
goImportBasePath,
90+
)
91+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package tfgen
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"testing"
6+
)
7+
8+
func TestPlainDocsParser(t *testing.T) {
9+
t.Parallel()
10+
11+
type testCase struct {
12+
// The name of the test case.
13+
name string
14+
docFile DocFile
15+
expected []byte
16+
g *Generator
17+
}
18+
19+
tests := []testCase{
20+
{
21+
name: "Replaces Upstream Front Matter With Pulumi Front Matter",
22+
docFile: DocFile{
23+
Content: []byte("---\nlayout: \"openstack\"\npage_title: \"Provider: OpenStack\"\nsidebar_current: \"docs-openstack-index\"\ndescription: |-\n The OpenStack provider is used to interact with the many resources supported by OpenStack. The provider needs to be configured with the proper credentials before it can be used.\n---\n\n# OpenStack Provider\n\nThe OpenStack provider is used to interact with the\nmany resources supported by OpenStack. The provider needs to be configured\nwith the proper credentials before it can be used.\n\nUse the navigation to the left to read about the available resources."),
24+
},
25+
expected: []byte("---\ntitle: OpenStack Provider Installation & Configuration\nmeta_desc: Provides an overview on how to configure the Pulumi OpenStack Provider.\nlayout: package\n---\n\nThe OpenStack provider is used to interact with the\nmany resources supported by OpenStack. The provider needs to be configured\nwith the proper credentials before it can be used.\n\nUse the navigation to the left to read about the available resources."),
26+
},
27+
{
28+
name: "Writes Pulumi Style Front Matter If Not Present",
29+
docFile: DocFile{
30+
Content: []byte("# Artifactory Provider\n\nThe [Artifactory](https://jfrog.com/artifactory/) provider is used to interact with the resources supported by Artifactory. The provider needs to be configured with the proper credentials before it can be used.\n\nLinks to documentation for specific resources can be found in the table of contents to the left.\n\nThis provider requires access to Artifactory APIs, which are only available in the _licensed_ pro and enterprise editions. You can determine which license you have by accessing the following the URL `${host}/artifactory/api/system/licenses/`.\n\nYou can either access it via API, or web browser - it require admin level credentials."),
31+
},
32+
expected: []byte("---\ntitle: Artifactory Provider Installation & Configuration\nmeta_desc: Provides an overview on how to configure the Pulumi Artifactory Provider.\nlayout: package\n---\n\nThe [Artifactory](https://jfrog.com/artifactory/) provider is used to interact with the resources supported by Artifactory. The provider needs to be configured with the proper credentials before it can be used.\n\nLinks to documentation for specific resources can be found in the table of contents to the left.\n\nThis provider requires access to Artifactory APIs, which are only available in the _licensed_ pro and enterprise editions. You can determine which license you have by accessing the following the URL `${host}/artifactory/api/system/licenses/`.\n\nYou can either access it via API, or web browser - it require admin level credentials."),
33+
},
34+
}
35+
for _, tt := range tests {
36+
tt := tt
37+
t.Run(tt.name, func(t *testing.T) {
38+
t.Skipf("this function is under development and will receive tests once all parts are completed")
39+
t.Parallel()
40+
g := &Generator{
41+
sink: mockSink{t},
42+
}
43+
actual, err := plainDocsParser(&tt.docFile, g)
44+
require.NoError(t, err)
45+
require.Equal(t, string(tt.expected), string(actual))
46+
})
47+
}
48+
}
49+
50+
func TestWriteInstallationInstructions(t *testing.T) {
51+
t.Parallel()
52+
53+
type testCase struct {
54+
// The name of the test case.
55+
name string
56+
docFile DocFile
57+
goImportBasePath string
58+
packageName string
59+
expected string
60+
}
61+
62+
tc := testCase{
63+
64+
name: "Generates Install Information From Package Name",
65+
expected: "## Installation\n\n" +
66+
"The testcase provider is available as a package in all Pulumi languages:\n\n" +
67+
"* JavaScript/TypeScript: [`@pulumi/testcase`](https://www.npmjs.com/package/@pulumi/testcase)\n" +
68+
"* Python: [`pulumi-testcase`](https://pypi.org/project/pulumi-testcase/)\n" + //TODO: get the Go mod version somehow :blood_sob:
69+
"* Go: [`github.com/pulumi/pulumi-testcase/sdk/v3/go/pulumi-testcase`](https://github.com/pulumi/pulumi-testcase)\n" +
70+
"* .NET: [`Pulumi.Testcase`](https://www.nuget.org/packages/Pulumi.Testcase)\n" + //TODO: use capitalized
71+
"* Java: [`com.pulumi/testcase`](https://central.sonatype.com/artifact/com.pulumi/testcase)\n\n",
72+
goImportBasePath: "github.com/pulumi/pulumi-testcase/sdk/v3/go/pulumi-testcase",
73+
packageName: "testcase",
74+
}
75+
76+
t.Run(tc.name, func(t *testing.T) {
77+
t.Parallel()
78+
actual := writeInstallationInstructions(tc.goImportBasePath, tc.packageName)
79+
require.Equal(t, string(tc.expected), actual)
80+
})
81+
}
82+
83+
func TestWriteFrontMatter(t *testing.T) {
84+
t.Parallel()
85+
86+
type testCase struct {
87+
// The name of the test case.
88+
name string
89+
docFile DocFile
90+
title string
91+
expected string
92+
}
93+
94+
tc := testCase{
95+
name: "Generates Front Matter for installation-configuration.md",
96+
title: "Testcase Provider",
97+
expected: delimiter +
98+
"title: Testcase Provider Installation & Configuration\n" +
99+
"meta_desc: Provides an overview on how to configure the Pulumi Testcase Provider.\n" +
100+
"layout: package\n" +
101+
delimiter +
102+
"\n",
103+
}
104+
105+
t.Run(tc.name, func(t *testing.T) {
106+
t.Parallel()
107+
actual := writeFrontMatter(tc.title)
108+
require.Equal(t, tc.expected, actual)
109+
})
110+
}
111+
112+
func TestWriteIndexFrontMatter(t *testing.T) {
113+
t.Parallel()
114+
115+
type testCase struct {
116+
// The name of the test case.
117+
name string
118+
docFile DocFile
119+
displayName string
120+
expected string
121+
}
122+
123+
tc := testCase{
124+
name: "Generates Front Matter for _index.md",
125+
displayName: "Testcase",
126+
expected: delimiter +
127+
"title: Testcase\n" +
128+
"meta_desc: The Testcase provider for Pulumi can be used to provision any of the cloud resources available in Testcase.\n" +
129+
"layout: package\n" +
130+
delimiter,
131+
}
132+
133+
t.Run(tc.name, func(t *testing.T) {
134+
t.Parallel()
135+
actual := writeIndexFrontMatter(tc.displayName)
136+
require.Equal(t, tc.expected, actual)
137+
})
138+
}

0 commit comments

Comments
 (0)