Skip to content

Commit

Permalink
Handle code blocks in import section
Browse files Browse the repository at this point in the history
  • Loading branch information
andrzejressel committed Sep 1, 2024
1 parent 662459e commit cca2891
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 45 deletions.
127 changes: 83 additions & 44 deletions pkg/tfgen/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,42 @@ func flattenListAttributeKey(attribute string) string {
return strings.ReplaceAll(attribute, ".0", "")
}

func parseImportShellLine(section, token string) string {
if strings.Contains(section, "terraform import") {
// First, remove the `$`
section := strings.Replace(section, "$ ", "", -1)
// Next, remove `terraform import` from the codeblock
section = strings.Replace(section, "terraform import ", "", -1)
importString := ""
parts := strings.Split(section, " ")
for i, p := range parts {
switch i {
case 0:
if !isBlank(p) {
// split the string on . and take the last item
// this gets the identifier broken from the tf resource
ids := strings.Split(p, ".")
name := ids[len(ids)-1]
importString = fmt.Sprintf("%s %s", importString, name)
}
default:
if !isBlank(p) {
importString = fmt.Sprintf("%s %s", importString, p)
}
}
}
var tok string
if token != "" {
tok = token
} else {
tok = "MISSING_TOK"
}
importCommand := fmt.Sprintf("$ pulumi import %s%s", tok, importString)
return importCommand
}
return section
}

