Ignore extracting versions from terraform.lock.hcl

New flag, `--lockfile`, is added to control whether ignore reading
.terraform.lock.hcl file in an attempt to extract the exact version of
provider being used or not. Default is true.

If set to true, exact version of provider available in lock file at the
time of execution will be extracted. If set to false, the version in .tf
file will be used (either exact, or a constrained version: >=, ~>, ...)

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
Khosrow Moossavi
2021-06-18 18:27:21 -04:00
parent 4d9fc6ca93
commit 5256426650
21 changed files with 66 additions and 17 deletions

View File

@@ -73,6 +73,8 @@ func NewCommand() *cobra.Command {
cmd.PersistentFlags().StringVar(&config.HeaderFrom, "header-from", "main.tf", "relative path of a file to read header from")
cmd.PersistentFlags().StringVar(&config.FooterFrom, "footer-from", "", "relative path of a file to read footer from (default \"\")")
cmd.PersistentFlags().BoolVar(&config.Settings.LockFile, "lockfile", true, "read .terraform.lock.hcl if exist")
cmd.PersistentFlags().BoolVar(&config.OutputValues.Enabled, "output-values", false, "inject output values into outputs (default false)")
cmd.PersistentFlags().StringVar(&config.OutputValues.From, "output-values-from", "", "inject output values from file into outputs (default \"\")")

View File

@@ -32,6 +32,7 @@ terraform-docs asciidoc document [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -32,6 +32,7 @@ terraform-docs asciidoc table [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -35,6 +35,7 @@ terraform-docs asciidoc [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -30,6 +30,7 @@ terraform-docs json [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -34,6 +34,7 @@ terraform-docs markdown document [PATH] [flags]
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--html use HTML tags in genereted output (default true)
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -34,6 +34,7 @@ terraform-docs markdown table [PATH] [flags]
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--html use HTML tags in genereted output (default true)
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -37,6 +37,7 @@ terraform-docs markdown [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -30,6 +30,7 @@ terraform-docs pretty [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -24,6 +24,7 @@ terraform-docs [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
-h, --help help for terraform-docs
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -30,6 +30,7 @@ terraform-docs tfvars hcl [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -29,6 +29,7 @@ terraform-docs tfvars json [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -25,6 +25,7 @@ Generate terraform.tfvars of inputs.
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -29,6 +29,7 @@ terraform-docs toml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -29,6 +29,7 @@ terraform-docs xml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -29,6 +29,7 @@ terraform-docs yaml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--lockfile read .terraform.lock.hcl if exist (default true)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")

View File

@@ -98,6 +98,7 @@ settings:
escape: true
html: true
indent: 2
lockfile: true
required: true
sensitive: true
type: true

View File

@@ -373,6 +373,7 @@ type settings struct {
Escape bool `mapstructure:"escape"`
HTML bool `mapstructure:"html"`
Indent int `mapstructure:"indent"`
LockFile bool `mapstructure:"lockfile"`
Required bool `mapstructure:"required"`
Sensitive bool `mapstructure:"sensitive"`
Type bool `mapstructure:"type"`
@@ -387,6 +388,7 @@ func defaultSettings() settings {
Escape: true,
HTML: true,
Indent: 2,
LockFile: true,
Required: true,
Sensitive: true,
Type: true,
@@ -469,6 +471,9 @@ func (c *Config) extract() (*print.Settings, *terraform.Options) {
options.ShowFooter = settings.ShowFooter
options.FooterFromFile = c.FooterFrom
// terraform.lock.hcl file
options.UseLockFile = c.Settings.LockFile
// sections
settings.ShowDataSources = c.Sections.dataSources
settings.ShowInputs = c.Sections.inputs

View File

@@ -411,14 +411,17 @@ func loadProviders(tfmodule *tfconfig.Module, options *Options) []*Provider {
Provider []provider `hcl:"provider,block"`
}
lock := make(map[string]provider)
var lf lockfile
filename := filepath.Join(options.Path, ".terraform.lock.hcl")
if err := hclsimple.DecodeFile(filename, nil, &lf); err == nil {
for i := range lf.Provider {
segments := strings.Split(lf.Provider[i].Name, "/")
name := segments[len(segments)-1]
lock[name] = lf.Provider[i]
if options.UseLockFile {
var lf lockfile
filename := filepath.Join(options.Path, ".terraform.lock.hcl")
if err := hclsimple.DecodeFile(filename, nil, &lf); err == nil {
for i := range lf.Provider {
segments := strings.Split(lf.Provider[i].Name, "/")
name := segments[len(segments)-1]
lock[name] = lf.Provider[i]
}
}
}

View File

@@ -13,6 +13,7 @@ package terraform
import (
"io/ioutil"
"path/filepath"
"sort"
"testing"
"github.com/stretchr/testify/assert"
@@ -665,32 +666,43 @@ func TestLoadOutputsValues(t *testing.T) {
func TestLoadProviders(t *testing.T) {
type expected struct {
providers int
providers []string
}
tests := []struct {
name string
path string
lockfile bool
expected expected
}{
{
name: "load module providers from path",
path: "full-example",
name: "load module providers from path",
path: "full-example",
lockfile: false,
expected: expected{
providers: 3,
providers: []string{"aws->= 2.15.0", "null-", "tls-"},
},
},
{
name: "load module providers from path",
path: "with-lock-file",
name: "load module providers from path",
path: "with-lock-file",
lockfile: true,
expected: expected{
providers: 3,
providers: []string{"aws-3.42.0", "null-3.1.0", "tls-3.1.0"},
},
},
{
name: "load module providers from path",
path: "with-lock-file",
lockfile: false,
expected: expected{
providers: []string{"aws->= 2.15.0", "null-", "tls-"},
},
},
{
name: "load module providers from path",
path: "no-providers",
expected: expected{
providers: 0,
providers: []string{},
},
},
}
@@ -698,12 +710,21 @@ func TestLoadProviders(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
options, _ := NewOptions().With(&Options{
Path: tt.path,
Path: filepath.Join("testdata", tt.path),
})
options.UseLockFile = tt.lockfile
module, _ := loadModule(filepath.Join("testdata", tt.path))
providers := loadProviders(module, options)
assert.Equal(tt.expected.providers, len(providers))
actual := []string{}
for _, p := range providers {
actual = append(actual, p.FullName()+"-"+string(p.Version))
providers[0].FullName()
}
sort.Strings(actual)
assert.Equal(tt.expected.providers, actual)
})
}
}

View File

@@ -31,6 +31,7 @@ type Options struct {
HeaderFromFile string
ShowFooter bool
FooterFromFile string
UseLockFile bool
SortBy *SortBy
OutputValues bool
OutputValuesPath string
@@ -44,6 +45,7 @@ func NewOptions() *Options {
HeaderFromFile: "main.tf",
ShowFooter: false,
FooterFromFile: "",
UseLockFile: true,
SortBy: &SortBy{Name: false, Required: false, Type: false},
OutputValues: false,
OutputValuesPath: "",