Skip to content

Commit

Permalink
Merge pull request #216 from warrensbox/master
Browse files Browse the repository at this point in the history
Fixes Semver issue and M1 installation issue with homebrew
  • Loading branch information
warrensbox committed Mar 8, 2022
2 parents 7e72036 + 092ccf5 commit 9a8164c
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 237 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.13.1201] - 2021-11-28
### Bug fixes
- No matter what users pass to --bin or -b, the local binary is called terraform. User can resume old behavior where -b is custom

### Added
- -c, --chdir=value : Switch to a different working directory before executing the given command. Ex: tfswitch --chdir terraform_project will run tfswitch in the terraform_project directory
- -P, --show-latest-pre=value : Show latest pre-release implicit version. Ex: tfswitch --show-latest-pre 0.13 prints 0.13.0-rc1 (latest)
- -S, --show-latest-stable=value : Show latest implicit version. Ex: tfswitch --show-latest-stable 0.13 prints 0.13.7 (latest)
- -U, --show-latest : Show latest stable version

### Removed
- snapcraft installation option
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ module github.com/warrensbox/terraform-switcher
go 1.13

require (
github.com/Masterminds/semver v1.5.0
github.com/chzyer/logex v1.1.10 // indirect
github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3 // indirect
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hashicorp/go-version v1.4.0
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824
github.com/lunixbochs/vtclean v0.0.0-20170504063817-d14193dfc626 // indirect
github.com/magiconair/properties v1.8.1 // indirect
github.com/manifoldco/promptui v0.2.2-0.20180308161052-c0c0d3afc6a0
Expand Down
14 changes: 7 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
Expand Down Expand Up @@ -65,22 +63,23 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4=
github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl2 v0.0.0-20190821123243-0c888d1241f6/go.mod h1:Cxv+IJLuBiEhQ7pBYGEuORa0nr4U994pE8mYLuFd7v0=
github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8=
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80 h1:PFfGModn55JA0oBsvFghhj0v93me+Ctr3uHC/UmFAls=
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80/go.mod h1:Cxv+IJLuBiEhQ7pBYGEuORa0nr4U994pE8mYLuFd7v0=
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f h1:R8UIC07Ha9jZYkdcJ51l4ownCB8xYwfJtrgZSMvqjWI=
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f/go.mod h1:Z0Nnk4+3Cy89smEbrq+sl1bxc9198gIP4I7wcQF6Kqs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824 h1:2W0nCRf6KE5PGakYzkMTiOCGKTZR1HGxd8zxdqbLqgc=
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824/go.mod h1:1Yap3+TRKI7BuRH6I8lbmjr+hMN7/GBxqBFhI2f2fmw=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -166,6 +165,7 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
Expand Down
166 changes: 19 additions & 147 deletions lib/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import (
"path/filepath"
"testing"

lib "github.com/warrensbox/terraform-switcher/lib"
"github.com/warrensbox/terraform-switcher/lib"
)

// TestDownloadFromURL_FileNameMatch : Check expected filename exist when downloaded
func TestDownloadFromURL_FileNameMatch(t *testing.T) {

hashiURL := "https://releases.hashicorp.com/terraform/"
installVersion := "terraform_"
installPath := GetInstallLocation(".terraform.versions_test")
tempDir := t.TempDir()
installPath := fmt.Sprintf(tempDir + string(os.PathSeparator) + ".terraform.versions_test")
macOS := "_darwin_amd64.zip"

// get current user
Expand All @@ -31,16 +32,16 @@ func TestDownloadFromURL_FileNameMatch(t *testing.T) {

// create /.terraform.versions_test/ directory to store code
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
log.Printf("Creating directory for terraform: %v", installLocation)
t.Logf("Creating directory for terraform: %v", installLocation)
err = os.MkdirAll(installLocation, 0755)
if err != nil {
fmt.Printf("Unable to create directory for terraform: %v", installLocation)
panic(err)
t.Logf("Unable to create directory for terraform: %v", installLocation)
t.Error("Test fail")
}
}

/* test download lowest terraform version */
lowestVersion := "0.1.0"
/* test download old terraform version */
lowestVersion := "0.11.0"

url := hashiURL + lowestVersion + "/" + installVersion + lowestVersion + macOS
expectedFile := filepath.Join(usr.HomeDir, installPath, installVersion+lowestVersion+macOS)
Expand All @@ -61,156 +62,27 @@ func TestDownloadFromURL_FileNameMatch(t *testing.T) {
t.Error("Download file mismatches expected file (unexpected)")
}

/* test download latest terraform version */
latestVersion := "0.11.7"

url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS
expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS)
installedFile, errDownload = lib.DownloadFromURL(installLocation, url)

if errDownload != nil {
t.Logf("Expected file name %v to be downloaded", expectedFile)
t.Error("Download not possible (unexpected)")
}

if installedFile == expectedFile {
t.Logf("Expected file name %v", expectedFile)
t.Logf("Downloaded file name %v", installedFile)
t.Log("Download file name matches expected file")
} else {
t.Logf("Expected file name %v", expectedFile)
t.Logf("Downloaded file name %v", installedFile)
t.Error("Dowload file name mismatches expected file (unexpected)")
}

cleanUp(installLocation)
}

