UNPKG

@byu-oit/tfvm

Version:

A CLI app for easily switching between Terraform versions

114 lines (104 loc) 4.29 kB
import chalk from 'chalk' import deleteExecutable from '../util/deleteExecutable.js' import fs from 'node:fs/promises' import enquirer from 'enquirer' import { versionRegEx, LOWEST_OTF_VERSION } from '../util/constants.js' import getInstalledVersions from '../util/getInstalledVersions.js' import { TfvmFS } from '../util/TfvmFS.js' import getErrorMessage from '../util/errorChecker.js' import { installFromWeb } from './install.js' import getSettings from '../util/getSettings.js' import requiresOldAWSAuth from '../util/requiresOldAWSAuth.js' import { logger } from '../util/logger.js' import { getOS } from '../util/tfvmOS.js' import * as semver from 'semver' const os = getOS() let openTofuCheck = false async function use (version) { try { await useVersion(version) } catch (error) { logger.fatal(error, `Fatal error when running "use" command where version=${version}: `) getErrorMessage(error) } } export default use /** * Switch to (and install if necessary) the desired version in X.X.X format * (Reused by the 'detect' command) * @param version */ export async function useVersion (version) { const versionWithV = 'v' + version if (!versionRegEx.test(versionWithV)) { console.log(chalk.red.bold('Invalid version syntax')) } else { const installedVersions = await getInstalledVersions(version) const settings = await getSettings() openTofuCheck = settings.useOpenTofu && semver.gte(version, LOWEST_OTF_VERSION) // delete tofu executable if using a version lower than 1.6.0 if (settings.useOpenTofu && semver.lt(version, LOWEST_OTF_VERSION)) { await deleteExecutable(false) } else if (openTofuCheck) { await deleteExecutable(true) } if (!installedVersions.includes(versionWithV)) { const successfullyInstalled = await installNewVersion(version) if (!successfullyInstalled) return } await switchVersionTo(version) } } /** * Install a given terraform version * @param {string} version a version string in X.X.X format * @returns {Promise<boolean>} true if the user opted to install the version, false if they did not */ export async function installNewVersion (version) { const settings = await getSettings() const openTofuCheck = settings.useOpenTofu && semver.gte(version, LOWEST_OTF_VERSION) console.log(chalk.white.bold(`${openTofuCheck ? 'OpenTofu' : 'Terraform'} v${version} is not installed. Would you like to install it?`)) const installToggle = new enquirer.Toggle({ disabled: 'Yes', enabled: 'No' }) if (await installToggle.run()) { console.log(chalk.white.bold(`No action taken. Use 'tfvm install ${version}' to install ${settings.useOpenTofu ? 'opentofu' : 'terraform'} v${version}`)) return false } else { await installFromWeb(version, false) return true } } /** * Switches to a version of terraform * @param {string} version The tf version to switch to in X.X.X format * @returns {Promise<void>} */ export async function switchVersionTo (version) { const settings = await getSettings() if (version[0] === 'v') version = version.substring(1) if (openTofuCheck) { await TfvmFS.createOtfAppDataDir() await TfvmFS.deleteCurrentOtfExe() await fs.copyFile( os.getPath(os.getOtfVersionsDir(), 'v' + version, os.getOtfExecutableName()), // source file os.getPath(os.getOpenTofuDir(), os.getOtfExecutableName()) // destination file ) } else { await TfvmFS.createTfAppDataDir() await TfvmFS.deleteCurrentTfExe() await fs.copyFile( os.getPath(os.getTfVersionsDir(), 'v' + version, os.getTFExecutableName()), // source file os.getPath(os.getTerraformDir(), os.getTFExecutableName()) // destination file ) } console.log(chalk.cyan.bold(`Now using ${openTofuCheck ? 'opentofu' : 'terraform'} v${version} (${os.getBitWidth()}-bit)`)) if (requiresOldAWSAuth(version) && !settings.disableAWSWarnings) { console.log(chalk.yellow.bold('Warning: This tf version is not compatible with the newest ' + 'AWS CLI authentication methods (e.g. aws sso login). Use short-term credentials instead.')) if (!settings.disableSettingPrompts) { console.log(chalk.yellow.bold('To disable this error run \'tfvm config disableAWSWarnings=true\'')) } } }