func (p *tfMarkdownParser) parseImports(subsection []string) {
var token string
if p.info != nil && p.info.GetTok() != "" {
Expand Down Expand Up @@ -1193,65 +1229,68 @@ func (p *tfMarkdownParser) parseImports(subsection []string) {
}

var importDocString string
for _, section := range subsection {
var i = 0

for i < len(subsection) {
section := subsection[i]
trimmedSection := strings.TrimSpace(section)
if strings.Contains(section, "**NOTE:") || strings.Contains(section, "**Please Note:") ||
strings.Contains(section, "**Note:**") {
// This is a Terraform import specific comment that we don't need to parse or include in our docs
i++
continue
}

// Skip another redundant comment
if strings.Contains(section, "Import is supported using the following syntax") {
i++
continue
}

// Remove the shell comment characters to avoid writing this line as a Markdown H1:
section = strings.TrimPrefix(section, "# ")

// There are multiple variations of codeblocks for import syntax
section = strings.Replace(section, "```shell", "", -1)
section = strings.Replace(section, "```sh", "", -1)
section = strings.Replace(section, "```", "", -1)

if strings.Contains(section, "terraform import") {
// First, remove the `$`
section := strings.Replace(section, "$ ", "", -1)
// Next, remove `terraform import` from the codeblock
section = strings.Replace(section, "terraform import ", "", -1)
importString := ""
parts := strings.Split(section, " ")
for i, p := range parts {
switch i {
case 0:
if !isBlank(p) {
// split the string on . and take the last item
// this gets the identifier broken from the tf resource
ids := strings.Split(p, ".")
name := ids[len(ids)-1]
importString = fmt.Sprintf("%s %s", importString, name)
}
default:
if !isBlank(p) {
importString = fmt.Sprintf("%s %s", importString, p)
}
// Handle terraform blocks - pass them whole without changes
if trimmedSection == "```terraform" || trimmedSection == "```hcl" {
for {
section = subsection[i]
trimmedSection := strings.TrimSpace(section)
importDocString = importDocString + section + "\n"
i++
if trimmedSection == "```" {
break
}
}
var tok string
if token != "" {
tok = token
} else {
tok = "MISSING_TOK"
}
importCommand := fmt.Sprintf("$ pulumi import %s%s\n", tok, importString)
importDetails := "```sh\n" + importCommand + "```\n\n"
importDocString = importDocString + importDetails
} else {
if !isBlank(section) {
// Ensure every section receives a line break.
section = section + "\n\n"
importDocString = importDocString + section
importDocString = importDocString + "\n"
continue
}

// Handle script blocks - replace terraform import with pulumi import
if trimmedSection == "```" || trimmedSection == "```sh" || trimmedSection == "```shell" {
initial := true
for {
section = subsection[i]
trimmedSection := strings.TrimSpace(section)
if initial {
// ``` and ```shell are removed when converting to programming language comment
importDocString = importDocString + "```sh" + "\n"
} else {
importDocString = importDocString + parseImportShellLine(section, token) + "\n"
}
i++
if trimmedSection == "```" && !initial {
break
}
initial = false
}
importDocString = importDocString + "\n"
continue
}

if !isBlank(section) {
// Ensure every section receives a line break.
section = section + "\n\n"
importDocString = importDocString + section
}

i++
}

if len(importDocString) > 0 {
Expand Down
7 changes: 6 additions & 1 deletion pkg/tfgen/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1784,7 +1784,7 @@ func TestParseImports_NoOverrides(t *testing.T) {
"",
},
token: "snowflake:index/accountGrant:AccountGrant",
expected: "## Import\n\nformat is account name | | | privilege | true/false for with_grant_option\n\n```sh\n$ pulumi import snowflake:index/accountGrant:AccountGrant example 'accountName|||USAGE|true'\n```\n\n",
expected: "## Import\n\n```sh\n# format is account name | | | privilege | true/false for with_grant_option\n$ pulumi import snowflake:index/accountGrant:AccountGrant example 'accountName|||USAGE|true'\n```\n\n",
},
{
input: []string{
Expand Down Expand Up @@ -1829,6 +1829,11 @@ func TestParseImports_NoOverrides(t *testing.T) {
token: "aws:lambda/layerVersion:LayerVersion",
expectedFile: "test_data/parse-imports/lambdalayer-expected.md",
},
{
input: readlines(t, "test_data/parse-imports/docker_container.md"),
token: "docker:index/container:Container",
expectedFile: "test_data/parse-imports/docker_container-expected.md",
},
}

for _, tt := range tests {
Expand Down
38 changes: 38 additions & 0 deletions pkg/tfgen/test_data/convertExamples/docker_container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Import is supported using the following syntax by providing the `id`:

```shell
#!/bin/bash
terraform import docker_container.foo id
```

### Example

Assuming you created a `container` as follows

```shell
#!/bin/bash
docker run --name foo -p8080:80 -d nginx
# prints the container ID
9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```

you provide the definition for the resource as follows

```terraform
resource "docker_container" "foo" {
name = "foo"
image = "nginx"
ports {
internal = "80"
external = "8080"
}
}
```

then the import command is as follows

```shell
#!/bin/bash
terraform import docker_container.foo 9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```
39 changes: 39 additions & 0 deletions pkg/tfgen/test_data/parse-imports/docker_container-expected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## Import

```sh
#!/bin/bash
$ pulumi import docker:index/container:Container foo id
```

### Example

Assuming you created a `container` as follows

```sh
#!/bin/bash
docker run --name foo -p8080:80 -d nginx
# prints the container ID
9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```

you provide the definition for the resource as follows

```terraform
resource "docker_container" "foo" {
name = "foo"
image = "nginx"
ports {
internal = "80"
external = "8080"
}
}
```

then the import command is as follows

```sh
#!/bin/bash
$ pulumi import docker:index/container:Container foo 9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```

38 changes: 38 additions & 0 deletions pkg/tfgen/test_data/parse-imports/docker_container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Import is supported using the following syntax by providing the `id`:

```shell
#!/bin/bash
terraform import docker_container.foo id
```

### Example

Assuming you created a `container` as follows

```shell
#!/bin/bash
docker run --name foo -p8080:80 -d nginx
# prints the container ID
9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```

you provide the definition for the resource as follows

```terraform
resource "docker_container" "foo" {
name = "foo"
image = "nginx"
ports {
internal = "80"
external = "8080"
}
}
```

then the import command is as follows

```shell
#!/bin/bash
terraform import docker_container.foo 9a550c0f0163d39d77222d3efd58701b625d47676c25c686c95b5b92d1cba6fd
```

0 comments on commit cca2891

Please sign in to comment.