// TestDownloadFromURL_FileExist : Check expected file exist when downloaded
func TestDownloadFromURL_FileExist(t *testing.T) {

hashiURL := "https://releases.hashicorp.com/terraform/"
installFile := "terraform"
installVersion := "terraform_"
installPath := GetInstallLocation(".terraform.versions_test")
macOS := "_darwin_amd64.zip"

// get current user
usr, errCurr := user.Current()
if errCurr != nil {
log.Fatal(errCurr)
}

fmt.Printf("Current user: %v \n", usr.HomeDir)
installLocation := filepath.Join(usr.HomeDir, installPath)

// create /.terraform.versions_test/ directory to store code
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
log.Printf("Creating directory for terraform: %v", installLocation)
err = os.MkdirAll(installLocation, 0755)
if err != nil {
fmt.Printf("Unable to create directory for terraform: %v", installLocation)
panic(err)
}
}

/* test download lowest terraform version */
lowestVersion := "0.1.0"

url := hashiURL + lowestVersion + "/" + installVersion + lowestVersion + macOS
expectedFile := filepath.Join(usr.HomeDir, installPath, installVersion+lowestVersion+macOS)
installedFile, errDownload := lib.DownloadFromURL(installLocation, url)

if errDownload != nil {
t.Logf("Expected file name %v to be downloaded", expectedFile)
t.Error("Download not possible (unexpected)")
}

if checkFileExist(expectedFile) {
t.Logf("Expected file %v", expectedFile)
t.Logf("Downloaded file %v", installedFile)
t.Log("Download file matches expected file")
} else {
t.Logf("Expected file %v", expectedFile)
t.Logf("Downloaded file %v", installedFile)
t.Error("Download file mismatches expected file (unexpected)")
}

/* test download latest terraform version */
latestVersion := "0.11.7"

url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS
expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS)
installFile, errDownload = lib.DownloadFromURL(installLocation, url)

if errDownload != nil {
t.Logf("Expected file name %v to be downloaded", expectedFile)
t.Error("Download not possible (unexpected)")
}

if checkFileExist(expectedFile) {
t.Logf("Expected file %v", expectedFile)
t.Logf("Downloaded file %v", installFile)
t.Log("Download file matches expected file")
} else {
t.Logf("Expected file %v", expectedFile)
t.Logf("Downloaded file %v", installFile)
t.Error("Download file mismatches expected file (unexpected)")
}

cleanUp(installLocation)
}

