-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- extract params into own struct for better usability
- extracted all parameter parsing into an explicit package and ensured the precedence
- Loading branch information
1 parent
6aaa2c4
commit 5837518
Showing
26 changed files
with
533 additions
and
392 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package param_parsing | ||
|
||
import "os" | ||
|
||
func GetParamsFromEnvironment(params Params) Params { | ||
params.Version = os.Getenv("TF_VERSION") | ||
return params | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestGetParamsFromEnvironment_version_from_env(t *testing.T) { | ||
var params Params | ||
expected := "1.0.0_from_env" | ||
_ = os.Setenv("TF_VERSION", expected) | ||
params = initParams(params) | ||
params = GetParamsFromEnvironment(params) | ||
if params.Version != expected { | ||
t.Error("Determined version is not matchching. Got " + params.Version + ", expected " + expected) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"fmt" | ||
"github.com/pborman/getopt" | ||
"github.com/warrensbox/terraform-switcher/lib" | ||
"os" | ||
) | ||
|
||
type Params struct { | ||
CustomBinaryPath string | ||
ListAllFlag bool | ||
LatestPre string | ||
ShowLatestPre string | ||
LatestStable string | ||
ShowLatestStable string | ||
LatestFlag bool | ||
ShowLatestFlag bool | ||
MirrorURL string | ||
ChDirPath string | ||
VersionFlag bool | ||
DefaultVersion string | ||
HelpFlag bool | ||
Version string | ||
} | ||
|
||
const ( | ||
defaultMirror = "https://releases.hashicorp.com/terraform" | ||
defaultLatest = "" | ||
) | ||
|
||
func GetParameters() Params { | ||
var params Params | ||
params = initParams(params) | ||
|
||
getopt.StringVarLong(¶ms.ChDirPath, "chdir", 'c', "Switch to a different working directory before executing the given command. Ex: tfswitch --chdir terraform_project will run tfswitch in the terraform_project directory") | ||
getopt.BoolVarLong(¶ms.VersionFlag, "version", 'v', "Displays the version of tfswitch") | ||
getopt.BoolVarLong(¶ms.HelpFlag, "help", 'h', "Displays help message") | ||
getopt.StringVarLong(¶ms.MirrorURL, "mirror", 'm', "Install from a remote API other than the default. Default: "+defaultMirror) | ||
getopt.StringVarLong(¶ms.CustomBinaryPath, "bin", 'b', "Custom binary path. Ex: tfswitch -b "+lib.ConvertExecutableExt("/Users/username/bin/terraform")) | ||
getopt.StringVarLong(¶ms.LatestPre, "latest-pre", 'p', "Latest pre-release implicit version. Ex: tfswitch --latest-pre 0.13 downloads 0.13.0-rc1 (latest)") | ||
getopt.StringVarLong(¶ms.ShowLatestPre, "show-latest-pre", 'P', "Show latest pre-release implicit version. Ex: tfswitch --show-latest-pre 0.13 prints 0.13.0-rc1 (latest)") | ||
getopt.StringVarLong(¶ms.LatestStable, "latest-stable", 's', "Latest implicit version based on a constraint. Ex: tfswitch --latest-stable 0.13.0 downloads 0.13.7 and 0.13 downloads 0.15.5 (latest)") | ||
getopt.StringVarLong(¶ms.ShowLatestStable, "show-latest-stable", 'S', "Show latest implicit version. Ex: tfswitch --show-latest-stable 0.13 prints 0.13.7 (latest)") | ||
getopt.StringVarLong(¶ms.DefaultVersion, "default", 'd', "Default to this version in case no other versions could be detected. Ex: tfswitch --default 1.2.4") | ||
getopt.BoolVarLong(¶ms.ListAllFlag, "list-all", 'l', "List all versions of terraform - including beta and rc") | ||
getopt.BoolVarLong(¶ms.LatestFlag, "latest", 'u', "Get latest stable version") | ||
getopt.BoolVarLong(¶ms.ShowLatestFlag, "show-latest", 'U', "Show latest stable version") | ||
|
||
// Parse the command line parameters to fetch stuff like chdir | ||
getopt.Parse() | ||
|
||
// Read configuration files in increasing precedence (least precedence first) | ||
params = GetParamsFromEnvironment(params) | ||
params = GetVersionFromTerragrunt(params) | ||
params = GetVersionFromVersionsTF(params) | ||
params = GetParamsFromTerraformVersion(params) | ||
params = GetParamsFromTfSwitch(params) | ||
params = GetParamsTOML(params) | ||
|
||
// Parse again to overwrite anything that might by defined on the cli AND in any config file (CLI always wins) | ||
getopt.Parse() | ||
args := getopt.Args() | ||
if len(args) == 1 { | ||
/* version provided on command line as arg */ | ||
params.Version = args[0] | ||
} | ||
return params | ||
} | ||
|
||
func getCommandlineParams(params Params) { | ||
getopt.StringVarLong(¶ms.CustomBinaryPath, "bin", 'b', "Custom binary path. Ex: tfswitch -b "+lib.ConvertExecutableExt("/Users/username/bin/terraform")) | ||
getopt.StringVarLong(¶ms.LatestPre, "latest-pre", 'p', "Latest pre-release implicit version. Ex: tfswitch --latest-pre 0.13 downloads 0.13.0-rc1 (latest)") | ||
getopt.StringVarLong(¶ms.ShowLatestPre, "show-latest-pre", 'P', "Show latest pre-release implicit version. Ex: tfswitch --show-latest-pre 0.13 prints 0.13.0-rc1 (latest)") | ||
getopt.StringVarLong(¶ms.LatestStable, "latest-stable", 's', "Latest implicit version based on a constraint. Ex: tfswitch --latest-stable 0.13.0 downloads 0.13.7 and 0.13 downloads 0.15.5 (latest)") | ||
getopt.StringVarLong(¶ms.ShowLatestStable, "show-latest-stable", 'S', "Show latest implicit version. Ex: tfswitch --show-latest-stable 0.13 prints 0.13.7 (latest)") | ||
getopt.StringVarLong(¶ms.DefaultVersion, "default", 'd', "Default to this version in case no other versions could be detected. Ex: tfswitch --default 1.2.4") | ||
|
||
getopt.BoolVarLong(¶ms.ListAllFlag, "list-all", 'l', "List all versions of terraform - including beta and rc") | ||
getopt.BoolVarLong(¶ms.LatestFlag, "latest", 'u', "Get latest stable version") | ||
getopt.BoolVarLong(¶ms.ShowLatestFlag, "show-latest", 'U', "Show latest stable version") | ||
} | ||
|
||
func initParams(params Params) Params { | ||
params.ChDirPath = lib.GetCurrentDirectory() | ||
params.CustomBinaryPath = lib.ConvertExecutableExt(lib.GetDefaultBin()) | ||
params.MirrorURL = defaultMirror | ||
params.LatestPre = defaultLatest | ||
params.ShowLatestPre = defaultLatest | ||
params.LatestStable = defaultLatest | ||
params.ShowLatestStable = defaultLatest | ||
params.MirrorURL = defaultMirror | ||
params.DefaultVersion = defaultLatest | ||
params.ListAllFlag = false | ||
params.LatestFlag = false | ||
params.ShowLatestFlag = false | ||
params.VersionFlag = false | ||
params.HelpFlag = false | ||
return params | ||
} | ||
|
||
func UsageMessage() { | ||
fmt.Print("\n\n") | ||
getopt.PrintUsage(os.Stderr) | ||
fmt.Println("Supply the terraform version as an argument, or choose from a menu") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"github.com/pborman/getopt" | ||
"os" | ||
"testing" | ||
) | ||
|
||
func TestGetParameters_version_from_args(t *testing.T) { | ||
expected := "0.13args" | ||
os.Args = []string{"cmd", expected} | ||
params := GetParameters() | ||
actual := params.Version | ||
if actual != expected { | ||
t.Error("Version Param was not parsed correctly. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
t.Cleanup(func() { | ||
getopt.CommandLine = getopt.New() | ||
}) | ||
} | ||
func TestGetParameters_params_are_overridden_by_toml_file(t *testing.T) { | ||
t.Cleanup(func() { | ||
getopt.CommandLine = getopt.New() | ||
}) | ||
expected := "../../test-data/test_tfswitchtoml" | ||
os.Args = []string{"cmd", "--chdir=" + expected} | ||
params := GetParameters() | ||
actual := params.ChDirPath | ||
if actual != expected { | ||
t.Error("ChDir Param was not parsed correctly. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
|
||
expected = "/usr/local/bin/terraform_from_toml" | ||
actual = params.CustomBinaryPath | ||
if actual != expected { | ||
t.Error("CustomBinaryPath Param was not as expected. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
expected = "0.11.3_toml" | ||
actual = params.Version | ||
if actual != expected { | ||
t.Error("Version Param was not as expected. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
} | ||
func TestGetParameters_toml_params_are_overridden_by_cli(t *testing.T) { | ||
t.Cleanup(func() { | ||
getopt.CommandLine = getopt.New() | ||
}) | ||
expected := "../../test-data/test_tfswitchtoml" | ||
os.Args = []string{"cmd", "--chdir=" + expected, "--bin=/usr/test/bin"} | ||
params := GetParameters() | ||
actual := params.ChDirPath | ||
if actual != expected { | ||
t.Error("ChDir Param was not parsed correctly. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
|
||
expected = "/usr/test/bin" | ||
actual = params.CustomBinaryPath | ||
if actual != expected { | ||
t.Error("CustomBinaryPath Param was not as expected. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
expected = "0.11.3_toml" | ||
actual = params.Version | ||
if actual != expected { | ||
t.Error("Version Param was not as expected. Actual: " + actual + ", Expected: " + expected) | ||
} | ||
} | ||
|
||
func TestGetParameters_check_config_precedence(t *testing.T) { | ||
t.Cleanup(func() { | ||
getopt.CommandLine = getopt.New() | ||
}) | ||
os.Args = []string{"cmd", "--chdir=../../test-data/test_precedence"} | ||
parameters := GetParameters() | ||
expected := "0.11.3" | ||
if parameters.Version != expected { | ||
t.Error("Version Param was not as expected. Actual: " + parameters.Version + ", Expected: " + expected) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"fmt" | ||
"github.com/warrensbox/terraform-switcher/lib" | ||
"log" | ||
"os" | ||
"strings" | ||
) | ||
|
||
func GetParamsFromTerraformVersion(params Params) Params { | ||
filePath := params.ChDirPath + "/.terraform-version" | ||
if lib.CheckFileExist(filePath) { | ||
fmt.Printf("Reading configuration from %s\n", filePath) | ||
content, err := os.ReadFile(filePath) | ||
if err != nil { | ||
log.Fatal("Could not read file content", filePath, err) | ||
} | ||
params.Version = strings.TrimSpace(string(content)) | ||
} | ||
return params | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
func TestGetParamsFromTerraformVersion(t *testing.T) { | ||
var params Params | ||
params.ChDirPath = "../../test-data/test_terraform-version" | ||
params = GetParamsFromTerraformVersion(params) | ||
expected := "0.11.0_tfversion" | ||
if params.Version != expected { | ||
fmt.Printf("Version from .terraform-version not read correctly. Got: %v, Expect: %v", params.Version, expected) | ||
t.Errorf("Version from .terraform-version not read correctly. Got: %v, Expect: %v", params.Version, expected) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hashicorp/hcl2/gohcl" | ||
"github.com/hashicorp/hcl2/hclparse" | ||
"github.com/warrensbox/terraform-switcher/lib" | ||
"log" | ||
) | ||
|
||
type terragruntVersionConstraints struct { | ||
TerraformVersionConstraint string `hcl:"terraform_version_constraint"` | ||
} | ||
|
||
func GetVersionFromTerragrunt(params Params) Params { | ||
filePath := params.ChDirPath + "/terragrunt.hcl" | ||
if lib.CheckFileExist(filePath) { | ||
fmt.Printf("Reading configuration from %s\n", filePath) | ||
parser := hclparse.NewParser() | ||
hclFile, diagnostics := parser.ParseHCLFile(filePath) | ||
if diagnostics.HasErrors() { | ||
log.Fatal("Unable to parse HCL file", filePath) | ||
} | ||
var versionFromTerragrunt terragruntVersionConstraints | ||
diagnostics = gohcl.DecodeBody(hclFile.Body, nil, &versionFromTerragrunt) | ||
if diagnostics.HasErrors() { | ||
log.Fatal("Could not decode body of HCL file.") | ||
} | ||
version, err := lib.GetSemver(versionFromTerragrunt.TerraformVersionConstraint, params.MirrorURL) | ||
if err != nil { | ||
log.Fatal("Could not determine semantic version") | ||
} | ||
params.Version = version | ||
} | ||
return params | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"github.com/hashicorp/go-version" | ||
"testing" | ||
) | ||
|
||
func TestGetVersionFromTerragrunt(t *testing.T) { | ||
var params Params | ||
params = initParams(params) | ||
params.ChDirPath = "../../test-data/test_terragrunt_hcl" | ||
params = GetVersionFromTerragrunt(params) | ||
v1, _ := version.NewVersion("0.13") | ||
v2, _ := version.NewVersion("0.14") | ||
actualVersion, _ := version.NewVersion(params.Version) | ||
if !actualVersion.GreaterThanOrEqual(v1) || !actualVersion.LessThan(v2) { | ||
t.Error("Determined version is not between 0.13 and 0.14") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"fmt" | ||
"github.com/warrensbox/terraform-switcher/lib" | ||
"log" | ||
"os" | ||
"strings" | ||
) | ||
|
||
func GetParamsFromTfSwitch(params Params) Params { | ||
filePath := params.ChDirPath + "/.tfswitchrc" | ||
if lib.CheckFileExist(filePath) { | ||
fmt.Printf("Reading configuration from %s\n", filePath) | ||
content, err := os.ReadFile(filePath) | ||
if err != nil { | ||
log.Fatal("Could not read file content", filePath, err) | ||
} | ||
params.Version = strings.TrimSpace(string(content)) | ||
} | ||
return params | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package param_parsing | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestGetParamsFromTfSwitch(t *testing.T) { | ||
var params Params | ||
params.ChDirPath = "../../test-data/test_tfswitchrc" | ||
params = GetParamsFromTfSwitch(params) | ||
expected := "0.10.5_tfswitch" | ||
if params.Version != expected { | ||
t.Error("Version from tfswitchrc not read correctly. Actual: " + params.Version + ", Expected: " + expected) | ||
} | ||
} |
Oops, something went wrong.