Skip to content

Commit

Permalink
added test files
Browse files Browse the repository at this point in the history
  • Loading branch information
warrensbox committed Jun 22, 2022
1 parent 7971f22 commit 7c0ad45
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 33 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ clean:

.PHONY: test
test: $(EXE)
mkdir -p build
mv $(EXE) build
go test -v ./...
find ./test-data/* -type d -print0 | while read -r -d $'\0' TEST_PATH; do ./build/tgswitch -c "${TEST_PATH}" || exit 1; done;

.PHONY: install
install: $(EXE)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/warrensbox/tgswitch
go 1.16

require (
github.com/hashicorp/go-version v1.5.0 // indirect
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80 // indirect
github.com/manifoldco/promptui v0.9.0
github.com/mitchellh/go-homedir v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
Expand Down
23 changes: 19 additions & 4 deletions lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ func ValidVersionFormat(version string) bool {
//Install : Install the provided version in the argument
func Install(tgversion string, usrBinPath string, mirrorURL string) string {

println("tgversion", tgversion)
println("usrBinPath", usrBinPath)
println("mirrorURL", mirrorURL)
/* Check to see if user has permission to the default bin location which is "/usr/local/bin/terragrunt"
* If user does not have permission to default bin location, proceed to create $HOME/bin and install the tfswitch there
* Inform user that they dont have permission to default location, therefore tfswitch was installed in $HOME/bin
Expand All @@ -184,13 +187,25 @@ func Install(tgversion string, usrBinPath string, mirrorURL string) string {
goarch := runtime.GOARCH
goos := runtime.GOOS

installFileVersionPath := ConvertExecutableExt(filepath.Join(installLocation, installVersion+tgversion))

/* check if selected version already downloaded */
installFileVersionPath := ConvertExecutableExt(filepath.Join(installLocation, installVersion+tgversion))
fileExist := CheckFileExist(installLocation + installVersion + tgversion)

/* if selected version already exist, */
if fileExist {
installLocation := ChangeSymlink(binPath, tgversion)
return installLocation

/* remove current symlink if exist*/
symlinkExist := CheckSymlink(binPath)

if symlinkExist {
RemoveSymlink(binPath)
}

/* set symlink to desired version */
CreateSymlink(installFileVersionPath, binPath)
fmt.Printf("Switched terragrunt to version %q \n", tgversion)
AddRecent(tgversion) //add to recent file for faster lookup
os.Exit(0)
}

//if does not have slash - append slash
Expand Down
5 changes: 0 additions & 5 deletions lib/list_versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package lib

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
Expand All @@ -27,10 +26,6 @@ func VersionExist(val interface{}, array interface{}) (exists bool) {
}
}

if !exists {
fmt.Println("Requested version does not exist")
}

return exists
}

Expand Down
55 changes: 55 additions & 0 deletions lib/semver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package lib

import (
"fmt"
"sort"

semver "github.com/hashicorp/go-version"
)

// GetSemver : returns version that will be installed based on server constaint provided
func GetSemver(tgconstraint *string, proxyUrl string) (string, error) {

tglist := GetAppList(proxyUrl) //get list of versions
fmt.Printf("Reading required version from constraint: %s\n", *tgconstraint)
tfversion, err := SemVerParser(tgconstraint, tglist)
return tfversion, err
}

// ValidateSemVer : Goes through the list of terragrunt version, return a valid tf version for contraint provided
func SemVerParser(tfconstraint *string, tflist []string) (string, error) {
tfversion := ""
constraints, err := semver.NewConstraint(*tfconstraint) //NewConstraint returns a Constraints instance that a Version instance can be checked against
if err != nil {
return "", fmt.Errorf("error parsing constraint: %s", err)
}
versions := make([]*semver.Version, len(tflist))
//put tfversion into semver object
for i, tfvals := range tflist {
version, err := semver.NewVersion(tfvals) //NewVersion parses a given version and returns an instance of Version or an error if unable to parse the version.
if err != nil {
return "", fmt.Errorf("error parsing constraint: %s", err)
}
versions[i] = version
}

sort.Sort(sort.Reverse(semver.Collection(versions)))

for _, element := range versions {
if constraints.Check(element) { // Validate a version against a constraint
tfversion = element.String()
fmt.Printf("Matched version: %s\n", tfversion)
if ValidVersionFormat(tfversion) { //check if version format is correct
return tfversion, nil
}
}
}

PrintInvalidTFVersion()
return "", fmt.Errorf("error parsing constraint: %s", *tfconstraint)
}

