mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 12:58:35 +07:00
Move plugin-sdk to in-tree in core repository
Moving terraform-docs/plugin-sdk standalone module to in-tree, because
maintaining both of them, specifically if anything needs to be added to
Config, or terraform will required dual effort on both repository. As
such now everything is consolidated under one repository. Example usage
for plugin developer after this move is as follow:
```go
package main
import (
_ "embed" //nolint
"github.com/terraform-docs/terraform-docs/plugin"
"github.com/terraform-docs/terraform-docs/print"
"github.com/terraform-docs/terraform-docs/template"
"github.com/terraform-docs/terraform-docs/terraform"
)
func main() {
plugin.Serve(&plugin.ServeOpts{
Name: "template",
Version: "0.1.0",
Printer: printer,
})
}
//go:embed sections.tmpl
var tplCustom []byte
// Print the custom format template. You have all the flexibility to generate
// the output however you choose to.
func printer(config *print.Config, module *terraform.Module) (string, error) {
tpl := template.New(config,
&template.Item{Name: "custom", Text: string(tplCustom)},
)
rendered, err := tpl.Render("custom", module)
if err != nil {
return "", err
}
return rendered, nil
}
```
Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
80
README.md
80
README.md
@@ -253,6 +253,14 @@ when formatter is set to `markdown table`.
|
||||
Note that sections visibility (i.e. `sections.show` and `sections.hide`) takes
|
||||
precedence over the `content`.
|
||||
|
||||
Additionally there's also one extra special variable avaialble to the `content`:
|
||||
|
||||
- `{{ .Module }}`
|
||||
|
||||
As opposed to the other variables mentioned above, which are generated sections
|
||||
based on a selected formatter, the `{{ .Module }}` variable is just a `struct`
|
||||
representing a [Terraform module].
|
||||
|
||||
````yaml
|
||||
content: |-
|
||||
Any arbitrary text can be placed anywhere in the content
|
||||
@@ -278,6 +286,12 @@ content: |-
|
||||
```hcl
|
||||
{{ include "examples/foo/main.tf" }}
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
{{ range .Module.Resources }}
|
||||
- {{ .GetMode }}.{{ .Spec }} ({{ .Position.Filename }}#{{ .Position.Line }})
|
||||
{{- end }}
|
||||
````
|
||||
|
||||
## Build on top of terraform-docs
|
||||
@@ -320,6 +334,68 @@ func buildTerraformDocs(path string, tmpl string) (string, error) {
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin
|
||||
|
||||
Generated output can be heavily customized with [`content`], but if using that
|
||||
is not enough for your use-case, you can write your own plugin.
|
||||
|
||||
In order to install a plugin the following steps are needed:
|
||||
|
||||
- download the plugin and place it in `~/.tfdocs.d/plugins` (or `./.tfdocs.d/plugins`)
|
||||
- make sure the plugin file name is `tfdocs-format-<NAME>`
|
||||
- modify [`formatter`] of `.terraform-docs.yml` file to be `<NAME>`
|
||||
|
||||
**Important notes:**
|
||||
|
||||
- if the plugin file name is different than the example above, terraform-docs won't
|
||||
be able to to pick it up nor register it properly
|
||||
- you can only use plugin thorough `.terraform-docs.yml` file and it cannot be used
|
||||
with CLI arguments
|
||||
|
||||
To create a new plugin create a new repository called `tfdocs-format-<NAME>` with
|
||||
following `main.go`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed" //nolint
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/plugin"
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
"github.com/terraform-docs/terraform-docs/template"
|
||||
"github.com/terraform-docs/terraform-docs/terraform"
|
||||
)
|
||||
|
||||
func main() {
|
||||
plugin.Serve(&plugin.ServeOpts{
|
||||
Name: "<NAME>",
|
||||
Version: "0.1.0",
|
||||
Printer: printerFunc,
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed sections.tmpl
|
||||
var tplCustom []byte
|
||||
|
||||
// printerFunc the function being executed by the plugin client.
|
||||
func printerFunc(config *print.Config, module *terraform.Module) (string, error) {
|
||||
tpl := template.New(config,
|
||||
&template.Item{Name: "custom", Text: string(tplCustom)},
|
||||
)
|
||||
|
||||
rendered, err := tpl.Render("custom", module)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rendered, nil
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to [tfdocs-format-template] for more details. You can create a new
|
||||
repository from it by clicking on `Use this template` button.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Users**
|
||||
@@ -341,8 +417,10 @@ MIT License - Copyright (c) 2021 The terraform-docs Authors.
|
||||
|
||||
[Chocolatey]: https://www.chocolatey.org
|
||||
[Config File Reference]: https://terraform-docs.io/user-guide/configuration/
|
||||
[`content`]: https://terraform-docs.io/user-guide/configuration/content/
|
||||
[Contributing Guide]: CONTRIBUTING.md
|
||||
[Formats Guide]: https://terraform-docs.io/reference/terraform-docs/
|
||||
[`formatter`]: https://terraform-docs.io/user-guide/configuration/formatter/
|
||||
[here]: https://golang.org/doc/code.html#GOPATH
|
||||
[Homebrew]: https://brew.sh
|
||||
[install pre-commit]: https://pre-commit.com/#install
|
||||
@@ -351,5 +429,7 @@ MIT License - Copyright (c) 2021 The terraform-docs Authors.
|
||||
[Scoop]: https://scoop.sh/
|
||||
[Slack]: https://slack.terraform-docs.io/
|
||||
[terraform-docs GitHub Action]: https://github.com/terraform-docs/gh-actions
|
||||
[Terraform module]: https://pkg.go.dev/github.com/terraform-docs/terraform-docs/terraform#Module
|
||||
[tfdocs-format-template]: https://github.com/terraform-docs/tfdocs-format-template
|
||||
[our website]: https://terraform-docs.io/
|
||||
[User Guide]: https://terraform-docs.io/user-guide/introduction/
|
||||
|
||||
@@ -8,13 +8,66 @@ weight: 310
|
||||
toc: false
|
||||
---
|
||||
|
||||
If you want to add or change formatter, you need to write plugins. When changing
|
||||
plugins, refer to the repository of each plugin and refer to how to build and
|
||||
install.
|
||||
Generated output can be heavily customized with [`content`], but if using that
|
||||
is not enough for your use-case, you can write your own plugin.
|
||||
|
||||
If you want to create a new plugin, please refer to [tfdocs-format-template]. The
|
||||
plugin can use [plugin-sdk] to communicate with the host process. You can create a
|
||||
new repository from `Use this template`.
|
||||
In order to install a plugin the following steps are needed:
|
||||
|
||||
[plugin-sdk]: https://github.com/terraform-docs/plugin-sdk
|
||||
- download the plugin and place it in `~/.tfdocs.d/plugins` (or `./.tfdocs.d/plugins`)
|
||||
- make sure the plugin file name is `tfdocs-format-<NAME>`
|
||||
- modify [`formatter`] of `.terraform-docs.yml` file to be `<NAME>`
|
||||
|
||||
**Important notes:**
|
||||
|
||||
- if the plugin file name is different than the example above, terraform-docs won't
|
||||
be able to to pick it up nor register it properly
|
||||
- you can only use plugin thorough `.terraform-docs.yml` file and it cannot be used
|
||||
with CLI arguments
|
||||
|
||||
To create a new plugin create a new repository called `tfdocs-format-<NAME>` with
|
||||
following `main.go`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed" //nolint
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/plugin"
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
"github.com/terraform-docs/terraform-docs/template"
|
||||
"github.com/terraform-docs/terraform-docs/terraform"
|
||||
)
|
||||
|
||||
func main() {
|
||||
plugin.Serve(&plugin.ServeOpts{
|
||||
Name: "<NAME>",
|
||||
Version: "0.1.0",
|
||||
Printer: printerFunc,
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed sections.tmpl
|
||||
var tplCustom []byte
|
||||
|
||||
// printerFunc the function being executed by the plugin client.
|
||||
func printerFunc(config *print.Config, module *terraform.Module) (string, error) {
|
||||
tpl := template.New(config,
|
||||
&template.Item{Name: "custom", Text: string(tplCustom)},
|
||||
)
|
||||
|
||||
rendered, err := tpl.Render("custom", module)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rendered, nil
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to [tfdocs-format-template] for more details. You can create a new
|
||||
repository from it by clicking on `Use this template` button.
|
||||
|
||||
[`content`]: {{< ref "content" >}}
|
||||
[`formatter`]: {{< ref "formatter" >}}
|
||||
[tfdocs-format-template]: https://github.com/terraform-docs/tfdocs-format-template
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# version: ">= 0.10, < 0.12"
|
||||
|
||||
# see: https://terraform-docs.io/user-guide/configuration/formatter
|
||||
formatter: markdown table
|
||||
# formatter: markdown table
|
||||
formatter: template
|
||||
|
||||
# see: https://terraform-docs.io/user-guide/configuration/header-from
|
||||
header-from: doc.txt
|
||||
|
||||
2
go.mod
2
go.mod
@@ -5,6 +5,7 @@ go 1.16
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/Masterminds/sprig/v3 v3.2.2
|
||||
github.com/hashicorp/go-hclog v0.15.0
|
||||
github.com/hashicorp/go-plugin v1.4.2
|
||||
github.com/hashicorp/go-version v1.3.0
|
||||
github.com/hashicorp/hcl/v2 v2.10.1
|
||||
@@ -15,7 +16,6 @@ require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/terraform-docs/plugin-sdk v0.3.1-0.20210825180722-c52e9860f575
|
||||
github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178932fa
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
honnef.co/go/tools v0.2.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -172,7 +172,6 @@ github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
|
||||
github.com/hashicorp/go-plugin v1.4.2 h1:yFvG3ufXXpqiMiZx9HLcaK3XbIqQ1WJFR/F1a2CuVw0=
|
||||
github.com/hashicorp/go-plugin v1.4.2/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
@@ -310,8 +309,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/terraform-docs/plugin-sdk v0.3.1-0.20210825180722-c52e9860f575 h1:pwOvvonyymFBE2YE5Yx1M236lH4WT9i8sgVYC4KMsgE=
|
||||
github.com/terraform-docs/plugin-sdk v0.3.1-0.20210825180722-c52e9860f575/go.mod h1:3G+0nZTeaMF1c5CZh8cOEYeNq0kUL6+DlQOVcxK7eCQ=
|
||||
github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178932fa h1:wdyf3TobwYFwsqnUGJcjdNHxKfwHPFbaOknBJehnF1M=
|
||||
github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178932fa/go.mod h1:GtanFwTsRRXScYHOMb5h4K18XQBFeS2tXat9/LrPtPc=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
@@ -691,7 +688,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.1.2/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
|
||||
honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE=
|
||||
honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
|
||||
mvdan.cc/xurls/v2 v2.3.0 h1:59Olnbt67UKpxF1EwVBopJvkSUBmgtb468E4GVWIZ1I=
|
||||
|
||||
@@ -22,10 +22,10 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
pluginsdk "github.com/terraform-docs/plugin-sdk/plugin"
|
||||
"github.com/terraform-docs/terraform-docs/format"
|
||||
"github.com/terraform-docs/terraform-docs/internal/plugin"
|
||||
"github.com/terraform-docs/terraform-docs/internal/version"
|
||||
pluginsdk "github.com/terraform-docs/terraform-docs/plugin"
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
"github.com/terraform-docs/terraform-docs/terraform"
|
||||
)
|
||||
@@ -344,9 +344,9 @@ func generateContent(config *print.Config) error {
|
||||
return fmt.Errorf("formatter '%s' not found", config.Formatter)
|
||||
}
|
||||
|
||||
content, cerr := client.Execute(pluginsdk.ExecuteArgs{
|
||||
Module: module.Convert(),
|
||||
Settings: nil, // TODO settings.Convert(),
|
||||
content, cerr := client.Execute(&pluginsdk.ExecuteArgs{
|
||||
Module: module,
|
||||
Config: config,
|
||||
})
|
||||
if cerr != nil {
|
||||
return cerr
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
|
||||
pluginsdk "github.com/terraform-docs/plugin-sdk/plugin"
|
||||
pluginsdk "github.com/terraform-docs/terraform-docs/plugin"
|
||||
)
|
||||
|
||||
// Discover plugins and registers them. The lookup priority of plugins is as
|
||||
|
||||
@@ -13,7 +13,7 @@ package plugin
|
||||
import (
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
pluginsdk "github.com/terraform-docs/plugin-sdk/plugin"
|
||||
pluginsdk "github.com/terraform-docs/terraform-docs/plugin"
|
||||
)
|
||||
|
||||
// namePrefix is the mandatory prefix for name of the plugin file. What
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"go/types"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
@@ -94,7 +93,7 @@ func TypeOf(t string, v interface{}) String {
|
||||
}
|
||||
|
||||
// Nil represents a 'nil' value which is marshaled to `null` when empty for JSON and YAML
|
||||
type Nil types.Nil
|
||||
type Nil struct{}
|
||||
|
||||
// HasDefault return false for Nil, because there's no value set for the variable
|
||||
func (n Nil) HasDefault() bool {
|
||||
|
||||
84
plugin/client.go
Normal file
84
plugin/client.go
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright 2021 The terraform-docs Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
"github.com/terraform-docs/terraform-docs/terraform"
|
||||
)
|
||||
|
||||
// Client is an RPC Client for the host.
|
||||
type Client struct {
|
||||
rpcClient *rpc.Client
|
||||
broker *goplugin.MuxBroker
|
||||
}
|
||||
|
||||
// ClientOpts is an option for initializing a Client.
|
||||
type ClientOpts struct {
|
||||
Cmd *exec.Cmd
|
||||
}
|
||||
|
||||
// ExecuteArgs is the collection of arguments being sent by terraform-docs
|
||||
// core while executing the plugin command.
|
||||
type ExecuteArgs struct {
|
||||
Module *terraform.Module
|
||||
Config *print.Config
|
||||
}
|
||||
|
||||
// NewClient is a wrapper of plugin.NewClient.
|
||||
func NewClient(opts *ClientOpts) *goplugin.Client {
|
||||
return goplugin.NewClient(&goplugin.ClientConfig{
|
||||
HandshakeConfig: handshakeConfig,
|
||||
Plugins: map[string]goplugin.Plugin{
|
||||
"formatter": &formatter{},
|
||||
},
|
||||
Cmd: opts.Cmd,
|
||||
Logger: hclog.New(&hclog.LoggerOptions{
|
||||
Name: "plugin",
|
||||
Output: os.Stderr,
|
||||
Level: hclog.LevelFromString(os.Getenv("TFDOCS_LOG")),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
// Name calls the server-side Name method and returns its version.
|
||||
func (c *Client) Name() (string, error) {
|
||||
var resp string
|
||||
err := c.rpcClient.Call("Plugin.Name", new(interface{}), &resp)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Version calls the server-side Version method and returns its version.
|
||||
func (c *Client) Version() (string, error) {
|
||||
var resp string
|
||||
err := c.rpcClient.Call("Plugin.Version", new(interface{}), &resp)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Execute calls the server-side Execute method and returns generated output.
|
||||
func (c *Client) Execute(args *ExecuteArgs) (string, error) {
|
||||
var resp string
|
||||
err := c.rpcClient.Call("Plugin.Execute", args, &resp)
|
||||
return resp, err
|
||||
}
|
||||
68
plugin/doc.go
Normal file
68
plugin/doc.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2021 The terraform-docs Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Package plugin contains the implementations needed to make
|
||||
// the built binary act as a plugin.
|
||||
//
|
||||
// A plugin is implemented as an RPC server and the host acts
|
||||
// as the client, sending analysis requests to the plugin.
|
||||
// Note that the server-client relationship here is the opposite of
|
||||
// the communication that takes place during the checking phase.
|
||||
//
|
||||
// Implementation details are hidden in go-plugin. This package is
|
||||
// essentially a wrapper for go-plugin.
|
||||
//
|
||||
// Usage
|
||||
//
|
||||
// A simple plugin can look like this:
|
||||
//
|
||||
// package main
|
||||
//
|
||||
// import (
|
||||
// _ "embed" //nolint
|
||||
//
|
||||
// "github.com/terraform-docs/terraform-docs/plugin"
|
||||
// "github.com/terraform-docs/terraform-docs/print"
|
||||
// "github.com/terraform-docs/terraform-docs/template"
|
||||
// "github.com/terraform-docs/terraform-docs/terraform"
|
||||
// )
|
||||
//
|
||||
// func main() {
|
||||
// plugin.Serve(&plugin.ServeOpts{
|
||||
// Name: "template",
|
||||
// Version: "0.1.0",
|
||||
// Printer: printerFunc,
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// //go:embed sections.tmpl
|
||||
// var tplCustom []byte
|
||||
//
|
||||
// // printerFunc the function being executed by the plugin client.
|
||||
// func printerFunc(config *print.Config, module *terraform.Module) (string, error) {
|
||||
// tpl := template.New(config,
|
||||
// &template.Item{Name: "custom", Text: string(tplCustom)},
|
||||
// )
|
||||
//
|
||||
// rendered, err := tpl.Render("custom", module)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
//
|
||||
// return rendered, nil
|
||||
// }
|
||||
//
|
||||
package plugin
|
||||
80
plugin/plugin.go
Normal file
80
plugin/plugin.go
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2021 The terraform-docs Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"net/rpc"
|
||||
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
)
|
||||
|
||||
// handshakeConfig is used for UX. ProcotolVersion will be updated by incompatible changes.
|
||||
var handshakeConfig = goplugin.HandshakeConfig{
|
||||
ProtocolVersion: 7,
|
||||
MagicCookieKey: "TFDOCS_PLUGIN",
|
||||
MagicCookieValue: "A7U5oTDDJwdL6UKOw6RXATDa86NEo4xLK3rz7QqegT1N4EY66qb6UeAJDSxLwtXH",
|
||||
}
|
||||
|
||||
// formatter is a wrapper to satisfy the interface of go-plugin.
|
||||
type formatter struct {
|
||||
name string
|
||||
version string
|
||||
printer printFunc
|
||||
}
|
||||
|
||||
func newFormatter(name string, version string, printer printFunc) *formatter {
|
||||
return &formatter{
|
||||
name: name,
|
||||
version: version,
|
||||
printer: printer,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *formatter) Name() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f *formatter) Version() string {
|
||||
return f.version
|
||||
}
|
||||
|
||||
func (f *formatter) Execute(args *ExecuteArgs) (string, error) {
|
||||
return f.printer(args.Config, args.Module)
|
||||
}
|
||||
|
||||
// Server returns an RPC server acting as a plugin.
|
||||
func (f *formatter) Server(b *goplugin.MuxBroker) (interface{}, error) {
|
||||
return &Server{impl: f, broker: b}, nil
|
||||
}
|
||||
|
||||
// Client returns an RPC client for the host.
|
||||
func (formatter) Client(b *goplugin.MuxBroker, c *rpc.Client) (interface{}, error) {
|
||||
return &Client{rpcClient: c, broker: b}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
gob.Register(new(types.Bool))
|
||||
gob.Register(new(types.Empty))
|
||||
gob.Register(new(types.List))
|
||||
gob.Register(new(types.Map))
|
||||
gob.Register(new(types.Nil))
|
||||
gob.Register(new(types.Number))
|
||||
gob.Register(new(types.String))
|
||||
}
|
||||
68
plugin/server.go
Normal file
68
plugin/server.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2021 The terraform-docs Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
"github.com/terraform-docs/terraform-docs/terraform"
|
||||
)
|
||||
|
||||
// Server is an RPC Server acting as a plugin.
|
||||
type Server struct {
|
||||
impl *formatter
|
||||
broker *goplugin.MuxBroker
|
||||
}
|
||||
|
||||
type printFunc func(*print.Config, *terraform.Module) (string, error)
|
||||
|
||||
// ServeOpts is an option for serving a plugin.
|
||||
type ServeOpts struct {
|
||||
Name string
|
||||
Version string
|
||||
Printer printFunc
|
||||
}
|
||||
|
||||
// Serve is a wrapper of plugin.Serve. This is entrypoint of all plugins.
|
||||
func Serve(opts *ServeOpts) {
|
||||
goplugin.Serve(&goplugin.ServeConfig{
|
||||
HandshakeConfig: handshakeConfig,
|
||||
Plugins: goplugin.PluginSet{
|
||||
"formatter": newFormatter(opts.Name, opts.Version, opts.Printer),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Name returns the version of the plugin.
|
||||
func (s *Server) Name(args interface{}, resp *string) error {
|
||||
*resp = s.impl.Name()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Version returns the version of the plugin.
|
||||
func (s *Server) Version(args interface{}, resp *string) error {
|
||||
*resp = s.impl.Version()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Execute returns the generated output.
|
||||
func (s *Server) Execute(args *ExecuteArgs, resp *string) error {
|
||||
r, err := s.impl.Execute(args)
|
||||
*resp = r
|
||||
return err
|
||||
}
|
||||
@@ -13,11 +13,9 @@ package terraform
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
)
|
||||
@@ -110,21 +108,3 @@ func (ii inputs) sort(enabled bool, by string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ii inputs) convert() []*terraformsdk.Input {
|
||||
list := []*terraformsdk.Input{}
|
||||
for _, i := range ii {
|
||||
list = append(list, &terraformsdk.Input{
|
||||
Name: i.Name,
|
||||
Type: fmt.Sprintf("%v", i.Type.Raw()),
|
||||
Description: fmt.Sprintf("%v", i.Description.Raw()),
|
||||
Default: i.Default.Raw(),
|
||||
Required: i.Required,
|
||||
Position: terraformsdk.Position{
|
||||
Filename: i.Position.Filename,
|
||||
Line: i.Position.Line,
|
||||
},
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ package terraform
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
)
|
||||
|
||||
// Module represents a Terraform module. It consists of
|
||||
@@ -72,19 +70,3 @@ func (m *Module) HasRequirements() bool {
|
||||
func (m *Module) HasResources() bool {
|
||||
return len(m.Resources) > 0
|
||||
}
|
||||
|
||||
// Convert internal Module to its equivalent in plugin-sdk
|
||||
func (m *Module) Convert() terraformsdk.Module {
|
||||
return terraformsdk.NewModule(
|
||||
terraformsdk.WithHeader(m.Header),
|
||||
terraformsdk.WithFooter(m.Footer),
|
||||
terraformsdk.WithInputs(inputs(m.Inputs).convert()),
|
||||
terraformsdk.WithModuleCalls(modulecalls(m.ModuleCalls).convert()),
|
||||
terraformsdk.WithOutputs(outputs(m.Outputs).convert()),
|
||||
terraformsdk.WithProviders(providers(m.Providers).convert()),
|
||||
terraformsdk.WithRequirements(requirements(m.Requirements).convert()),
|
||||
terraformsdk.WithResources(resources(m.Resources).convert()),
|
||||
terraformsdk.WithRequiredInputs(inputs(m.RequiredInputs).convert()),
|
||||
terraformsdk.WithOptionalInputs(inputs(m.OptionalInputs).convert()),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
)
|
||||
@@ -73,19 +72,3 @@ func (mm modulecalls) sort(enabled bool, by string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mm modulecalls) convert() []*terraformsdk.ModuleCall {
|
||||
list := []*terraformsdk.ModuleCall{}
|
||||
for _, m := range mm {
|
||||
list = append(list, &terraformsdk.ModuleCall{
|
||||
Name: m.Name,
|
||||
Source: m.Source,
|
||||
Version: m.Version,
|
||||
Position: terraformsdk.Position{
|
||||
Filename: m.Position.Filename,
|
||||
Line: m.Position.Line,
|
||||
},
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
)
|
||||
|
||||
@@ -154,21 +152,3 @@ func (oo outputs) sort(enabled bool, by string) { //nolint:unparam
|
||||
sortOutputsByName(oo)
|
||||
}
|
||||
}
|
||||
|
||||
func (oo outputs) convert() []*terraformsdk.Output {
|
||||
list := []*terraformsdk.Output{}
|
||||
for _, o := range oo {
|
||||
list = append(list, &terraformsdk.Output{
|
||||
Name: o.Name,
|
||||
Description: fmt.Sprintf("%v", o.Description.Raw()),
|
||||
Value: nil,
|
||||
Sensitive: o.Sensitive,
|
||||
Position: terraformsdk.Position{
|
||||
Filename: o.Position.Filename,
|
||||
Line: o.Position.Line,
|
||||
},
|
||||
ShowValue: o.ShowValue,
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
)
|
||||
|
||||
@@ -62,19 +61,3 @@ func (pp providers) sort(enabled bool, by string) { //nolint:unparam
|
||||
sortProvidersByName(pp)
|
||||
}
|
||||
}
|
||||
|
||||
func (pp providers) convert() []*terraformsdk.Provider {
|
||||
list := []*terraformsdk.Provider{}
|
||||
for _, p := range pp {
|
||||
list = append(list, &terraformsdk.Provider{
|
||||
Name: p.Name,
|
||||
Alias: fmt.Sprintf("%v", p.Alias.Raw()),
|
||||
Version: fmt.Sprintf("%v", p.Version.Raw()),
|
||||
Position: terraformsdk.Position{
|
||||
Filename: p.Position.Filename,
|
||||
Line: p.Position.Line,
|
||||
},
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ the root directory of this source tree.
|
||||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
)
|
||||
|
||||
@@ -22,16 +19,3 @@ type Requirement struct {
|
||||
Name string `json:"name" toml:"name" xml:"name" yaml:"name"`
|
||||
Version types.String `json:"version" toml:"version" xml:"version" yaml:"version"`
|
||||
}
|
||||
|
||||
type requirements []*Requirement
|
||||
|
||||
func (rr requirements) convert() []*terraformsdk.Requirement {
|
||||
list := []*terraformsdk.Requirement{}
|
||||
for _, r := range rr {
|
||||
list = append(list, &terraformsdk.Requirement{
|
||||
Name: r.Name,
|
||||
Version: fmt.Sprintf("%v", r.Version.Raw()),
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
terraformsdk "github.com/terraform-docs/plugin-sdk/terraform"
|
||||
"github.com/terraform-docs/terraform-docs/internal/types"
|
||||
)
|
||||
|
||||
@@ -87,23 +86,3 @@ func (rr resources) sort(enabled bool, by string) { //nolint:unparam
|
||||
// always sort by type
|
||||
sortResourcesByType(rr)
|
||||
}
|
||||
|
||||
func (rr resources) convert() []*terraformsdk.Resource {
|
||||
list := []*terraformsdk.Resource{}
|
||||
for _, r := range rr {
|
||||
list = append(list, &terraformsdk.Resource{
|
||||
Type: r.Type,
|
||||
Name: r.Name,
|
||||
ProviderName: r.ProviderName,
|
||||
ProviderSource: r.ProviderSource,
|
||||
Mode: r.Mode,
|
||||
Version: fmt.Sprintf("%v", r.Version.Raw()),
|
||||
Position: terraformsdk.Position{
|
||||
Filename: r.Position.Filename,
|
||||
Line: r.Position.Line,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -30,24 +30,6 @@ func TestResourceSpec(t *testing.T) {
|
||||
}
|
||||
assert.Equal("tls_private_key.baz", resource.Spec())
|
||||
}
|
||||
func TestPluginSdkConversion(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
resource := Resource{
|
||||
Type: "private_key",
|
||||
Name: "baz",
|
||||
ProviderName: "tls",
|
||||
ProviderSource: "hashicorp/tls",
|
||||
Mode: "managed",
|
||||
Version: types.String("latest"),
|
||||
}
|
||||
sdkResource := resources{&resource}.convert()[0]
|
||||
assert.Equal(resource.Type, sdkResource.Type)
|
||||
assert.Equal(resource.Name, sdkResource.Name)
|
||||
assert.Equal(resource.ProviderName, sdkResource.ProviderName)
|
||||
assert.Equal(resource.ProviderSource, sdkResource.ProviderSource)
|
||||
assert.Equal(resource.Mode, sdkResource.Mode)
|
||||
assert.Equal(resource.Version, types.String(sdkResource.Version))
|
||||
}
|
||||
|
||||
func TestResourceMode(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
|
||||
Reference in New Issue
Block a user