Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Example documentation for Image #479

Merged
merged 13 commits into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ cleanup:
rm -r $(WORKING_DIR)/bin
rm -f provider/cmd/$(PROVIDER)/schema.go

examples:
guineveresaenger marked this conversation as resolved.
Show resolved Hide resolved
cd provider/pkg/docs-gen/examples/ && go run generate.go ./yaml ./

help:
@grep '^[^.#]\+:\s\+.*#' Makefile | \
sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\033[93m"`\1`printf "\033[0m"` \3 [\2]/" | \
Expand All @@ -102,12 +105,12 @@ provider: tfgen install_plugins
test:
cd examples && go test -v -tags=all -parallel $(TESTPARALLELISM) -timeout 2h

tfgen: install_plugins
tfgen: examples install_plugins
(cd provider && go build -p 1 -o $(WORKING_DIR)/bin/$(TFGEN) -ldflags "-X $(PROJECT)/$(VERSION_PATH)=$(VERSION)" $(PROJECT)/$(PROVIDER_PATH)/cmd/$(TFGEN))
$(WORKING_DIR)/bin/$(TFGEN) schema --out provider/cmd/$(PROVIDER)
(cd provider && VERSION=$(VERSION) go generate cmd/$(PROVIDER)/main.go)

bin/pulumi-java-gen:
$(shell pulumictl download-binary -n pulumi-language-java -v $(JAVA_GEN_VERSION) -r pulumi/pulumi-java)

.PHONY: development build build_sdks install_go_sdk install_java_sdk install_python_sdk install_sdks only_build build_dotnet build_go build_java build_nodejs build_python clean cleanup help install_dotnet_sdk install_nodejs_sdk install_plugins lint_provider provider test tfgen
.PHONY: development build build_sdks examples install_go_sdk install_java_sdk install_python_sdk install_sdks only_build build_dotnet build_go build_java build_nodejs build_python clean cleanup help install_dotnet_sdk install_nodejs_sdk install_plugins lint_provider provider test tfgen
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so diffs become meaningful (assuming we are now editing this file by hand.

Suggested change
.PHONY: development build build_sdks examples install_go_sdk install_java_sdk install_python_sdk install_sdks only_build build_dotnet build_go build_java build_nodejs build_python clean cleanup help install_dotnet_sdk install_nodejs_sdk install_plugins lint_provider provider test tfgen
.PHONY: development build build_sdks \
examples install_go_sdk install_java_sdk \
install_python_sdk install_sdks only_build \
build_dotnet build_go build_java \
build_nodejs build_python clean \
cleanup help install_dotnet_sdk \
install_nodejs_sdk install_plugins lint_provider \
test tfgen provider

12 changes: 6 additions & 6 deletions provider/cmd/pulumi-resource-docker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3017,7 +3017,7 @@
]
},
"docker:index/builderVersion:BuilderVersion": {
"description": "The version of the Docker builder",
"description": "The version of the Docker builder.",
"type": "string",
"enum": [
{
Expand Down Expand Up @@ -3053,11 +3053,11 @@
"additionalProperties": {
"type": "string"
},
"description": "An optional map of named build-time argument variables to set during the Docker build. This flag allows you to pass built-time variablesthat can be accessed like environment variables inside the RUN instruction."
"description": "An optional map of named build-time argument variables to set during the Docker build. This flag allows you to pass build-time variablesthat can be accessed like environment variables inside the RUN instruction."
},
"builderVersion": {
"$ref": "#/types/docker:index/builderVersion:BuilderVersion",
"description": "The version of the Docker builder. ",
"description": "The version of the Docker builder.",
"default": "BuilderBuildKit"
},
"cacheFrom": {
Expand All @@ -3076,7 +3076,7 @@
},
"platform": {
"type": "string",
"description": " Set platform if server is multi-platform capable"
"description": "The architecture of the platform you want to build this image for, e.g. `linux/arm64`."
},
"target": {
"type": "string",
Expand Down Expand Up @@ -4418,7 +4418,7 @@
}
},
"docker:index/image:Image": {
"description": "Builds a Docker Image and pushes to a Docker registry.",
"description": "{{% examples %}}\nBuilds a Docker Image and pushes to a Docker registry.\n\n{{% examples %}}\n## Example Usage\n{{% example %}}\n### A Docker image build\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst demoImage = new docker.Image(\"demo-image\", {\n build: {\n context: \".\",\n dockerfile: \"Dockerfile\",\n },\n imageName: \"username/image:tag1\",\n skipPush: true,\n});\nexport const imageName = demoImage.imageName;\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\ndemo_image = docker.Image(\"demo-image\",\n build={\n \"context\": \".\",\n \"dockerfile\": \"Dockerfile\",\n },\n image_name=\"username/image:tag1\",\n skip_push=True)\npulumi.export(\"imageName\", demo_image.image_name)\n```\n```csharp\nusing System.Collections.Generic;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var demoImage = new Docker.Image(\"demo-image\", new()\n {\n Build = \n {\n { \"context\", \".\" },\n { \"dockerfile\", \"Dockerfile\" },\n },\n ImageName = \"username/image:tag1\",\n SkipPush = true,\n });\n\n return new Dictionary\u003cstring, object?\u003e\n {\n [\"imageName\"] = demoImage.ImageName,\n };\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tdemoImage, err := docker.NewImage(ctx, \"demo-image\", \u0026docker.ImageArgs{\n\t\t\tBuild: pulumi.Any{\n\t\t\t\tContext: pulumi.String(\".\"),\n\t\t\t\tDockerfile: pulumi.String(\"Dockerfile\"),\n\t\t\t},\n\t\t\tImageName: pulumi.String(\"username/image:tag1\"),\n\t\t\tSkipPush: pulumi.Bool(true),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tctx.Export(\"imageName\", demoImage.ImageName)\n\t\treturn nil\n\t})\n}\n```\n```yaml\nconfig: {}\ndescription: A Docker image build\nname: image-yaml\noutputs:\n imageName: ${demo-image.imageName}\nresources:\n demo-image:\n options:\n version: v4.0.0-alpha.1\n properties:\n build:\n context: .\n dockerfile: Dockerfile\n imageName: username/image:tag1\n skipPush: true\n type: docker:Image\nruntime: yaml\nvariables: {}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.Image;\nimport com.pulumi.docker.ImageArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var demoImage = new Image(\"demoImage\", ImageArgs.builder()\n .imageName(\"username/image:tag1\")\n .skipPush(true)\n .build());\n\n ctx.export(\"imageName\", demoImage.imageName());\n }\n}\n```\n{{% /example %}}\n{{% /examples %}}\n\n{{% //examples %}}",
"properties": {
"baseImageName": {
"type": "string",
Expand All @@ -4430,7 +4430,7 @@
},
"registryServer": {
"type": "string",
"description": "The URL of the registry server hosting the image."
"description": "The name of the registry server hosting the image."
}
},
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/terraform-providers/terraform-provider-docker/shim v0.0.0
google.golang.org/grpc v1.51.0
google.golang.org/protobuf v1.28.1
gopkg.in/yaml.v3 v3.0.1
)

replace (
Expand Down Expand Up @@ -256,7 +257,6 @@ require (
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/frand v1.4.2 // indirect
sourcegraph.com/sourcegraph/appdash v0.0.0-20211028080628-e2786a622600 // indirect
)
6 changes: 6 additions & 0 deletions provider/nativeDocs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package provider

import _ "embed" // nolint:golint

//go:embed pkg/docs-gen/examples/image.md
var docImage string
172 changes: 172 additions & 0 deletions provider/pkg/docs-gen/examples/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package main

import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
"gopkg.in/yaml.v3"
)

//go:generate go run generate.go yaml .

func main() {
if len(os.Args) < 3 {
fmt.Fprintf(os.Stdout, "Usage: %s <yaml source dir path> <markdown destination path>\n", os.Args[0])
os.Exit(1)
}
yamlPath := os.Args[1]
mdPath := os.Args[2]

if !filepath.IsAbs(yamlPath) {
cwd, err := os.Getwd()
contract.AssertNoError(err)
yamlPath = filepath.Join(cwd, yamlPath)
}

fileInfo, err := os.Lstat(mdPath)
if err != nil && os.IsNotExist(err) {
if err := os.MkdirAll(mdPath, 0600); err != nil {
panic(err)
}
}

if !fileInfo.IsDir() {
fmt.Fprintf(os.Stderr, "Expect markdown destination %q to be a directory\n", mdPath)
os.Exit(1)
}

yamlFiles, err := os.ReadDir(yamlPath)
if err != nil {
panic(err)
}
for _, yamlFile := range yamlFiles {
if err := processYaml(filepath.Join(yamlPath, yamlFile.Name()), mdPath); err != nil {
fmt.Fprintf(os.Stderr, "%+v", err)
os.Exit(1)
}
}
}

func markdownExamples(examples []string) string {
s := "{{% examples %}}\n## Example Usage\n"
for _, example := range examples {
s += example
}
s += "{{% /examples %}}\n"
return s
}

func markdownExample(description string,
typescript string,
python string,
csharp string,
golang string,
yaml string,
java string) string {

return fmt.Sprintf("{{%% example %%}}\n### %s\n\n"+
"```typescript\n%s```\n"+
"```python\n%s```\n"+
"```csharp\n%s```\n"+
"```go\n%s```\n"+
"```yaml\n%s```\n"+
"```java\n%s```\n"+
"{{%% /example %%}}\n",
description, typescript, python, csharp, golang, yaml, java)
}

func convert(language, tempDir, programFile string) (string, error) {
exampleDir := filepath.Join(tempDir, "example"+language)
cmd := exec.Command(
"pulumi",
"convert",
"--language",
language,
"--out",
filepath.Join(tempDir, exampleDir),
"--generate-only",
)

cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Dir = tempDir
if err := cmd.Run(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "convert %s failed, ignoring: %+v", language, err)
}
content, err := os.ReadFile(filepath.Join(tempDir, exampleDir, programFile))
if err != nil {
return "", err
}

return string(content), nil
}

func processYaml(path string, mdDir string) error {
yamlFile, err := os.Open(path)
if err != nil {
return err
}

base := filepath.Base(path)
md := strings.NewReplacer(".yaml", ".md", ".yml", ".md").Replace(base)

defer contract.IgnoreClose(yamlFile)
decoder := yaml.NewDecoder(yamlFile)
exampleStrings := []string{}
for {
example := map[string]interface{}{}
err := decoder.Decode(&example)
if err == io.EOF {
break
}

description := example["description"].(string)
dir, err := os.MkdirTemp("", "")
if err != nil {
return err
}

defer func() {
contract.IgnoreError(os.RemoveAll(dir))
}()

src, err := os.OpenFile(filepath.Join(dir, "Pulumi.yaml"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}

if err = yaml.NewEncoder(src).Encode(example); err != nil {
return err
}
contract.AssertNoError(src.Close())

typescript, err := convert("typescript", dir, "index.ts")
guineveresaenger marked this conversation as resolved.
Show resolved Hide resolved
python, err := convert("python", dir, "__main__.py")
csharp, err := convert("csharp", dir, "Program.cs")
golang, err := convert("go", dir, "main.go")
java, err := convert("java", dir, "src/main/java/generated_program/App.java")

yamlContent, err := os.ReadFile(filepath.Join(dir, "Pulumi.yaml"))
if err != nil {
return err
}
yaml := string(yamlContent)

exampleStrings = append(exampleStrings, markdownExample(description, typescript, python, csharp, golang, yaml, java))
}
contract.AssertNoError(err)
fmt.Fprintf(os.Stdout, "Writing %s\n", filepath.Join(mdDir, md))
f, err := os.OpenFile(filepath.Join(mdDir, md), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
return err
}
defer contract.IgnoreClose(f)
_, err = f.Write([]byte(markdownExamples(exampleStrings)))
contract.AssertNoError(err)
return nil
}
Loading