Skip to content

Commit

Permalink
Merge branch '315-opentofu-support' into 315-convert-recent-file-to-json
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewJohn committed May 27, 2024
2 parents 4a1a0be + ec24d69 commit a10eed5
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
1 change: 1 addition & 0 deletions lib/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ const (
InstallDir = ".terraform.versions"
recentFile = "RECENT"
tfDarwinArm64StartVersion = "1.0.2"
DefaultProductId = "terraform"
)
17 changes: 14 additions & 3 deletions lib/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,20 @@ func CheckFileExist(file string) bool {

// Unzip will decompress a zip archive, moving all files and folders
// within the zip file (parameter 1) to an output directory (parameter 2).
func Unzip(src string, dest string, fileToUnzip string) ([]string, error) {
// fileToUnzip (parameter 3) specifices the file within the zipfile to be extracted.
// This is optional and default to "terraform"
func Unzip(src string, dest string, fileToUnzipSlice ...string) ([]string, error) {
logger.Debugf("Unzipping file %q", src)

// Handle old signature of method, where fileToUnzip did not exist
legacyProduct := getLegacyProduct()
fileToUnzip := legacyProduct.GetExecutableName()
if len(fileToUnzipSlice) == 1 {
fileToUnzip = fileToUnzipSlice[0]
} else if len(fileToUnzipSlice) > 1 {
logger.Fatal("Too many args passed to Unzip")
}

var filenames []string

reader, err := zip.OpenReader(src)
Expand Down Expand Up @@ -79,9 +90,9 @@ func Unzip(src string, dest string, fileToUnzip string) ([]string, error) {
unzipWaitGroup.Wait()

if len(filenames) < 1 {
logger.Fatalf("Could not find terraform file in release archive to unzip")
logger.Fatalf("Could not find %s file in release archive to unzip", fileToUnzip)
} else if len(filenames) > 1 {
logger.Fatalf("Extracted more files than expected in release archive")
logger.Fatal("Extracted more files than expected in release archive")
}

return filenames, nil
Expand Down
38 changes: 22 additions & 16 deletions lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,6 @@ func ConvertExecutableExt(fpath string) string {
// installableBinLocation : Checks if terraform is installable in the location provided by the user.
// If not, create $HOME/bin. Ask users to add $HOME/bin to $PATH and return $HOME/bin as install location
func installableBinLocation(product Product, userBinPath string) string {

// @TODO Remove duplicate code in if homeBinExist and rationalise return to single instance

homedir := GetHomeDirectory() //get user's home directory
binDir := Path(userBinPath) //get path directory from binary path
binPathExist := CheckDirExist(binDir) //the default is /usr/local/bin but users can provide custom bin locations
Expand All @@ -170,18 +167,16 @@ func installableBinLocation(product Product, userBinPath string) string {

// IF: "/usr/local/bin" or `custom bin path` provided by user is non-writable, (binPathWritable == false), we will attempt to install terraform at the ~/bin location. See ELSE
if !binPathWritable {

homeBinExist := CheckDirExist(filepath.Join(homedir, "bin")) //check to see if ~/bin exist
if homeBinExist { //if ~/bin exist, install at ~/bin/terraform
logger.Infof("Installing terraform at %q", filepath.Join(homedir, "bin"))
return filepath.Join(homedir, "bin", product.GetExecutableName())
} else { //if ~/bin directory does not exist, create ~/bin for terraform installation
homeBinDir := filepath.Join(homedir, "bin")
if !CheckDirExist(homeBinDir) { //if ~/bin exist, install at ~/bin/terraform
logger.Noticef("Unable to write to %q", userBinPath)
logger.Infof("Creating bin directory at %q", filepath.Join(homedir, "bin"))
createDirIfNotExist(filepath.Join(homedir, "bin")) //create ~/bin
logger.Warnf("Run `export PATH=\"$PATH:%s\"` to append bin to $PATH", filepath.Join(homedir, "bin"))
return filepath.Join(homedir, "bin", product.GetExecutableName())
logger.Infof("Creating bin directory at %q", homeBinDir)
createDirIfNotExist(homeBinDir) //create ~/bin
logger.Warnf("Run `export PATH=\"$PATH:%s\"` to append bin to $PATH", homeBinDir)
}
logger.Infof("Installing %s at %q", product.GetName(), homeBinDir)
return filepath.Join(homeBinDir, product.GetExecutableName())

} else { // ELSE: the "/usr/local/bin" or custom path provided by user is writable, we will return installable location
return filepath.Join(userBinPath)
}
Expand All @@ -193,10 +188,13 @@ func installableBinLocation(product Product, userBinPath string) string {
}

// InstallLatestVersion install latest stable tf version
// This is a legacy method that is deprecated in favor of InstallLatestProductVersion
func InstallLatestVersion(dryRun bool, customBinaryPath, installPath string, mirrorURL string) {
product := getLegacyProduct()
InstallLatestProductVersion(product, dryRun, customBinaryPath, installPath, mirrorURL)
}

// InstallLatestProductVersion install latest stable tf version
func InstallLatestProductVersion(product Product, dryRun bool, customBinaryPath, installPath string, mirrorURL string) {
tfversion, _ := getTFLatest(mirrorURL)
if !dryRun {
Expand All @@ -205,10 +203,13 @@ func InstallLatestProductVersion(product Product, dryRun bool, customBinaryPath,
}

// InstallLatestImplicitVersion install latest - argument (version) must be provided
// This is a legacy method that is deprecated in favor of InstallLatestProductImplicitVersion
func InstallLatestImplicitVersion(dryRun bool, requestedVersion, customBinaryPath, installPath string, mirrorURL string, preRelease bool) {
product := getLegacyProduct()
InstallLatestProductImplicitVersion(product, dryRun, requestedVersion, customBinaryPath, installPath, mirrorURL, preRelease)
}

// InstallLatestProductImplicitVersion install latest - argument (version) must be provided
func InstallLatestProductImplicitVersion(product Product, dryRun bool, requestedVersion, customBinaryPath, installPath string, mirrorURL string, preRelease bool) {
_, err := version.NewConstraint(requestedVersion)
if err != nil {
Expand All @@ -222,13 +223,14 @@ func InstallLatestProductImplicitVersion(product Product, dryRun bool, requested
PrintInvalidMinorTFVersion()
}

// InstallVersion install product using legacy product
// InstallVersion install Terraform product
// This is a legacy method that is deprecated in favor of InstallProductVersion
func InstallVersion(dryRun bool, version, customBinaryPath, installPath, mirrorURL string) {
product := getLegacyProduct()
InstallProductVersion(product, dryRun, version, customBinaryPath, installPath, mirrorURL)
}

// InstallVersion install with provided version as argument
// InstallProductVersion install with provided version as argument
func InstallProductVersion(product Product, dryRun bool, version, customBinaryPath, installPath, mirrorURL string) {
logger.Debugf("Install version %s. Dry run: %s", version, strconv.FormatBool(dryRun))
if !dryRun {
Expand Down Expand Up @@ -265,6 +267,10 @@ func InstallProductVersion(product Product, dryRun bool, version, customBinaryPa
}
}

// InstallProductOption displays & installs tf version
// This is a legacy method that will be deprecated in favor of InstallProductOption
/* listAll = true - all versions including beta and rc will be displayed */
/* listAll = false - only official stable release are displayed */
func InstallOption(listAll, dryRun bool, customBinaryPath, installPath string, mirrorURL string) {
product := getLegacyProduct()
InstallProductOption(product, listAll, dryRun, customBinaryPath, installPath, mirrorURL)
Expand All @@ -275,7 +281,7 @@ type VersionSelector struct {
Label string
}

// InstallOption displays & installs tf version
// InstallProductOption displays & installs tf version
/* listAll = true - all versions including beta and rc will be displayed */
/* listAll = false - only official stable release are displayed */
func InstallProductOption(product Product, listAll, dryRun bool, customBinaryPath, installPath string, mirrorURL string) {
Expand Down
4 changes: 2 additions & 2 deletions lib/list_versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ func getVersionsFromBody(body string, preRelease bool, tfVersionList *tfVersionL
}
}

// getTFList : Get the list of available terraform version given the hashicorp url
// getTFList : Get the list of available versions given the mirror URL
func getTFList(mirrorURL string, preRelease bool) ([]string, error) {
logger.Debugf("Get list of terraform versions")
logger.Debug("Getting list of versions")
result, err := getTFURLBody(mirrorURL)
if err != nil {
return nil, err
Expand Down
7 changes: 3 additions & 4 deletions lib/param_parsing/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ func GetParameters() Params {
getopt.StringVarLong(&params.LatestStable, "latest-stable", 's', "Latest implicit version based on a constraint. Ex: tfswitch --latest-stable 0.13.0 downloads 0.13.7 and 0.13 downloads 0.15.5 (latest)")
getopt.BoolVarLong(&params.ListAllFlag, "list-all", 'l', "List all versions of terraform - including beta and rc")
getopt.StringVarLong(&params.LogLevel, "log-level", 'g', "Set loglevel for tfswitch. One of (INFO, NOTICE, DEBUG, TRACE)")

getopt.StringVarLong(&params.MirrorURL, "mirror", 'm', "install from a remote API other than the default. Default (based on product):\n"+strings.Join(defaultMirrors, "\n"))
getopt.BoolVarLong(&params.ShowLatestFlag, "show-latest", 'U', "Show latest stable version")
getopt.StringVarLong(&params.ShowLatestPre, "show-latest-pre", 'P', "Show latest pre-release implicit version. Ex: tfswitch --show-latest-pre 0.13 prints 0.13.0-rc1 (latest)")
getopt.StringVarLong(&params.ShowLatestStable, "show-latest-stable", 'S', "Show latest implicit version. Ex: tfswitch --show-latest-stable 0.13 prints 0.13.7 (latest)")
getopt.StringVarLong(&params.Product, "product", 'q', fmt.Sprintf("Specifies which product to use. Ex: `tfswitch --product terraform` will install Terraform. Options: (%s)", strings.Join(productIds, ", ")))
getopt.StringVarLong(&params.Product, "product", 'q', fmt.Sprintf("Specifies which product to use. Ex: `tfswitch --product opentofu` will install Terraform. Options: (%s). Default: %s", strings.Join(productIds, ", "), lib.DefaultProductId))
getopt.BoolVarLong(&params.VersionFlag, "version", 'v', "Displays the version of tfswitch")

// Parse the command line parameters to fetch stuff like chdir
Expand Down Expand Up @@ -89,7 +88,7 @@ func GetParameters() Params {
// Set defaults based on product
product := lib.GetProductById(params.Product)
if product == nil {
logger.Fatalf("Invalid product: " + params.Product)
logger.Fatalf("Invalid \"product\" configuration value: %q", params.Product)
} else { // Use else as there is a warning that params maybe nil, as it does not see Fatalf as a break condition
params.MirrorURL = product.GetDefaultMirrorUrl()
}
Expand Down Expand Up @@ -127,7 +126,7 @@ func initParams(params Params) Params {
params.ShowLatestPre = lib.DefaultLatest
params.ShowLatestStable = lib.DefaultLatest
params.Version = lib.DefaultLatest
params.Product = "terraform"
params.Product = lib.DefaultProductId
params.VersionFlag = false
return params
}
5 changes: 4 additions & 1 deletion lib/products.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,13 @@ func GetAllProducts() []Product {
return products
}

// Obtain produced used by deprecated public methods that
// now expect a product to be called.
// Once these public methods are removed, this function can be removed
func getLegacyProduct() Product {
product := GetProductById(legacyProductId)
if product == nil {
logger.Fatalf("Default product could not be found")
logger.Fatal("Default product could not be found")
}
return product
}

0 comments on commit a10eed5

Please sign in to comment.