diff --git a/.travis.yml b/.travis.yml index 5b77da93..ef8a07fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,55 @@ install: true go: - "1.16" -script: - - make test - - make clean +jobs: + include: + - os: linux + cache: + directories: + - $HOME/go + script: + - make test + - make clean + - os: osx + cache: + directories: + - $HOME/go + script: + - make test + - make clean + - os: windows + cache: + directories: + - $HOME/go + - $HOME/AppData/Local/Temp/chocolatey + - /C/tools/msys64 + before_install: + - |- + case $TRAVIS_OS_NAME in + windows) + [[ ! -f C:/tools/msys64/msys2_shell.cmd ]] && rm -rf C:/tools/msys64 + choco uninstall -y mingw + choco upgrade --no-progress -y msys2 + export msys2='cmd //C RefreshEnv.cmd ' + export msys2+='& set MSYS=winsymlinks:nativestrict ' + export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start' + export mingw64="$msys2 -mingw64 -full-path -here -c "\"\$@"\" --" + export msys2+=" -msys2 -c "\"\$@"\" --" + $msys2 pacman --sync --noconfirm --needed mingw-w64-x86_64-toolchain + ## Install more MSYS2 packages from https://packages.msys2.org/base here + taskkill //IM gpg-agent.exe //F # https://travis-ci.community/t/4967 + export PATH=/C/tools/msys64/mingw64/bin:$PATH + export MAKE=mingw32-make # so that Autotools can find it + ;; + esac + before_cache: + - |- + case $TRAVIS_OS_NAME in + windows) + # https://unix.stackexchange.com/a/137322/107554 + $msys2 pacman --sync --clean --noconfirm + ;; + esac + script: + - $MAKE test + - $MAKE clean diff --git a/README.md b/README.md index e5b5475f..734541ea 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,12 @@ The most recently selected versions are presented at the top of the dropdown. 2. For example, `tfswitch 0.10.5` for version 0.10.5 of terraform. 3. Hit **Enter** to switch. +**NOTE** for windows host `tfswitch` need to be run under `Administrator` mode, and `$HOME/.tfswitch.toml` with `bin` must be defined (with a valid path) as minimum, below is an example for `$HOME/.tfswitch.toml` on windows + +```toml +bin = "C:\\Users\\<%USRNAME%>\\bin\\terraform.exe" +``` + ### See all versions including beta, alpha and release candidates(rc) drawing diff --git a/lib/common_test.go b/lib/common_test.go index 08606b34..864d40bd 100644 --- a/lib/common_test.go +++ b/lib/common_test.go @@ -51,7 +51,6 @@ func cleanUp(path string) { func removeFiles(src string) { files, err := filepath.Glob(src) if err != nil { - panic(err) } for _, f := range files { diff --git a/lib/download.go b/lib/download.go index b2477b49..bb81c03c 100644 --- a/lib/download.go +++ b/lib/download.go @@ -5,6 +5,7 @@ import ( "io" "net/http" "os" + "path/filepath" "strings" ) @@ -29,9 +30,10 @@ func DownloadFromURL(installLocation string, url string) (string, error) { return "", fmt.Errorf("Unable to download from %s\nPlease download manually from https://releases.hashicorp.com/terraform/", url) } - output, err := os.Create(installLocation + fileName) + zipFile := filepath.Join(installLocation, fileName) + output, err := os.Create(zipFile) if err != nil { - fmt.Println("Error while creating", installLocation+fileName, "-", err) + fmt.Println("Error while creating", zipFile, "-", err) return "", err } defer output.Close() @@ -43,5 +45,5 @@ func DownloadFromURL(installLocation string, url string) (string, error) { } fmt.Println(n, "bytes downloaded.") - return installLocation + fileName, nil + return zipFile, nil } diff --git a/lib/download_test.go b/lib/download_test.go index f4785ae7..e47d6a7b 100644 --- a/lib/download_test.go +++ b/lib/download_test.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "os/user" + "path/filepath" "testing" lib "github.com/warrensbox/terraform-switcher/lib" @@ -26,7 +27,7 @@ func TestDownloadFromURL_FileNameMatch(t *testing.T) { } fmt.Printf("Current user: %v \n", usr.HomeDir) - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) // create /.terraform.versions_test/ directory to store code if _, err := os.Stat(installLocation); os.IsNotExist(err) { @@ -42,7 +43,7 @@ func TestDownloadFromURL_FileNameMatch(t *testing.T) { lowestVersion := "0.1.0" url := hashiURL + lowestVersion + "/" + installVersion + lowestVersion + macOS - expectedFile := usr.HomeDir + installPath + installVersion + lowestVersion + macOS + expectedFile := filepath.Join(usr.HomeDir, installPath, installVersion+lowestVersion+macOS) installedFile, errDownload := lib.DownloadFromURL(installLocation, url) if errDownload != nil { @@ -64,7 +65,7 @@ func TestDownloadFromURL_FileNameMatch(t *testing.T) { latestVersion := "0.11.7" url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS - expectedFile = usr.HomeDir + installPath + installVersion + latestVersion + macOS + expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS) installedFile, errDownload = lib.DownloadFromURL(installLocation, url) if errDownload != nil { @@ -101,7 +102,7 @@ func TestDownloadFromURL_FileExist(t *testing.T) { } fmt.Printf("Current user: %v \n", usr.HomeDir) - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) // create /.terraform.versions_test/ directory to store code if _, err := os.Stat(installLocation); os.IsNotExist(err) { @@ -117,7 +118,7 @@ func TestDownloadFromURL_FileExist(t *testing.T) { lowestVersion := "0.1.0" url := hashiURL + lowestVersion + "/" + installVersion + lowestVersion + macOS - expectedFile := usr.HomeDir + installPath + installVersion + lowestVersion + macOS + expectedFile := filepath.Join(usr.HomeDir, installPath, installVersion+lowestVersion+macOS) installedFile, errDownload := lib.DownloadFromURL(installLocation, url) if errDownload != nil { @@ -139,7 +140,7 @@ func TestDownloadFromURL_FileExist(t *testing.T) { latestVersion := "0.11.7" url = hashiURL + latestVersion + "/" + installVersion + latestVersion + macOS - expectedFile = usr.HomeDir + installPath + installVersion + latestVersion + macOS + expectedFile = filepath.Join(usr.HomeDir, installPath, installVersion+latestVersion+macOS) installFile, errDownload = lib.DownloadFromURL(installLocation, url) if errDownload != nil { @@ -176,7 +177,7 @@ func TestInvalidURL(t *testing.T) { } fmt.Printf("Current user: %v \n", usr.HomeDir) - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) // create /.terraform.versions_test/ directory to store code if _, err := os.Stat(installLocation); os.IsNotExist(err) { @@ -189,7 +190,7 @@ func TestInvalidURL(t *testing.T) { } url := hashiURL + invalidVersion + "/" + installVersion + invalidVersion + macOS - //expectedFile := usr.HomeDir + installPath + installVersion + invalidVersion + macOS + //expectedFile :=filepath.Join(usr.HomeDir, installPath, installVersion + invalidVersion + macOS) _, errDownload := lib.DownloadFromURL(installLocation, url) if errDownload != nil { diff --git a/lib/files_test.go b/lib/files_test.go index fe9cd632..a3766625 100644 --- a/lib/files_test.go +++ b/lib/files_test.go @@ -21,8 +21,7 @@ import ( // TestRenameFile : Create a file, check filename exist, // rename file, check new filename exit func TestRenameFile(t *testing.T) { - - installFile := "terraform" + installFile := lib.ConvertExecutableExt("terraform") installVersion := "terraform_" installPath := "/.terraform.versions_test/" version := "0.0.7" @@ -31,33 +30,37 @@ func TestRenameFile(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) - createFile(installLocation + installFile) + installFilePath := filepath.Join(installLocation, installFile) + + createFile(installFilePath) - if exist := checkFileExist(installLocation + installFile); exist { - t.Logf("File exist %v", installLocation+installFile) + if exist := checkFileExist(installFilePath); exist { + t.Logf("File exist %v", installFilePath) } else { - t.Logf("File does not exist %v", installLocation+installFile) + t.Logf("File does not exist %v", installFilePath) t.Error("Missing file") } - lib.RenameFile(installLocation+installFile, installLocation+installVersion+version) + installVersionFilePath := lib.ConvertExecutableExt(filepath.Join(installLocation, installVersion+version)) + + lib.RenameFile(installFilePath, installVersionFilePath) - if exist := checkFileExist(installLocation + installVersion + version); exist { - t.Logf("New file exist %v", installLocation+installVersion+version) + if exist := checkFileExist(installVersionFilePath); exist { + t.Logf("New file exist %v", installVersionFilePath) } else { - t.Logf("New file does not exist %v", installLocation+installVersion+version) + t.Logf("New file does not exist %v", installVersionFilePath) t.Error("Missing new file") } - if exist := checkFileExist(installLocation + installFile); exist { - t.Logf("Old file should not exist %v", installLocation+installFile) + if exist := checkFileExist(installFilePath); exist { + t.Logf("Old file should not exist %v", installFilePath) t.Error("Did not rename file") } else { - t.Logf("Old file does not exist %v", installLocation+installFile) + t.Logf("Old file does not exist %v", installFilePath) } cleanUp(installLocation) @@ -66,34 +69,35 @@ func TestRenameFile(t *testing.T) { // TestRemoveFiles : Create a file, check file exist, // remove file, check file does not exist func TestRemoveFiles(t *testing.T) { - - installFile := "terraform" + installFile := lib.ConvertExecutableExt("terraform") installPath := "/.terraform.versions_test/" usr, errCurr := user.Current() if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) - createFile(installLocation + installFile) + installFilePath := filepath.Join(installLocation, installFile) + + createFile(installFilePath) - if exist := checkFileExist(installLocation + installFile); exist { - t.Logf("File exist %v", installLocation+installFile) + if exist := checkFileExist(installFilePath); exist { + t.Logf("File exist %v", installFilePath) } else { - t.Logf("File does not exist %v", installLocation+installFile) + t.Logf("File does not exist %v", installFilePath) t.Error("Missing file") } - lib.RemoveFiles(installLocation + installFile) + lib.RemoveFiles(installFilePath) - if exist := checkFileExist(installLocation + installFile); exist { - t.Logf("Old file should not exist %v", installLocation+installFile) + if exist := checkFileExist(installFilePath); exist { + t.Logf("Old file should not exist %v", installFilePath) t.Error("Did not remove file") } else { - t.Logf("Old file does not exist %v", installLocation+installFile) + t.Logf("Old file does not exist %v", installFilePath) } cleanUp(installLocation) @@ -102,7 +106,6 @@ func TestRemoveFiles(t *testing.T) { // TestUnzip : Create a file, check file exist, // remove file, check file does not exist func TestUnzip(t *testing.T) { - installPath := "/.terraform.versions_test/" absPath, _ := filepath.Abs("../test-data/test-data.zip") @@ -112,7 +115,7 @@ func TestUnzip(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) @@ -138,14 +141,13 @@ func TestUnzip(t *testing.T) { // TestCreateDirIfNotExist : Create a directory, check directory exist func TestCreateDirIfNotExist(t *testing.T) { - installPath := "/.terraform.versions_test/" usr, errCurr := user.Current() if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) cleanUp(installLocation) @@ -171,7 +173,6 @@ func TestCreateDirIfNotExist(t *testing.T) { //TestWriteLines : write to file, check readline to verify func TestWriteLines(t *testing.T) { - installPath := "/.terraform.versions_test/" recentFile := "RECENT" semverRegex := regexp.MustCompile(`\A\d+(\.\d+){2}(-\w+\d*)?\z`) @@ -181,19 +182,19 @@ func TestWriteLines(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) + recentFilePath := filepath.Join(installLocation, recentFile) test_array := []string{"0.1.1", "0.0.2", "0.0.3", "0.12.0-rc1", "0.12.0-beta1"} - errWrite := lib.WriteLines(test_array, installLocation+recentFile) + errWrite := lib.WriteLines(test_array, recentFilePath) if errWrite != nil { t.Logf("Write should work %v (unexpected)", errWrite) log.Fatal(errWrite) } else { - var ( file *os.File part []byte @@ -201,10 +202,9 @@ func TestWriteLines(t *testing.T) { errOpen, errRead error lines []string ) - if file, errOpen = os.Open(installLocation + recentFile); errOpen != nil { + if file, errOpen = os.Open(recentFilePath); errOpen != nil { log.Fatal(errOpen) } - defer file.Close() reader := bufio.NewReader(file) buffer := bytes.NewBuffer(make([]byte, 0)) @@ -233,11 +233,11 @@ func TestWriteLines(t *testing.T) { } } + file.Close() t.Log("Write versions exist (expected)") } cleanUp(installLocation) - } // TestReadLines : read from file, check write to verify @@ -250,10 +250,11 @@ func TestReadLines(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) + recentFilePath := filepath.Join(installLocation, recentFile) test_array := []string{"0.0.1", "0.0.2", "0.0.3", "0.12.0-rc1", "0.12.0-beta1"} var ( @@ -261,10 +262,9 @@ func TestReadLines(t *testing.T) { errCreate error ) - if file, errCreate = os.Create(installLocation + recentFile); errCreate != nil { + if file, errCreate = os.Create(recentFilePath); errCreate != nil { log.Fatalf("Error: %s\n", errCreate) } - defer file.Close() for _, item := range test_array { _, err := file.WriteString(strings.TrimSpace(item) + "\n") @@ -274,7 +274,7 @@ func TestReadLines(t *testing.T) { } } - lines, errRead := lib.ReadLines(installLocation + recentFile) + lines, errRead := lib.ReadLines(recentFilePath) if errRead != nil { log.Fatalf("Error: %s\n", errRead) @@ -287,15 +287,14 @@ func TestReadLines(t *testing.T) { } } + file.Close() t.Log("Read versions exist (expected)") cleanUp(installLocation) - } // TestIsDirEmpty : create empty directory, check if empty func TestIsDirEmpty(t *testing.T) { - current := time.Now() installPath := "/.terraform.versions_test/" @@ -304,18 +303,19 @@ func TestIsDirEmpty(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) test_dir := current.Format("2006-01-02") + test_dir_path := filepath.Join(installLocation, test_dir) t.Logf("Create test dir: %v \n", test_dir) createDirIfNotExist(installLocation) - createDirIfNotExist(installLocation + "/" + test_dir) + createDirIfNotExist(test_dir_path) - empty := lib.IsDirEmpty(installLocation + "/" + test_dir) + empty := lib.IsDirEmpty(test_dir_path) - t.Logf("Expected directory to be empty %v [expected]", installLocation+"/"+test_dir) + t.Logf("Expected directory to be empty %v [expected]", test_dir_path) if empty == true { t.Logf("Directory empty") @@ -323,33 +323,31 @@ func TestIsDirEmpty(t *testing.T) { t.Error("Directory not empty") } - cleanUp(installLocation + "/" + test_dir) - + cleanUp(test_dir_path) cleanUp(installLocation) - } // TestCheckDirHasTGBin : create tg file in directory, check if exist func TestCheckDirHasTFBin(t *testing.T) { - goarch := runtime.GOARCH goos := runtime.GOOS installPath := "/.terraform.versions_test/" - installFile := "terraform" + installFilePrefix := "terraform" usr, errCurr := user.Current() if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) - createFile(installLocation + installFile + "_" + goos + "_" + goarch) + installFileVersionPath := lib.ConvertExecutableExt(filepath.Join(installLocation, installFilePrefix+"_"+goos+"_"+goarch)) + createFile(installFileVersionPath) - empty := lib.CheckDirHasTGBin(installLocation, installFile) + empty := lib.CheckDirHasTGBin(installLocation, installFilePrefix) - t.Logf("Expected directory to have tf file %v [expected]", installLocation+installFile+"_"+goos+"_"+goarch) + t.Logf("Expected directory to have tf file %v [expected]", installFileVersionPath) if empty == true { t.Logf("Directory empty") @@ -362,23 +360,23 @@ func TestCheckDirHasTFBin(t *testing.T) { // TestPath : create file in directory, check if path exist func TestPath(t *testing.T) { - installPath := "/.terraform.versions_test" - installFile := "terraform" + installFile := lib.ConvertExecutableExt("terraform") usr, errCurr := user.Current() if errCurr != nil { log.Fatal(errCurr) } - installLocation := usr.HomeDir + installPath + installLocation := filepath.Join(usr.HomeDir, installPath) createDirIfNotExist(installLocation) - createFile(installLocation + "/" + installFile) + installFilePath := filepath.Join(installLocation, installFile) + createFile(installFilePath) - path := lib.Path(installLocation + "/" + installFile) + path := lib.Path(installFilePath) - t.Logf("Path created %s\n", installLocation+installFile) + t.Logf("Path created %s\n", installFilePath) t.Logf("Path expected %s\n", installLocation) t.Logf("Path from library %s\n", path) if path == installLocation { @@ -391,7 +389,6 @@ func TestPath(t *testing.T) { } // TestGetFileName : remove file ext. .tfswitch.config returns .tfswitch - func TestGetFileName(t *testing.T) { fileNameWithExt := "file.toml" @@ -404,3 +401,55 @@ func TestGetFileName(t *testing.T) { t.Error("File did not remove extension (unexpected)") } } + +// TestConvertExecutableExt : convert executable binary with extension +func TestConvertExecutableExt(t *testing.T) { + usr, errCurr := user.Current() + if errCurr != nil { + log.Fatal(errCurr) + } + + installPath := "/.terraform.versions_test/" + test_array := []string{ + "terraform", + "terraform.exe", + filepath.Join(usr.HomeDir, installPath, "terraform"), + filepath.Join(usr.HomeDir, installPath, "terraform.exe"), + } + + for _, fpath := range test_array { + fpathExt := lib.ConvertExecutableExt((fpath)) + outputMsg := fpath + " converted to " + fpathExt + " on " + runtime.GOOS + + switch runtime.GOOS { + case "windows": + if filepath.Ext(fpathExt) != ".exe" { + t.Error(outputMsg + " (unexpected)") + continue + } + + if filepath.Ext(fpath) == ".exe" { + if fpathExt != fpath { + t.Error(outputMsg + " (unexpected)") + } else { + t.Logf(outputMsg + " (expected)") + } + continue + } + + if fpathExt != fpath+".exe" { + t.Error(outputMsg + " (unexpected)") + continue + } + + t.Logf(outputMsg + " (expected)") + default: + if fpath != fpathExt { + t.Error(outputMsg + " (unexpected)") + continue + } + + t.Logf(outputMsg + " (expected)") + } + } +} diff --git a/lib/install.go b/lib/install.go index dde1e5b3..4656816e 100644 --- a/lib/install.go +++ b/lib/install.go @@ -5,6 +5,7 @@ import ( "log" "os" "os/user" + "path/filepath" "runtime" ) @@ -59,7 +60,7 @@ func getInstallLocation() string { } /* set installation location */ - installLocation = usr.HomeDir + installPath + installLocation = filepath.Join(usr.HomeDir, installPath) /* Create local installation directory if it does not exist */ CreateDirIfNotExist(installLocation) @@ -97,7 +98,8 @@ func Install(tfversion string, binPath string) { } /* check if selected version already downloaded */ - fileExist := CheckFileExist(installLocation + installVersion + tfversion) + installFileVersionPath := ConvertExecutableExt(filepath.Join(installLocation, installVersion+tfversion)) + fileExist := CheckFileExist(installFileVersionPath) /* if selected version already exist, */ if fileExist { @@ -110,7 +112,7 @@ func Install(tfversion string, binPath string) { } /* set symlink to desired version */ - CreateSymlink(installLocation+installVersion+tfversion, binPath) + CreateSymlink(installFileVersionPath, binPath) fmt.Printf("Switched terraform to version %q \n", tfversion) AddRecent(tfversion) //add to recent file for faster lookup os.Exit(0) @@ -136,10 +138,11 @@ func Install(tfversion string, binPath string) { } /* rename unzipped file to terraform version name - terraform_x.x.x */ - RenameFile(installLocation+installFile, installLocation+installVersion+tfversion) + installFilePath := ConvertExecutableExt(filepath.Join(installLocation, installFile)) + RenameFile(installFilePath, installFileVersionPath) /* remove zipped file to clear clutter */ - RemoveFiles(installLocation + installVersion + tfversion + "_" + goos + "_" + goarch + ".zip") + RemoveFiles(zipFile) /* remove current symlink if exist*/ symlinkExist := CheckSymlink(binPath) @@ -149,7 +152,7 @@ func Install(tfversion string, binPath string) { } /* set symlink to desired version */ - CreateSymlink(installLocation+installVersion+tfversion, binPath) + CreateSymlink(installFileVersionPath, binPath) fmt.Printf("Switched terraform to version %q \n", tfversion) AddRecent(tfversion) //add to recent file for faster lookup os.Exit(0) @@ -159,10 +162,11 @@ func Install(tfversion string, binPath string) { func AddRecent(requestedVersion string) { installLocation = getInstallLocation() //get installation location - this is where we will put our terraform binary file + versionFile := filepath.Join(installLocation, recentFile) - fileExist := CheckFileExist(installLocation + recentFile) + fileExist := CheckFileExist(versionFile) if fileExist { - lines, errRead := ReadLines(installLocation + recentFile) + lines, errRead := ReadLines(versionFile) if errRead != nil { fmt.Printf("Error: %s\n", errRead) @@ -172,7 +176,7 @@ func AddRecent(requestedVersion string) { for _, line := range lines { if !ValidVersionFormat(line) { fmt.Println("File dirty. Recreating cache file.") - RemoveFiles(installLocation + recentFile) + RemoveFiles(versionFile) CreateRecentFile(requestedVersion) return } @@ -185,10 +189,10 @@ func AddRecent(requestedVersion string) { _, lines = lines[len(lines)-1], lines[:len(lines)-1] lines = append([]string{requestedVersion}, lines...) - WriteLines(lines, installLocation+recentFile) + WriteLines(lines, versionFile) } else { lines = append([]string{requestedVersion}, lines...) - WriteLines(lines, installLocation+recentFile) + WriteLines(lines, versionFile) } } @@ -201,11 +205,12 @@ func AddRecent(requestedVersion string) { func GetRecentVersions() ([]string, error) { installLocation = getInstallLocation() //get installation location - this is where we will put our terraform binary file + versionFile := filepath.Join(installLocation, recentFile) - fileExist := CheckFileExist(installLocation + recentFile) + fileExist := CheckFileExist(versionFile) if fileExist { - lines, errRead := ReadLines(installLocation + recentFile) + lines, errRead := ReadLines(versionFile) outputRecent := []string{} if errRead != nil { @@ -219,7 +224,7 @@ func GetRecentVersions() ([]string, error) { and the recent file will be removed */ if !ValidVersionFormat(line) { - RemoveFiles(installLocation + recentFile) + RemoveFiles(versionFile) return nil, errRead } @@ -240,5 +245,18 @@ func CreateRecentFile(requestedVersion string) { installLocation = getInstallLocation() //get installation location - this is where we will put our terraform binary file - WriteLines([]string{requestedVersion}, installLocation+recentFile) + WriteLines([]string{requestedVersion}, filepath.Join(installLocation, recentFile)) +} + +//ConvertExecutableExt : convert excutable with local OS extension +func ConvertExecutableExt(fpath string) string { + switch runtime.GOOS { + case "windows": + if filepath.Ext(fpath) == ".exe" { + return fpath + } + return fpath + ".exe" + default: + return fpath + } } diff --git a/lib/symlink_test.go b/lib/symlink_test.go index 328c21d3..08d4f636 100644 --- a/lib/symlink_test.go +++ b/lib/symlink_test.go @@ -4,6 +4,7 @@ import ( "log" "os" "os/user" + "path/filepath" "testing" "github.com/warrensbox/terraform-switcher/lib" @@ -21,8 +22,8 @@ func TestCreateSymlink(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - symlinkPathSrc := usr.HomeDir + testSymlinkSrc - symlinkPathDest := usr.HomeDir + testSymlinkDest + symlinkPathSrc := filepath.Join(usr.HomeDir, testSymlinkSrc) + symlinkPathDest := filepath.Join(usr.HomeDir, testSymlinkDest) ln, _ := os.Readlink(symlinkPathSrc) @@ -59,8 +60,8 @@ func TestRemoveSymlink(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - symlinkPathSrc := usr.HomeDir + testSymlinkSrc - symlinkPathDest := usr.HomeDir + testSymlinkDest + symlinkPathSrc := filepath.Join(usr.HomeDir, testSymlinkSrc) + symlinkPathDest := filepath.Join(usr.HomeDir, testSymlinkDest) ln, _ := os.Readlink(symlinkPathSrc) @@ -94,8 +95,8 @@ func TestCheckSymlink(t *testing.T) { if errCurr != nil { log.Fatal(errCurr) } - symlinkPathSrc := usr.HomeDir + testSymlinkSrc - symlinkPathDest := usr.HomeDir + testSymlinkDest + symlinkPathSrc := filepath.Join(usr.HomeDir, testSymlinkSrc) + symlinkPathDest := filepath.Join(usr.HomeDir, testSymlinkDest) ln, _ := os.Readlink(symlinkPathSrc) diff --git a/main.go b/main.go index 65c15cfa..da0a25b6 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "sort" "strings" @@ -55,7 +56,7 @@ const ( var version = "0.12.0\n" func main() { - custBinPath := getopt.StringLong("bin", 'b', defaultBin, "Custom binary path. Ex: /Users/username/bin/terraform") + custBinPath := getopt.StringLong("bin", 'b', lib.ConvertExecutableExt(defaultBin), "Custom binary path. Ex: "+lib.ConvertExecutableExt("/Users/username/bin/terraform")) listAllFlag := getopt.BoolLong("list-all", 'l', "List all versions of terraform - including beta and rc") latestPre := getopt.StringLong("latest-pre", 'p', defaultLatest, "Latest pre-release implicit version. Ex: tfswitch --latest-pre 0.13 downloads 0.13.0-rc1 (latest)") latestStable := getopt.StringLong("latest-stable", 's', defaultLatest, "Latest implicit version. Ex: tfswitch --latest-stable 0.13 downloads 0.13.7 (latest)") @@ -79,11 +80,11 @@ func main() { os.Exit(1) } - TFVersionFile := dir + fmt.Sprintf("/%s", tfvFilename) //settings for .terraform-version file in current directory (tfenv compatible) - RCFile := dir + fmt.Sprintf("/%s", rcFilename) //settings for .tfswitchrc file in current directory (backward compatible purpose) - TOMLConfigFile := dir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in current directory (option to specify bin directory) - HomeTOMLConfigFile := homedir + fmt.Sprintf("/%s", tomlFilename) //settings for .tfswitch.toml file in home directory (option to specify bin directory) - TGHACLFile := dir + fmt.Sprintf("/%s", tgHclFilename) //settings for terragrunt.hcl file in current directory (option to specify bin directory) + TFVersionFile := filepath.Join(dir, tfvFilename) //settings for .terraform-version file in current directory (tfenv compatible) + RCFile := filepath.Join(dir, rcFilename) //settings for .tfswitchrc file in current directory (backward compatible purpose) + TOMLConfigFile := filepath.Join(dir, tomlFilename) //settings for .tfswitch.toml file in current directory (option to specify bin directory) + HomeTOMLConfigFile := filepath.Join(homedir, tomlFilename) //settings for .tfswitch.toml file in home directory (option to specify bin directory) + TGHACLFile := filepath.Join(dir, tgHclFilename) //settings for terragrunt.hcl file in current directory (option to specify bin directory) switch { case *versionFlag: @@ -100,7 +101,6 @@ func main() { * If you provide a version on the command line, this will override the version value in the toml file */ case fileExists(TOMLConfigFile) || fileExists(HomeTOMLConfigFile): - version := "" binPath := *custBinPath if fileExists(TOMLConfigFile) { //read from toml from current directory @@ -337,8 +337,8 @@ func getParamsTOML(binPath string, dir string) (string, string) { os.Exit(1) // exit immediately if config file provided but it is unable to read it } - bin := viper.Get("bin") // read custom binary location - if binPath == defaultBin && bin != nil { // if the bin path is the same as the default binary path and if the custom binary is provided in the toml file (use it) + bin := viper.Get("bin") // read custom binary location + if binPath == lib.ConvertExecutableExt(defaultBin) && bin != nil { // if the bin path is the same as the default binary path and if the custom binary is provided in the toml file (use it) binPath = os.ExpandEnv(bin.(string)) } //fmt.Println(binPath) //uncomment this to debug @@ -360,7 +360,6 @@ func usageMessage() { /* listAll = true - all versions including beta and rc will be displayed */ /* listAll = false - only official stable release are displayed */ func installOption(listAll bool, custBinPath *string) { - tflist, _ := lib.GetTFList(hashiURL, listAll) //get list of versions recentVersions, _ := lib.GetRecentVersions() //get recent versions from RECENT file tflist = append(recentVersions, tflist...) //append recent versions to the top of the list