Skip to content

Commit 9a8164c

Browse files
authored
Merge pull request #216 from warrensbox/master
Fixes Semver issue and M1 installation issue with homebrew
2 parents 7e72036 + 092ccf5 commit 9a8164c

File tree

11 files changed

+253
-237
lines changed

11 files changed

+253
-237
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Changelog
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [0.13.1201] - 2021-11-28
8+
### Bug fixes
9+
- No matter what users pass to --bin or -b, the local binary is called terraform. User can resume old behavior where -b is custom
10+
11+
### Added
12+
- -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
13+
- -P, --show-latest-pre=value : Show latest pre-release implicit version. Ex: tfswitch --show-latest-pre 0.13 prints 0.13.0-rc1 (latest)
14+
- -S, --show-latest-stable=value : Show latest implicit version. Ex: tfswitch --show-latest-stable 0.13 prints 0.13.7 (latest)
15+
- -U, --show-latest : Show latest stable version
16+
17+
### Removed
18+
- snapcraft installation option

go.mod

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ module github.com/warrensbox/terraform-switcher
33
go 1.13
44

55
require (
6-
github.com/Masterminds/semver v1.5.0
76
github.com/chzyer/logex v1.1.10 // indirect
87
github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3 // indirect
98
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
10-
github.com/hashicorp/go-version v1.3.0 // indirect
9+
github.com/hashicorp/go-version v1.4.0
1110
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80
11+
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f
1212
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect
13-
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824
1413
github.com/lunixbochs/vtclean v0.0.0-20170504063817-d14193dfc626 // indirect
1514
github.com/magiconair/properties v1.8.1 // indirect
1615
github.com/manifoldco/promptui v0.2.2-0.20180308161052-c0c0d3afc6a0

go.sum

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
22
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
33
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4-
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
5-
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
64
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
75
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
86
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
@@ -65,22 +63,23 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
6563
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
6664
github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
6765
github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
68-
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
69-
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
66+
github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4=
67+
github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
7068
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
7169
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
7270
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
73-
github.com/hashicorp/hcl2 v0.0.0-20190821123243-0c888d1241f6/go.mod h1:Cxv+IJLuBiEhQ7pBYGEuORa0nr4U994pE8mYLuFd7v0=
71+
github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8=
72+
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
7473
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80 h1:PFfGModn55JA0oBsvFghhj0v93me+Ctr3uHC/UmFAls=
7574
github.com/hashicorp/hcl2 v0.0.0-20191002203319-fb75b3253c80/go.mod h1:Cxv+IJLuBiEhQ7pBYGEuORa0nr4U994pE8mYLuFd7v0=
75+
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f h1:R8UIC07Ha9jZYkdcJ51l4ownCB8xYwfJtrgZSMvqjWI=
76+
github.com/hashicorp/terraform-config-inspect v0.0.0-20211115214459-90acf1ca460f/go.mod h1:Z0Nnk4+3Cy89smEbrq+sl1bxc9198gIP4I7wcQF6Kqs=
7677
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
7778
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
7879
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
7980
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
8081
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
8182
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
82-
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824 h1:2W0nCRf6KE5PGakYzkMTiOCGKTZR1HGxd8zxdqbLqgc=
83-
github.com/kiranjthomas/terraform-config-inspect v0.0.0-20191120205521-a1d709eb2824/go.mod h1:1Yap3+TRKI7BuRH6I8lbmjr+hMN7/GBxqBFhI2f2fmw=
8483
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
8584
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
8685
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -166,6 +165,7 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
166165
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
167166
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
168167
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
168+
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
169169
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
170170
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
171171
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=

lib/download_test.go

Lines changed: 19 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ import (
99
"path/filepath"
1010
"testing"
1111

12-
lib "github.com/warrensbox/terraform-switcher/lib"
12+
"github.com/warrensbox/terraform-switcher/lib"
1313
)
1414

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

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

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

3233
// create /.terraform.versions_test/ directory to store code
3334
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
34-
log.Printf("Creating directory for terraform: %v", installLocation)
35+
t.Logf("Creating directory for terraform: %v", installLocation)
3536
err = os.MkdirAll(installLocation, 0755)
3637
if err != nil {
37-
fmt.Printf("Unable to create directory for terraform: %v", installLocation)
38-
panic(err)
38+
t.Logf("Unable to create directory for terraform: %v", installLocation)
39+
t.Error("Test fail")
3940
}
4041
}
4142

42-
/* test download lowest terraform version */
43-
lowestVersion := "0.1.0"
43+
/* test download old terraform version */
44+
lowestVersion := "0.11.0"
4445

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

