Compare commits

..

7 Commits

Author SHA1 Message Date
fe80f029b5 Merge pull request 'Add error handling and improve comments' (#7) from fix-1.9.x into master
Reviewed-on: #7
2024-09-12 00:38:13 +00:00
15742e8f3f Add error handling and improve comments
Added fmt.Errorf for better error messages during HTTP and file handling in InstallTerraformVersion. Also fixed indentation in comments to follow Go conventions. Made other small improvements for better readability and maintainability.
2024-09-11 20:27:10 -04:00
5251c15271 Merge pull request 'feature/fix-mac-arm' (#6) from feature/fix-mac-arm into master
Reviewed-on: #6
2023-10-05 21:36:42 +00:00
2d3d1f881e Merge pull request 'master' (#5) from master into feature/fix-mac-arm
Reviewed-on: #5
2023-10-05 21:05:43 +00:00
cde1201da5 Merge pull request 'Fixed make install command' (#4) from fix-makefile into master
Reviewed-on: #4
2023-10-05 21:05:02 +00:00
6df08053c6 Fixed make install command 2023-10-05 17:02:10 -04:00
8690a026b1 added fix to use x86 in for arm mac's where arm package is unavailable 2023-10-03 19:26:18 -04:00
19 changed files with 823 additions and 55 deletions

View File

@ -7,12 +7,12 @@ build:
# Clean # Clean
#################################################### ####################################################
clean: clean:
rm -f ~/.local/bin/versionedTerraform rm -f $(shell go env GOPATH)/bin/versionedTerraform
#################################################### ####################################################
# Install # Install
#################################################### ####################################################
install: install:
mv versionedTerraform ~/.local/bin/ mv versionedTerraform $(shell go env GOPATH)/bin/
#################################################### ####################################################
# help feature # help feature
#################################################### ####################################################
@ -22,6 +22,6 @@ help:
@echo 'Targets:' @echo 'Targets:'
@echo ' build go build -o versionedTerraform ./cmd' @echo ' build go build -o versionedTerraform ./cmd'
@echo ' clean removes installed versionedTerraform file' @echo ' clean removes installed versionedTerraform file'
@echo ' install installs versionedTerraform to local user bin folder' @echo ' install installs versionedTerraform to bin folder in GOPATH'
@echo ' all Nothing to do.' @echo ' all Nothing to do.'
@echo '' @echo ''

View File

@ -5,7 +5,7 @@ A wrapper for terraform to detect the expected version of terraform,
download, and execute that version download, and execute that version
## Requirements ## Requirements
- go compiler (only tested on go1.17) - go
## Install ## Install
`make build install` for installation to local user<br> `make build install` for installation to local user<br>

View File

@ -86,3 +86,50 @@ func (s *SemVersion) VersionInSlice(sSem []SemVersion) bool {
} }
return false return false
} }
func (s *SemVersion) IsEqualTo(s2 SemVersion) bool {
if s.majorVersion == s2.majorVersion && s.minorVersion == s2.minorVersion && s.patchVersion == s2.patchVersion {
return true
}
return false
}
func (s *SemVersion) IsLessThan(s2 SemVersion) bool {
if s2.majorVersion > s.majorVersion {
return true
}
if s2.minorVersion > s.minorVersion && s2.majorVersion == s.majorVersion {
return true
}
if s2.patchVersion > s.patchVersion && s2.majorVersion == s.majorVersion && s2.minorVersion == s.minorVersion {
return true
}
return false
}
func (s *SemVersion) IsGreaterThan(s2 SemVersion) bool {
if s2.majorVersion < s.majorVersion {
return true
}
if s2.minorVersion < s.minorVersion && s2.majorVersion == s.majorVersion {
return true
}
if s2.patchVersion < s.patchVersion && s2.majorVersion == s.majorVersion && s2.minorVersion == s.minorVersion {
return true
}
return false
}
func (s *SemVersion) IsLessOrEqual(s2 SemVersion) bool {
if s.IsLessThan(s2) || s.IsEqualTo(s2) {
return true
}
return false
}
func (s *SemVersion) IsGreaterOrEqual(s2 SemVersion) bool {
if s.IsGreaterThan(s2) || s.IsEqualTo(s2) {
return true
}
return false
}

View File

@ -86,3 +86,688 @@ func TestSemVersion_VersionInSlice_fail(t *testing.T) {
t.Errorf("Expected Sem Version to not be found in semArray") t.Errorf("Expected Sem Version to not be found in semArray")
} }
} }
func TestSemVersion_IsLessThan(t *testing.T) {
cases := []struct {
name string
want bool
s1, s2 SemVersion
}{
{"IsEqualTo",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MinorVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
},
{"PatchVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionGreater",
false,
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
},
{"MinorVersionGreater",
false,
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"PatchVersionGreater",
false,
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
}
for _, c := range cases {
t.Run("Test: "+c.name, func(t *testing.T) {
t.Parallel()
got := c.s1.IsLessThan(c.s2)
if c.want != got {
t.Errorf("Expected %+v got %+v", c.want, got)
}
})
}
}
func TestSemVersion_IsGreaterThan(t *testing.T) {
cases := []struct {
name string
want bool
s1, s2 SemVersion
}{
{"IsEqualTo",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MinorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
},
{"PatchVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionGreater",
true,
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
},
{"MinorVersionGreater",
true,
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"PatchVersionGreater",
true,
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
}
for _, c := range cases {
t.Run("Test: "+c.name, func(t *testing.T) {
t.Parallel()
got := c.s1.IsGreaterThan(c.s2)
if c.want != got {
t.Errorf("Expected %+v got %+v", c.want, got)
}
})
}
}
func TestSemVersion_IsEqualTo(t *testing.T) {
cases := []struct {
name string
want bool
s1, s2 SemVersion
}{
{"IsEqualTo",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MinorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
},
{"PatchVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionGreater",
false,
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
},
{"MinorVersionGreater",
false,
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"PatchVersionGreater",
false,
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
}
for _, c := range cases {
t.Run("Test: "+c.name, func(t *testing.T) {
t.Parallel()
got := c.s1.IsEqualTo(c.s2)
if c.want != got {
t.Errorf("Expected %+v got %+v", c.want, got)
}
})
}
}
func TestSemVersion_IsLessOrEqual(t *testing.T) {
cases := []struct {
name string
want bool
s1, s2 SemVersion
}{
{"IsEqualTo",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MinorVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
},
{"PatchVersionLess",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionGreater",
false,
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
},
{"MinorVersionGreater",
false,
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"PatchVersionGreater",
false,
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
}
for _, c := range cases {
t.Run("Test: "+c.name, func(t *testing.T) {
t.Parallel()
got := c.s1.IsLessOrEqual(c.s2)
if c.want != got {
t.Errorf("Expected %+v got %+v", c.want, got)
}
})
}
}
func TestSemVersion_IsGreaterOrEqual(t *testing.T) {
cases := []struct {
name string
want bool
s1, s2 SemVersion
}{
{"IsEqualTo",
true,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MinorVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
},
{"PatchVersionLess",
false,
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
},
{"MajorVersionGreater",
true,
SemVersion{
version: "2.2.3",
isStable: false,
majorVersion: 2,
minorVersion: 2,
patchVersion: 3,
},
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
},
{"MinorVersionGreater",
true,
SemVersion{
version: "1.3.3",
isStable: false,
majorVersion: 1,
minorVersion: 3,
patchVersion: 3,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
{"PatchVersionGreater",
true,
SemVersion{
version: "1.2.4",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 4,
},
SemVersion{
version: "1.2.3",
isStable: false,
majorVersion: 1,
minorVersion: 2,
patchVersion: 3,
},
},
}
for _, c := range cases {
t.Run("Test: "+c.name, func(t *testing.T) {
t.Parallel()
got := c.s1.IsGreaterOrEqual(c.s2)
if c.want != got {
t.Errorf("Expected %+v got %+v", c.want, got)
}
})
}
}

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_darwin_amd64.zip" fileSuffix = "_darwin_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_darwin_arm64.zip" fileSuffix = "_darwin_arm64.zip"
minVersion = "1.0.2"
alternateSuffix = "_darwin_amd64.zip"
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_freebsd_386.zip" fileSuffix = "_freebsd_386.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_freebsd_amd64.zip" fileSuffix = "_freebsd_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_freebsd_arm.zip" fileSuffix = "_freebsd_arm.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_linux_386.zip" fileSuffix = "_linux_386.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_linux_amd64.zip" fileSuffix = "_linux_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_linux_arm.zip" fileSuffix = "_linux_arm.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_linux_arm64.zip" fileSuffix = "_linux_arm64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_openbsd_386.zip" fileSuffix = "_openbsd_386.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_openbsd_amd64.zip" fileSuffix = "_openbsd_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_solaris_amd64.zip" fileSuffix = "_solaris_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,6 +5,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"errors" "errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -62,7 +63,6 @@ func (v *Version) getOneLessRelease() {
// getLatestRelease returns the latest release from Version // getLatestRelease returns the latest release from Version
func (v *Version) getLatestRelease() { func (v *Version) getLatestRelease() {
//todo clean up
for _, release := range v.availableVersions { for _, release := range v.availableVersions {
if release.majorVersion > v.Version.majorVersion && if release.majorVersion > v.Version.majorVersion &&
(release.isStable || !needsStable) { (release.isStable || !needsStable) {
@ -86,51 +86,59 @@ func (v *Version) getLatestRelease() {
// configuration directory // configuration directory
func (v *Version) InstallTerraformVersion() error { func (v *Version) InstallTerraformVersion() error {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
resp, err := http.Get(hashicorpUrl + suffix := fileSuffix
minV := NewSemVersion(minVersion)
if v.Version.IsLessThan(*minV) {
suffix = alternateSuffix
}
url := hashicorpUrl +
v.Version.ToString() + v.Version.ToString() +
"/" + terraformPrefix + "/" + terraformPrefix +
v.Version.ToString() + v.Version.ToString() +
fileSuffix) suffix
resp, err := http.Get(url)
if err != nil { if err != nil {
return err return fmt.Errorf("failed to download Terraform: %v", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return err return fmt.Errorf("failed to read response body: %v", err)
} }
zipReader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) zipReader, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
if err != nil { if err != nil {
return err return fmt.Errorf("failed to create zip reader: %v", err)
} }
versionedFileName := homeDir + versionedTerraformFolder + "/" + terraformPrefix + v.Version.ToString() versionedFileName := homeDir + versionedTerraformFolder + "/" + terraformPrefix + v.Version.ToString()
versionedFile, err := os.OpenFile(versionedFileName, os.O_WRONLY, 0755) versionedFile, err := os.OpenFile(versionedFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
if os.IsNotExist(err) {
versionedFile, err = os.OpenFile(versionedFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil { if err != nil {
return err return fmt.Errorf("failed to create output file: %v", err)
}
}
if err != nil {
return err
} }
defer versionedFile.Close() defer versionedFile.Close()
for _, zipFIle := range zipReader.File { for _, zipFile := range zipReader.File {
zr, err := zipFIle.Open() if zipFile.Name != "terraform" {
if err != nil { continue
return err
} }
unzippedFileBytes, _ := ioutil.ReadAll(zr)
_, err = versionedFile.Write(unzippedFileBytes) zr, err := zipFile.Open()
if err != nil { if err != nil {
return err return fmt.Errorf("failed to open zip file: %v", err)
} }
zr.Close() defer zr.Close()
_, err = io.Copy(versionedFile, zr)
if err != nil {
return fmt.Errorf("failed to write terraform binary: %v", err)
} }
break
}
return nil return nil
} }

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_windows_386.zip" fileSuffix = "_windows_386.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )

View File

@ -5,4 +5,6 @@ package versionedTerraform
const ( const (
fileSuffix = "_windows_amd64.zip" fileSuffix = "_windows_amd64.zip"
minVersion = "0.0.0"
alternateSuffix = ""
) )