// TestInvalidURL : Invalid url should throw an error
func TestInvalidURL(t *testing.T) {

hashiURL := "https://releases.hashicorp.com/terraform/"
installVersion := "terraform_"
installPath := GetInstallLocation(".terraform.versions_test")
macOS := "_darwin_amd64.zip"
invalidVersion := "0.11.7-nonexistent"

// get current user
usr, errCurr := user.Current()
if errCurr != nil {
log.Fatal(errCurr)
}

fmt.Printf("Current user: %v \n", usr.HomeDir)
installLocation := filepath.Join(usr.HomeDir, installPath)

// create /.terraform.versions_test/ directory to store code
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
log.Printf("Creating directory for terraform: %v\n", installLocation)
err = os.MkdirAll(installLocation, 0755)
if err != nil {
fmt.Printf("Unable to create directory for terraform: %v\n", installLocation)
panic(err)
}
}

url := hashiURL + invalidVersion + "/" + installVersion + invalidVersion + macOS
//expectedFile :=filepath.Join(usr.HomeDir, installPath, installVersion + invalidVersion + macOS)
_, errDownload := lib.DownloadFromURL(installLocation, url)

if errDownload != nil {
t.Logf("Unable to download from %s - invalid url or version (expected)\n", url)
t.Logf("Download not possible (expected)")
//check file name is what is expected
_, err := os.Stat(expectedFile)
if err != nil {
t.Logf("Expected file does not exist %v", expectedFile)
}

cleanUp(installLocation)
t.Cleanup(func() {
defer os.Remove(tempDir)
fmt.Println("Cleanup temporary directory")
})
}

// TestDownloadFromURL_Valid : Test if https://releases.hashicorp.com/terraform/ is still valid
// // TestDownloadFromURL_Valid : Test if https://releases.hashicorp.com/terraform/ is still valid
func TestDownloadFromURL_Valid(t *testing.T) {

hashiURL := "https://releases.hashicorp.com/terraform/"

url, err := url.ParseRequestURI(hashiURL)
if err != nil {
t.Errorf("Valid URL provided: %v", err)
t.Errorf("Invalid URL %v", err)
t.Errorf("Invalid URL %v [unexpected]", err)
} else {
t.Logf("Valid URL from %v", url)
t.Logf("Valid URL from %v [expected]", url)
}
}
5 changes: 0 additions & 5 deletions lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,3 @@ func InstallableBinLocation(userBinPath string) string {
os.Exit(1)
return ""
}

// func PrintCreateDirStmt(unableDir string, writable string) {
// fmt.Printf("Creating bin directory at: %s\n", writable)
// fmt.Printf("RUN `export PATH=$PATH:%s` to append bin to $PATH\n", writable)
// }
40 changes: 24 additions & 16 deletions lib/list_versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,36 @@ func GetTFLatest(mirrorURL string) (string, error) {
//GetTFLatestImplicit : Get the latest implicit terraform version given the hashicorp url
func GetTFLatestImplicit(mirrorURL string, preRelease bool, version string) (string, error) {

result, error := GetTFURLBody(mirrorURL)
if error != nil {
return "", error
}
var semver string
if preRelease == true {
//TODO: use GetTFList() instead of GetTFURLBody
versions, error := GetTFURLBody(mirrorURL)
if error != nil {
return "", error
}
// Getting versions from body; should return match /X.X.X-@/ where X is a number,@ is a word character between a-z or A-Z
semver = fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)\/`, version)
semver := fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)\/`, version)
r, err := regexp.Compile(semver)
if err != nil {
return "", err
}
for i := range versions {
if r.MatchString(versions[i]) {
str := r.FindString(versions[i])
trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/
return trimstr, nil
}
}
} else if preRelease == false {
semver = fmt.Sprintf(`\/(%s{1}\.\d+)\/`, version)
}
r, _ := regexp.Compile(semver)
for i := range result {
if r.MatchString(result[i]) {
str := r.FindString(result[i])
trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/
return trimstr, nil
listAll := false
tflist, _ := GetTFList(mirrorURL, listAll) //get list of versions
version = fmt.Sprintf("~> %v", version)
semv, err := SemVerParser(&version, tflist)
if err != nil {
return "", err
}
return semv, nil
}

return "", nil

}

//GetTFURLBody : Get list of terraform versions from hashicorp releases
Expand Down

0 comments on commit 9a8164c

Please sign in to comment.