Skip to content

Commit

Permalink
New feature to specify custome location
Browse files Browse the repository at this point in the history
  • Loading branch information
warrensbox committed Oct 17, 2019
1 parent e0d50b8 commit 56568b1
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 22 deletions.
37 changes: 36 additions & 1 deletion lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"regexp"
"runtime"

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

Expand Down Expand Up @@ -47,17 +48,34 @@ func init() {
for path := next(); len(path) > 0; path = next() {
installedBinPath = path
}

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

if symlinkExist {
RemoveSymlink(installedBinPath)
}
/* Create local installation directory if it does not exist */
CreateDirIfNotExist(installLocation)
}

//Install : Install the provided version in the argument
func Install(url string, appversion string, assests []modal.Repo, userBinPath * string) string {
func Install(url string, appversion string, assests []modal.Repo, userBinPath *string) string {

/* If user provided bin path use user one instead of default */
if userBinPath != nil {
installedBinPath = *userBinPath
}

pathDir := lib.Path(installedBinPath) //get path directory from binary path
binDirExist := lib.CheckDirExist(pathDir) //check bin path exist

if !binDirExist {
fmt.Printf("Binary path does not exist: %s\n", pathDir)
fmt.Printf("Please create binary path: %s for terragrunt installation\n", pathDir)
os.Exit(1)
}

/* check if selected version already downloaded */
fileExist := CheckFileExist(installLocation + installVersion + appversion)

Expand Down Expand Up @@ -195,3 +213,20 @@ func GetRecentVersions() ([]string, error) {
func CreateRecentFile(requestedVersion string) {
WriteLines([]string{requestedVersion}, installLocation+recentFile)
}

// ValidVersionFormat : returns valid version format
/* For example: 0.1.2 = valid
// For example: 0.1.2-beta1 = valid
// For example: 0.1.2-alpha = valid
// For example: a.1.2 = invalid
// For example: 0.1. 2 = invalid
*/
func ValidVersionFormat(version string) bool {

// 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
// Follow https://semver.org/spec/v1.0.0-beta.html
// Check regular expression at https://rubular.com/r/ju3PxbaSBALpJB
semverRegex := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-[a-zA-z]+\d*)?$`)

return semverRegex.MatchString(version)
}
97 changes: 97 additions & 0 deletions lib/list_versions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,100 @@ func TestRemoveDuplicateVersions(t *testing.T) {
t.Log("Write versions exist (expected)")
}
}

//TestValidVersionFormat : test if func returns valid version format
// more regex testing at https://rubular.com/r/UvWXui7EU2icSb
func TestValidVersionFormat(t *testing.T) {

var version string
version = "0.11.8"

valid := lib.ValidVersionFormat(version)

if valid == true {
t.Logf("Valid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "1.11.9"

valid = lib.ValidVersionFormat(version)

if valid == true {
t.Logf("Valid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "1.11.a"

valid = lib.ValidVersionFormat(version)

if valid == false {
t.Logf("Invalid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "22323"

valid = lib.ValidVersionFormat(version)

if valid == false {
t.Logf("Invalid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "@^&*!)!"

valid = lib.ValidVersionFormat(version)

if valid == false {
t.Logf("Invalid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "1.11.9-beta1"

valid = lib.ValidVersionFormat(version)

if valid == true {
t.Logf("Valid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "0.12.0-rc2"

valid = lib.ValidVersionFormat(version)

if valid == true {
t.Logf("Valid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "1.11.4-boom"

valid = lib.ValidVersionFormat(version)

if valid == true {
t.Logf("Valid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

version = "1.11.4-1"

valid = lib.ValidVersionFormat(version)

if valid == false {
t.Logf("Invalid version format : %s (expected)", version)
} else {
log.Fatalf("Failed to verify version format: %s\n", version)
}

}
41 changes: 25 additions & 16 deletions lib/symlink.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package lib

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

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

err := os.Symlink(cwd, dir)
if err != nil {
fmt.Println(err)
log.Fatalf("Unable to create symlink. You must have SUDO privileges %v \n", err)
panic(err)
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.
Error: %s
`, dir, dir, err)
os.Exit(1)
}
}