// Print invalid TF version
func PrintInvalidTFVersion() {
fmt.Println("Version does not exist or invalid terraform version format.\n Format should be #.#.# or #.#.#-@# where # are numbers and @ are word characters.\n For example, 0.11.7 and 0.11.9-beta1 are valid versions")
}
19 changes: 9 additions & 10 deletions lib/symlink.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package lib

import (
"fmt"
"log"
"os"
)

//CreateSymlink : create symlink
//CreateSymlink : create symlink
func CreateSymlink(cwd string, dir string) {

println("cwd", cwd)
println("dir", dir)
err := os.Symlink(cwd, dir)
if err != nil {
log.Fatalf(`
Unable to create new symlink.
Maybe symlink already exist. Try removing existing symlink manually.
Try running "unlink" to remove existing symlink.
If error persist, you may not have the permission to create a symlink at %s.
If error persist, you may not have the permission to create a symlink at %s
Error: %s
`, dir, err)
os.Exit(1)
Expand Down Expand Up @@ -67,18 +67,17 @@ func CheckSymlink(symlinkPath string) bool {
}

// ChangeSymlink : move symlink to existing binary
func ChangeSymlink(installedBinPath string, appversion string) string {
func ChangeSymlink(binVersionPath string, binPath string) {

installLocation = GetInstallLocation() //get installation location - this is where we will put our terragrunt binary file
binPath = InstallableBinLocation(binPath)

/* remove current symlink if exist*/
symlinkExist := CheckSymlink(installedBinPath)
symlinkExist := CheckSymlink(binPath)
if symlinkExist {
RemoveSymlink(installedBinPath)
RemoveSymlink(binPath)
}

/* set symlink to desired version */
CreateSymlink(installLocation+installVersion+appversion, installedBinPath)
fmt.Printf("Switched terragrunt to version %q \n", appversion)
return installLocation
CreateSymlink(binVersionPath, binPath)

}
63 changes: 51 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,20 @@ func main() {
TOMLConfigFile := filepath.Join(*chDirPath, tomlFilename) //settings for .tgswitch.toml file in current directory (option to specify bin directory)
HomeTOMLConfigFile := filepath.Join(homedir, tomlFilename) //settings for .tgswitch.toml file in home directory (option to specify bin directory)
RCFile := filepath.Join(*chDirPath, rcFilename) //settings for .tgswitchrc file in current directory (backward compatible purpose)
TFVersionFile := filepath.Join(*chDirPath, tgvFilename) //settings for .terragrunt-version file in current directory (tfenv compatible)
TGVersionFile := filepath.Join(*chDirPath, tgvFilename) //settings for .terragrunt-version file in current directory (tfenv compatible)
TGHACLFile := filepath.Join(*chDirPath, tgHclFilename) //settings for terragrunt.hcl file in current directory
switch {
case *versionFlag:
fmt.Printf("\nVersion: %v\n", version)
case *helpFlag:
usageMessage()
/* Checks if the .tgswitch.toml file exist in home or current directory
* This block checks to see if the tgswitch toml file is provided in the current path.
* If the .tgswitch.toml file exist, it has a higher precedence than the .tgswitchrc file
* You can specify the custom binary path and the version you desire
* If you provide a custom binary path with the -b option, this will override the bin value in the toml file
* If you provide a version on the command line, this will override the version value in the toml file
*/
case lib.FileExists(TOMLConfigFile) || lib.FileExists(HomeTOMLConfigFile):
version := ""
binPath := *custBinPath
Expand All @@ -82,7 +89,7 @@ func main() {
} else { // else read from toml from home directory
version, binPath = GetParamsTOML(binPath, homedir)
}
fmt.Println("version", version)

/* GIVEN A TOML FILE, */
switch {
case len(args) == 1:
Expand Down Expand Up @@ -111,20 +118,24 @@ func main() {
case lib.FileExists(RCFile) && len(args) == 0:
lib.ReadingFileMsg(rcFilename)
tgversion := lib.RetrieveFileContents(RCFile)
installVersion(tgversion, custBinPath)
installVersion(tgversion, &binPath)
/* if .terragrunt-version file found (IN ADDITION TO A TOML FILE) */
case lib.FileExists(TFVersionFile) && len(args) == 0:
lib.ReadingFileMsg(rcFilename)
tgversion := lib.RetrieveFileContents(RCFile)
installVersion(tgversion, custBinPath)
case lib.FileExists(TGVersionFile) && len(args) == 0:
lib.ReadingFileMsg(TGVersionFile)
tgversion := lib.RetrieveFileContents(TGVersionFile)
println("version", tgversion)
println("&binPath", string(binPath))
installVersion(tgversion, &binPath)
/* if Terraform Version environment variable is set (IN ADDITION TO A TOML FILE)*/
case checkTGEnvExist() && len(args) == 0 && version == "":

tgversion := os.Getenv("TG_VERSION")
fmt.Printf("Terragrunt version environment variable: %s\n", tgversion)
installVersion(tgversion, &binPath)
/* if terragrunt.hcl file found (IN ADDITION TO A TOML FILE) */
case lib.FileExists(TGHACLFile) && checkVersionDefinedHCL(&TGHACLFile) && len(args) == 0:

installTGHclFile(&TGHACLFile, binPath, proxyUrl)
case version != "":
lib.Install(version, *custBinPath, terragruntURL)
lib.Install(version, binPath, terragruntURL)
default:
installFromList(&binPath)
}
Expand Down Expand Up @@ -153,10 +164,10 @@ func main() {
os.Exit(1)
}

} else if _, err := os.Stat(TFVersionFile); err == nil && len(args) == 0 {
} else if _, err := os.Stat(TGVersionFile); err == nil && len(args) == 0 {
fmt.Printf("Reading required terragrunt version %s \n", tgvFilename)

fileContents, err := ioutil.ReadFile(TFVersionFile)
fileContents, err := ioutil.ReadFile(TGVersionFile)
if err != nil {
fmt.Printf("Failed to read %s file. Follow the README.md instructions for setup. https://github.com/warrensbox/tgswitch/blob/master/README.md\n", tgvFilename)
fmt.Printf("Error: %s\n", err)
Expand Down Expand Up @@ -282,6 +293,8 @@ func installVersion(arg string, custBinPath *string) {
installFileVersionPath := lib.ConvertExecutableExt(filepath.Join(installLocation, versionPrefix+requestedVersion))
recentDownloadFile := lib.CheckFileExist(installFileVersionPath)
if recentDownloadFile {
println(string(*custBinPath))
println(installFileVersionPath)
lib.ChangeSymlink(installFileVersionPath, *custBinPath)
fmt.Printf("Switched terraform to version %q \n", requestedVersion)
lib.AddRecent(requestedVersion) //add to recent file for faster lookup
Expand Down Expand Up @@ -311,6 +324,32 @@ func checkTGEnvExist() bool {
return os.Getenv("TG_VERSION") != ""
}

// install using a version constraint
func installFromConstraint(tgconstraint *string, custBinPath, mirrorURL string) {

tgversion, err := lib.GetSemver(tgconstraint, mirrorURL)
if err == nil {
lib.Install(tgversion, custBinPath, mirrorURL)
}
fmt.Println(err)
fmt.Println("No version found to match constraint. Follow the README.md instructions for setup. https://github.com/warrensbox/tgswitch/blob/master/README.md")
os.Exit(1)
}

// Install using version constraint from terragrunt file
func installTGHclFile(tgFile *string, custBinPath, mirrorURL string) {
fmt.Printf("Terragrunt file found: %s\n", *tgFile)
parser := hclparse.NewParser()
file, diags := parser.ParseHCLFile(*tgFile) //use hcl parser to parse HCL file
if diags.HasErrors() {
fmt.Println("Unable to parse HCL file")
os.Exit(1)
}
var version terragruntVersionConstraints
gohcl.DecodeBody(file.Body, nil, &version)
installFromConstraint(&version.TerragruntVersionConstraint, custBinPath, mirrorURL)
}

// check if version is defined in hcl file /* lazy-emergency fix - will improve later */
func checkVersionDefinedHCL(tgFile *string) bool {
parser := hclparse.NewParser()
Expand Down
2 changes: 1 addition & 1 deletion test-data/test_terragrunt-version/.terragrunt-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.34.5
0.37.0
16 changes: 16 additions & 0 deletions test-data/test_terragrunt_hcl/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
include {
path = "${find_in_parent_folders()}"
}

terraform {
source = "..."

extra_arguments "variables" {
commands = get_terraform_commands_that_need_vars()
}
}
inputs = merge(
jsondecode(file("${find_in_parent_folders("general.tfvars")}"))
)

terragrunt_version_constraint=">= 0.37, < 0.38"
1 change: 1 addition & 0 deletions test-data/test_tfswitchrc/.tgswitchrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.37.2
2 changes: 2 additions & 0 deletions test-data/test_tfswitchtoml/.tgswitch.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bin = "/usr/local/bin/terragrunt"
version = "0.37.3"
2 changes: 1 addition & 1 deletion test-data/test_tgswitchrc/.tgswitchrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.31.11
0.37.4

0 comments on commit 7c0ad45

Please sign in to comment.