64-
/* test download latest terraform version */
65-
latestVersion := "0.11.7"
66-
67-
url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS
68-
expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS)
69-
installedFile, errDownload = lib.DownloadFromURL(installLocation, url)
70-
71-
if errDownload != nil {
72-
t.Logf("Expected file name %v to be downloaded", expectedFile)
73-
t.Error("Download not possible (unexpected)")
74-
}
75-
76-
if installedFile == expectedFile {
77-
t.Logf("Expected file name %v", expectedFile)
78-
t.Logf("Downloaded file name %v", installedFile)
79-
t.Log("Download file name matches expected file")
80-
} else {
81-
t.Logf("Expected file name %v", expectedFile)
82-
t.Logf("Downloaded file name %v", installedFile)
83-
t.Error("Dowload file name mismatches expected file (unexpected)")
84-
}
85-
86-
cleanUp(installLocation)
87-
}
88-
89-
// TestDownloadFromURL_FileExist : Check expected file exist when downloaded
90-
func TestDownloadFromURL_FileExist(t *testing.T) {
91-
92-
hashiURL := "https://releases.hashicorp.com/terraform/"
93-
installFile := "terraform"
94-
installVersion := "terraform_"
95-
installPath := GetInstallLocation(".terraform.versions_test")
96-
macOS := "_darwin_amd64.zip"
97-
98-
// get current user
99-
usr, errCurr := user.Current()
100-
if errCurr != nil {
101-
log.Fatal(errCurr)
102-
}
103-
104-
fmt.Printf("Current user: %v \n", usr.HomeDir)
105-
installLocation := filepath.Join(usr.HomeDir, installPath)
106-
107-
// create /.terraform.versions_test/ directory to store code
108-
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
109-
log.Printf("Creating directory for terraform: %v", installLocation)
110-
err = os.MkdirAll(installLocation, 0755)
111-
if err != nil {
112-
fmt.Printf("Unable to create directory for terraform: %v", installLocation)
113-
panic(err)
114-
}
115-
}
116-
117-
/* test download lowest terraform version */
118-
lowestVersion := "0.1.0"
119-
120-
url := hashiURL + lowestVersion + "/" + installVersion + lowestVersion + macOS
121-
expectedFile := filepath.Join(usr.HomeDir, installPath, installVersion+lowestVersion+macOS)
122-
installedFile, errDownload := lib.DownloadFromURL(installLocation, url)
123-
124-
if errDownload != nil {
125-
t.Logf("Expected file name %v to be downloaded", expectedFile)
126-
t.Error("Download not possible (unexpected)")
127-
}
128-
129-
if checkFileExist(expectedFile) {
130-
t.Logf("Expected file %v", expectedFile)
131-
t.Logf("Downloaded file %v", installedFile)
132-
t.Log("Download file matches expected file")
133-
} else {
134-
t.Logf("Expected file %v", expectedFile)
135-
t.Logf("Downloaded file %v", installedFile)
136-
t.Error("Download file mismatches expected file (unexpected)")
137-
}
138-
139-
/* test download latest terraform version */
140-
latestVersion := "0.11.7"
141-
142-
url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS
143-
expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS)
144-
installFile, errDownload = lib.DownloadFromURL(installLocation, url)
145-
146-
if errDownload != nil {
147-
t.Logf("Expected file name %v to be downloaded", expectedFile)
148-
t.Error("Download not possible (unexpected)")
149-
}
150-
151-
if checkFileExist(expectedFile) {
152-
t.Logf("Expected file %v", expectedFile)
153-
t.Logf("Downloaded file %v", installFile)
154-
t.Log("Download file matches expected file")
155-
} else {
156-
t.Logf("Expected file %v", expectedFile)
157-
t.Logf("Downloaded file %v", installFile)
158-
t.Error("Download file mismatches expected file (unexpected)")
159-
}
160-
161-
cleanUp(installLocation)
162-
}
163-
164-
// TestInvalidURL : Invalid url should throw an error
165-
func TestInvalidURL(t *testing.T) {
166-
167-
hashiURL := "https://releases.hashicorp.com/terraform/"
168-
installVersion := "terraform_"
169-
installPath := GetInstallLocation(".terraform.versions_test")
170-
macOS := "_darwin_amd64.zip"
171-
invalidVersion := "0.11.7-nonexistent"
172-
173-
// get current user
174-
usr, errCurr := user.Current()
175-
if errCurr != nil {
176-
log.Fatal(errCurr)
177-
}
178-
179-
fmt.Printf("Current user: %v \n", usr.HomeDir)
180-
installLocation := filepath.Join(usr.HomeDir, installPath)
181-
182-
// create /.terraform.versions_test/ directory to store code
183-
if _, err := os.Stat(installLocation); os.IsNotExist(err) {
184-
log.Printf("Creating directory for terraform: %v\n", installLocation)
185-
err = os.MkdirAll(installLocation, 0755)
186-
if err != nil {
187-
fmt.Printf("Unable to create directory for terraform: %v\n", installLocation)
188-
panic(err)
189-
}
190-
}
191-
192-
url := hashiURL + invalidVersion + "/" + installVersion + invalidVersion + macOS
193-
//expectedFile :=filepath.Join(usr.HomeDir, installPath, installVersion + invalidVersion + macOS)
194-
_, errDownload := lib.DownloadFromURL(installLocation, url)
195-
196-
if errDownload != nil {
197-
t.Logf("Unable to download from %s - invalid url or version (expected)\n", url)
198-
t.Logf("Download not possible (expected)")
65+
//check file name is what is expected
66+
_, err := os.Stat(expectedFile)
67+
if err != nil {
68+
t.Logf("Expected file does not exist %v", expectedFile)
19969
}
20070

201-
cleanUp(installLocation)
71+
t.Cleanup(func() {
72+
defer os.Remove(tempDir)
73+
fmt.Println("Cleanup temporary directory")
74+
})
20275
}
20376

204-
// TestDownloadFromURL_Valid : Test if https://releases.hashicorp.com/terraform/ is still valid
77+
// // TestDownloadFromURL_Valid : Test if https://releases.hashicorp.com/terraform/ is still valid
20578
func TestDownloadFromURL_Valid(t *testing.T) {
20679

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

20982
url, err := url.ParseRequestURI(hashiURL)
21083
if err != nil {
211-
t.Errorf("Valid URL provided: %v", err)
212-
t.Errorf("Invalid URL %v", err)
84+
t.Errorf("Invalid URL %v [unexpected]", err)
21385
} else {
214-
t.Logf("Valid URL from %v", url)
86+
t.Logf("Valid URL from %v [expected]", url)
21587
}
21688
}

lib/install.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,3 @@ func InstallableBinLocation(userBinPath string) string {
315315
os.Exit(1)
316316
return ""
317317
}
318-
319-
// func PrintCreateDirStmt(unableDir string, writable string) {
320-
// fmt.Printf("Creating bin directory at: %s\n", writable)
321-
// fmt.Printf("RUN `export PATH=$PATH:%s` to append bin to $PATH\n", writable)
322-
// }

lib/list_versions.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,36 @@ func GetTFLatest(mirrorURL string) (string, error) {
7373
//GetTFLatestImplicit : Get the latest implicit terraform version given the hashicorp url
7474
func GetTFLatestImplicit(mirrorURL string, preRelease bool, version string) (string, error) {
7575

76-
result, error := GetTFURLBody(mirrorURL)
77-
if error != nil {
78-
return "", error
79-
}
80-
var semver string
8176
if preRelease == true {
77+
//TODO: use GetTFList() instead of GetTFURLBody
78+
versions, error := GetTFURLBody(mirrorURL)
79+
if error != nil {
80+
return "", error
81+
}
8282
// 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
83-
semver = fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)\/`, version)
83+
semver := fmt.Sprintf(`\/(%s{1}\.\d+\-[a-zA-z]+\d*)\/`, version)
84+
r, err := regexp.Compile(semver)
85+
if err != nil {
86+
return "", err
87+
}
88+
for i := range versions {
89+
if r.MatchString(versions[i]) {
90+
str := r.FindString(versions[i])
91+
trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/
92+
return trimstr, nil
93+
}
94+
}
8495
} else if preRelease == false {
85-
semver = fmt.Sprintf(`\/(%s{1}\.\d+)\/`, version)
86-
}
87-
r, _ := regexp.Compile(semver)
88-
for i := range result {
89-
if r.MatchString(result[i]) {
90-
str := r.FindString(result[i])
91-
trimstr := strings.Trim(str, "/") //remove "/" from /X.X.X/
92-
return trimstr, nil
96+
listAll := false
97+
tflist, _ := GetTFList(mirrorURL, listAll) //get list of versions
98+
version = fmt.Sprintf("~> %v", version)
99+
semv, err := SemVerParser(&version, tflist)
100+
if err != nil {
101+
return "", err
93102
}
103+
return semv, nil
94104
}
95-
96105
return "", nil
97-
98106
}
99107

100108
//GetTFURLBody : Get list of terraform versions from hashicorp releases

0 commit comments

Comments
 (0)