Expand All @@ -22,34 +27,38 @@ func RemoveSymlink(symlinkPath string) {

_, err := os.Lstat(symlinkPath)
if err != nil {
fmt.Println(err)
log.Fatalf("Unable to find symlink. You must have SUDO privileges - %v \n", err)
panic(err)
log.Fatalf(`
Unable to remove 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.
Error: %s
`, symlinkPath, symlinkPath, err)
os.Exit(1)
} else {
errRemove := os.Remove(symlinkPath)
if errRemove != nil {
fmt.Println(errRemove)
log.Fatalf("Unable to remove symlink. You must have SUDO privileges - %v \n", errRemove)
panic(errRemove)
log.Fatalf(`
Unable to remove 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.
Error: %s
`, symlinkPath, symlinkPath, errRemove)
os.Exit(1)
}
}
}

// CheckSymlink : check file is symlink
func CheckSymlink(symlinkPath string) bool {

//symlink := false
//fmt.Println("Checking symlink")

fi, err := os.Lstat(symlinkPath)
if err != nil {
fmt.Println(err)
// symlink = false
return false
}

if fi.Mode()&os.ModeSymlink != 0 {
//symlink = true
return true
}

Expand Down
40 changes: 35 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strings"

"github.com/manifoldco/promptui"
"github.com/pborman/getopt"
Expand All @@ -29,9 +31,11 @@ import (

const (
terragruntURL = "https://api.github.com/repos/gruntwork-io/terragrunt/releases?"
defaultBin = "/usr/local/bin/terragrunt" //default bin installation dir
rcFilename = ".tgswitchrc"
)

var version = "0.1.0\n"
var version = "0.2.0\n"

var CLIENT_ID = "xxx"
var CLIENT_SECRET = "xxx"
Expand All @@ -43,21 +47,47 @@ func main() {
client.ClientID = CLIENT_ID
client.ClientSecret = CLIENT_SECRET

userBinPath := getopt.StringLong("bin", 'b', "Custom binary path. For example: /Users/username/bin/terragrunt")
custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. For example: /Users/username/bin/terragrunt")
versionFlag := getopt.BoolLong("version", 'v', "displays the version of tgswitch")
helpFlag := getopt.BoolLong("help", 'h', "displays help message")
_ = versionFlag

getopt.Parse()
args := getopt.Args()

dir, err := os.Getwd()
if err != nil {
log.Printf("Failed to get current directory %v\n", err)
os.Exit(1)
}

rcfile := dir + fmt.Sprintf("/%s", rcFilename) //settings for .tfswitchrc file in current directory

if *versionFlag {
fmt.Printf("\nVersion: %v\n", version)
} else if *helpFlag {
usageMessage()
} else {

if len(args) == 1 {
if _, err := os.Stat(rcfile); err == nil && len(args) == 0 { //if there is a .tfswitchrc file, and no commmand line arguments
fmt.Printf("Reading required terraform version %s \n", rcFilename)

fileContents, err := ioutil.ReadFile(rcfile)
if err != nil {
fmt.Printf("Failed to read %s file. Follow the README.md instructions for setup. https://github.com/warrensbox/terraform-switcher/blob/master/README.md\n", rcFilename)
fmt.Printf("Error: %s\n", err)
os.Exit(1)
}
tfversion := strings.TrimSuffix(string(fileContents), "\n")
_, assets := lib.GetAppList(terragruntURL, &client)

if lib.ValidVersionFormat(tfversion) { //check if version is correct
lib.Install(terragruntURL, string(tfversion), assets, custBinPath)
} else {
fmt.Println("Invalid terraform version format. Format should be #.#.# or #.#.#-@# where # is numbers and @ is word characters. For example, 0.11.7 and 0.11.9-beta1 are valid versions")
os.Exit(1)
}
} else if len(args) == 1 {

semverRegex := regexp.MustCompile(`\A\d+(\.\d+){2}\z`)
if semverRegex.MatchString(args[0]) {
Expand All @@ -68,7 +98,7 @@ func main() {
exist := lib.VersionExist(requestedVersion, tflist)

if exist {
installLocation := lib.Install(terragruntURL, requestedVersion, assets, userBinPath)
installLocation := lib.Install(terragruntURL, requestedVersion, assets, custBinPath)
lib.AddRecent(requestedVersion, installLocation) //add to recent file for faster lookup
} else {
fmt.Println("Not a valid terragrunt version")
Expand Down Expand Up @@ -100,7 +130,7 @@ func main() {
os.Exit(1)
}

installLocation := lib.Install(terragruntURL, tgversion, assets, userBinPath)
installLocation := lib.Install(terragruntURL, tgversion, assets, custBinPath)
lib.AddRecent(tgversion, installLocation) //add to recent file for faster lookup
os.Exit(0)
} else {
Expand Down

0 comments on commit 56568b1

Please sign in to comment.