@fredlackey/devutils 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/package.json +1 -1
- package/src/commands/install.js +374 -36
- package/src/installs/adobe-creative-cloud.js +527 -25
- package/src/installs/adobe-creative-cloud.md +605 -0
- package/src/installs/appcleaner.js +303 -26
- package/src/installs/appcleaner.md +699 -0
- package/src/installs/apt-transport-https.js +390 -0
- package/src/installs/apt-transport-https.md +678 -0
- package/src/installs/atomicparsley.js +624 -26
- package/src/installs/atomicparsley.md +795 -0
- package/src/installs/aws-cli.js +779 -26
- package/src/installs/aws-cli.md +727 -0
- package/src/installs/balena-etcher.js +688 -26
- package/src/installs/balena-etcher.md +761 -0
- package/src/installs/bambu-studio.js +912 -26
- package/src/installs/bambu-studio.md +780 -0
- package/src/installs/bash-completion.js +554 -23
- package/src/installs/bash-completion.md +833 -0
- package/src/installs/bash.js +399 -26
- package/src/installs/bash.md +993 -0
- package/src/installs/beyond-compare.js +585 -26
- package/src/installs/beyond-compare.md +813 -0
- package/src/installs/build-essential.js +511 -26
- package/src/installs/build-essential.md +977 -0
- package/src/installs/ca-certificates.js +618 -0
- package/src/installs/ca-certificates.md +937 -0
- package/src/installs/caffeine.js +490 -26
- package/src/installs/caffeine.md +839 -0
- package/src/installs/camtasia.js +577 -25
- package/src/installs/camtasia.md +762 -0
- package/src/installs/chatgpt.js +458 -26
- package/src/installs/chatgpt.md +814 -0
- package/src/installs/chocolatey.js +447 -0
- package/src/installs/chocolatey.md +661 -0
- package/src/installs/chrome-canary.js +472 -26
- package/src/installs/chrome-canary.md +641 -0
- package/src/installs/chromium.js +645 -26
- package/src/installs/chromium.md +838 -0
- package/src/installs/claude-code.js +558 -26
- package/src/installs/claude-code.md +1173 -0
- package/src/installs/curl.js +361 -26
- package/src/installs/curl.md +714 -0
- package/src/installs/cursor.js +561 -26
- package/src/installs/cursor.md +970 -0
- package/src/installs/dbschema.js +674 -26
- package/src/installs/dbschema.md +925 -0
- package/src/installs/dependencies.md +435 -0
- package/src/installs/development-tools.js +600 -0
- package/src/installs/development-tools.md +977 -0
- package/src/installs/docker.js +1010 -25
- package/src/installs/docker.md +1109 -0
- package/src/installs/drawio.js +1001 -26
- package/src/installs/drawio.md +795 -0
- package/src/installs/elmedia-player.js +328 -25
- package/src/installs/elmedia-player.md +556 -0
- package/src/installs/ffmpeg.js +870 -25
- package/src/installs/ffmpeg.md +852 -0
- package/src/installs/file.js +464 -0
- package/src/installs/file.md +987 -0
- package/src/installs/gemini-cli.js +793 -26
- package/src/installs/gemini-cli.md +1153 -0
- package/src/installs/git.js +382 -26
- package/src/installs/git.md +907 -0
- package/src/installs/gitego.js +931 -26
- package/src/installs/gitego.md +1172 -0
- package/src/installs/go.js +913 -26
- package/src/installs/go.md +958 -0
- package/src/installs/google-chrome.js +801 -25
- package/src/installs/google-chrome.md +862 -0
- package/src/installs/gpg.js +412 -73
- package/src/installs/gpg.md +1056 -0
- package/src/installs/homebrew.js +1015 -26
- package/src/installs/homebrew.md +988 -0
- package/src/installs/imageoptim.js +950 -26
- package/src/installs/imageoptim.md +1119 -0
- package/src/installs/installers.json +2297 -0
- package/src/installs/jq.js +382 -26
- package/src/installs/jq.md +809 -0
- package/src/installs/keyboard-maestro.js +701 -26
- package/src/installs/keyboard-maestro.md +825 -0
- package/src/installs/latex.js +771 -26
- package/src/installs/latex.md +1095 -0
- package/src/installs/lftp.js +338 -26
- package/src/installs/lftp.md +907 -0
- package/src/installs/lsb-release.js +346 -0
- package/src/installs/lsb-release.md +814 -0
- package/src/installs/messenger.js +829 -26
- package/src/installs/messenger.md +900 -0
- package/src/installs/microsoft-office.js +550 -26
- package/src/installs/microsoft-office.md +760 -0
- package/src/installs/microsoft-teams.js +782 -25
- package/src/installs/microsoft-teams.md +886 -0
- package/src/installs/node.js +886 -26
- package/src/installs/node.md +1153 -0
- package/src/installs/nordpass.js +698 -26
- package/src/installs/nordpass.md +921 -0
- package/src/installs/nvm.js +977 -26
- package/src/installs/nvm.md +1057 -0
- package/src/installs/openssh.js +734 -64
- package/src/installs/openssh.md +1056 -0
- package/src/installs/pandoc.js +644 -26
- package/src/installs/pandoc.md +1036 -0
- package/src/installs/pinentry.js +492 -26
- package/src/installs/pinentry.md +1142 -0
- package/src/installs/pngyu.js +851 -26
- package/src/installs/pngyu.md +896 -0
- package/src/installs/postman.js +781 -26
- package/src/installs/postman.md +940 -0
- package/src/installs/procps.js +425 -0
- package/src/installs/procps.md +851 -0
- package/src/installs/safari-tech-preview.js +355 -25
- package/src/installs/safari-tech-preview.md +533 -0
- package/src/installs/sfnt2woff.js +640 -26
- package/src/installs/sfnt2woff.md +795 -0
- package/src/installs/shellcheck.js +463 -26
- package/src/installs/shellcheck.md +1005 -0
- package/src/installs/slack.js +722 -25
- package/src/installs/slack.md +865 -0
- package/src/installs/snagit.js +566 -25
- package/src/installs/snagit.md +844 -0
- package/src/installs/software-properties-common.js +372 -0
- package/src/installs/software-properties-common.md +805 -0
- package/src/installs/spotify.js +858 -25
- package/src/installs/spotify.md +901 -0
- package/src/installs/studio-3t.js +803 -26
- package/src/installs/studio-3t.md +918 -0
- package/src/installs/sublime-text.js +780 -25
- package/src/installs/sublime-text.md +914 -0
- package/src/installs/superwhisper.js +687 -25
- package/src/installs/superwhisper.md +630 -0
- package/src/installs/tailscale.js +727 -26
- package/src/installs/tailscale.md +1100 -0
- package/src/installs/tar.js +389 -0
- package/src/installs/tar.md +946 -0
- package/src/installs/termius.js +780 -26
- package/src/installs/termius.md +844 -0
- package/src/installs/terraform.js +761 -26
- package/src/installs/terraform.md +899 -0
- package/src/installs/tidal.js +752 -25
- package/src/installs/tidal.md +864 -0
- package/src/installs/tmux.js +328 -26
- package/src/installs/tmux.md +1030 -0
- package/src/installs/tree.js +393 -26
- package/src/installs/tree.md +833 -0
- package/src/installs/unzip.js +460 -0
- package/src/installs/unzip.md +879 -0
- package/src/installs/vim.js +403 -26
- package/src/installs/vim.md +1040 -0
- package/src/installs/vlc.js +803 -26
- package/src/installs/vlc.md +927 -0
- package/src/installs/vscode.js +825 -26
- package/src/installs/vscode.md +1002 -0
- package/src/installs/wget.js +415 -0
- package/src/installs/wget.md +791 -0
- package/src/installs/whatsapp.js +710 -25
- package/src/installs/whatsapp.md +854 -0
- package/src/installs/winpty.js +352 -0
- package/src/installs/winpty.md +620 -0
- package/src/installs/woff2.js +535 -26
- package/src/installs/woff2.md +977 -0
- package/src/installs/wsl.js +572 -0
- package/src/installs/wsl.md +699 -0
- package/src/installs/xcode-clt.js +520 -0
- package/src/installs/xcode-clt.md +351 -0
- package/src/installs/xcode.js +542 -26
- package/src/installs/xcode.md +573 -0
- package/src/installs/yarn.js +806 -26
- package/src/installs/yarn.md +1074 -0
- package/src/installs/yq.js +636 -26
- package/src/installs/yq.md +944 -0
- package/src/installs/yt-dlp.js +683 -26
- package/src/installs/yt-dlp.md +946 -0
- package/src/installs/yum-utils.js +297 -0
- package/src/installs/yum-utils.md +648 -0
- package/src/installs/zoom.js +740 -25
- package/src/installs/zoom.md +884 -0
- package/src/scripts/README.md +567 -45
- package/src/scripts/STATUS.md +208 -0
- package/src/scripts/afk.js +395 -7
- package/src/scripts/backup-all.js +731 -9
- package/src/scripts/backup-source.js +711 -8
- package/src/scripts/brewd.js +373 -7
- package/src/scripts/brewi.js +505 -9
- package/src/scripts/brewr.js +512 -9
- package/src/scripts/brews.js +462 -9
- package/src/scripts/brewu.js +488 -7
- package/src/scripts/c.js +185 -7
- package/src/scripts/ccurl.js +325 -8
- package/src/scripts/certbot-crontab-init.js +488 -8
- package/src/scripts/certbot-init.js +641 -9
- package/src/scripts/ch.js +339 -7
- package/src/scripts/claude-danger.js +253 -8
- package/src/scripts/clean-dev.js +419 -8
- package/src/scripts/clear-dns-cache.js +525 -7
- package/src/scripts/clone.js +417 -7
- package/src/scripts/code-all.js +420 -7
- package/src/scripts/count-files.js +195 -8
- package/src/scripts/count-folders.js +195 -8
- package/src/scripts/count.js +248 -8
- package/src/scripts/d.js +203 -7
- package/src/scripts/datauri.js +373 -8
- package/src/scripts/delete-files.js +363 -7
- package/src/scripts/docker-clean.js +410 -8
- package/src/scripts/dp.js +426 -7
- package/src/scripts/e.js +375 -9
- package/src/scripts/empty-trash.js +497 -7
- package/src/scripts/evm.js +428 -9
- package/src/scripts/fetch-github-repos.js +441 -10
- package/src/scripts/get-channel.js +329 -8
- package/src/scripts/get-course.js +384 -11
- package/src/scripts/get-dependencies.js +290 -9
- package/src/scripts/get-folder.js +783 -10
- package/src/scripts/get-tunes.js +411 -10
- package/src/scripts/get-video.js +352 -9
- package/src/scripts/git-backup.js +561 -9
- package/src/scripts/git-clone.js +477 -9
- package/src/scripts/git-pup.js +303 -7
- package/src/scripts/git-push.js +380 -8
- package/src/scripts/h.js +607 -9
- package/src/scripts/hide-desktop-icons.js +483 -7
- package/src/scripts/hide-hidden-files.js +522 -7
- package/src/scripts/install-dependencies-from.js +440 -9
- package/src/scripts/ips.js +647 -10
- package/src/scripts/iso.js +354 -8
- package/src/scripts/killni.js +561 -7
- package/src/scripts/ll.js +451 -8
- package/src/scripts/local-ip.js +310 -8
- package/src/scripts/m.js +508 -8
- package/src/scripts/map.js +293 -8
- package/src/scripts/mkd.js +287 -7
- package/src/scripts/ncu-update-all.js +441 -8
- package/src/scripts/nginx-init.js +702 -12
- package/src/scripts/npmi.js +366 -7
- package/src/scripts/o.js +495 -8
- package/src/scripts/org-by-date.js +321 -7
- package/src/scripts/p.js +208 -7
- package/src/scripts/packages.js +313 -8
- package/src/scripts/path.js +209 -7
- package/src/scripts/ports.js +582 -8
- package/src/scripts/q.js +290 -8
- package/src/scripts/refresh-files.js +378 -10
- package/src/scripts/remove-smaller-files.js +500 -8
- package/src/scripts/rename-files-with-date.js +517 -9
- package/src/scripts/resize-image.js +523 -9
- package/src/scripts/rm-safe.js +653 -8
- package/src/scripts/s.js +525 -9
- package/src/scripts/set-git-public.js +349 -7
- package/src/scripts/show-desktop-icons.js +459 -7
- package/src/scripts/show-hidden-files.js +456 -7
- package/src/scripts/tpa.js +265 -8
- package/src/scripts/tpo.js +264 -7
- package/src/scripts/u.js +489 -7
- package/src/scripts/vpush.js +422 -8
- package/src/scripts/y.js +267 -7
- package/src/utils/common/os.js +94 -2
- package/src/utils/ubuntu/apt.js +13 -7
- package/src/utils/windows/choco.js +82 -26
- package/src/utils/windows/winget.js +89 -27
|
@@ -1,44 +1,779 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @fileoverview Install Terraform.
|
|
4
|
+
* @fileoverview Install Terraform across supported platforms.
|
|
5
5
|
* @module installs/terraform
|
|
6
|
+
*
|
|
7
|
+
* Terraform is an open-source infrastructure as code (IaC) tool created by HashiCorp.
|
|
8
|
+
* It enables you to define, provision, and manage cloud infrastructure across multiple
|
|
9
|
+
* providers (AWS, Azure, GCP, and many others) using declarative configuration files
|
|
10
|
+
* written in HashiCorp Configuration Language (HCL).
|
|
11
|
+
*
|
|
12
|
+
* Key capabilities:
|
|
13
|
+
* - Multi-cloud provisioning: Manage resources across AWS, Azure, GCP, Kubernetes, and 3,000+ providers
|
|
14
|
+
* - State management: Track infrastructure state to detect drift and enable safe updates
|
|
15
|
+
* - Dependency resolution: Automatically determine the order of resource creation and destruction
|
|
16
|
+
* - Module ecosystem: Reuse infrastructure patterns through the Terraform Registry
|
|
17
|
+
*
|
|
18
|
+
* Supported platforms:
|
|
19
|
+
* - macOS: Homebrew (HashiCorp tap)
|
|
20
|
+
* - Ubuntu/Debian: APT (HashiCorp repository)
|
|
21
|
+
* - Raspberry Pi OS: Manual binary installation (ARM)
|
|
22
|
+
* - Amazon Linux/RHEL: YUM (HashiCorp repository)
|
|
23
|
+
* - Windows: Chocolatey
|
|
24
|
+
* - WSL (Ubuntu): APT (HashiCorp repository)
|
|
25
|
+
* - Git Bash: Windows installation via Chocolatey/PowerShell
|
|
6
26
|
*/
|
|
7
27
|
|
|
8
28
|
const os = require('../utils/common/os');
|
|
29
|
+
const shell = require('../utils/common/shell');
|
|
30
|
+
const brew = require('../utils/macos/brew');
|
|
31
|
+
const apt = require('../utils/ubuntu/apt');
|
|
32
|
+
const choco = require('../utils/windows/choco');
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The name of the Terraform command used to verify installation
|
|
36
|
+
* @constant {string}
|
|
37
|
+
*/
|
|
38
|
+
const TERRAFORM_COMMAND = 'terraform';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The HashiCorp Homebrew tap repository name
|
|
42
|
+
* @constant {string}
|
|
43
|
+
*/
|
|
44
|
+
const HASHICORP_TAP = 'hashicorp/tap';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The Homebrew formula name for Terraform from HashiCorp tap
|
|
48
|
+
* @constant {string}
|
|
49
|
+
*/
|
|
50
|
+
const BREW_FORMULA_NAME = 'hashicorp/tap/terraform';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The Chocolatey package name for Terraform
|
|
54
|
+
* @constant {string}
|
|
55
|
+
*/
|
|
56
|
+
const CHOCO_PACKAGE_NAME = 'terraform';
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The Terraform version to use for manual binary installations (Raspberry Pi)
|
|
60
|
+
* Update this when newer versions are released
|
|
61
|
+
* @constant {string}
|
|
62
|
+
*/
|
|
63
|
+
const TERRAFORM_VERSION = '1.14.3';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if Terraform is already installed by verifying the terraform command exists
|
|
67
|
+
*
|
|
68
|
+
* This is a quick synchronous check that works across all platforms by looking
|
|
69
|
+
* for the terraform executable in the system PATH.
|
|
70
|
+
*
|
|
71
|
+
* @returns {boolean} True if Terraform is installed and accessible in PATH
|
|
72
|
+
*/
|
|
73
|
+
function isTerraformInstalled() {
|
|
74
|
+
return shell.commandExists(TERRAFORM_COMMAND);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get the installed version of Terraform
|
|
79
|
+
*
|
|
80
|
+
* Executes 'terraform --version' and parses the output to extract the version number.
|
|
81
|
+
* Returns null if Terraform is not installed or the version cannot be determined.
|
|
82
|
+
*
|
|
83
|
+
* @returns {Promise<string|null>} The version string (e.g., "1.14.3") or null if not installed
|
|
84
|
+
*/
|
|
85
|
+
async function getTerraformVersion() {
|
|
86
|
+
// First check if the command exists to avoid unnecessary exec calls
|
|
87
|
+
if (!isTerraformInstalled()) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const result = await shell.exec('terraform --version');
|
|
92
|
+
if (result.code === 0 && result.stdout) {
|
|
93
|
+
// Output format: "Terraform v1.14.3\non darwin_arm64"
|
|
94
|
+
const match = result.stdout.match(/Terraform v([\d.]+)/);
|
|
95
|
+
return match ? match[1] : null;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Install Terraform on macOS using Homebrew with the official HashiCorp tap
|
|
102
|
+
*
|
|
103
|
+
* This function:
|
|
104
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
105
|
+
* 2. Verifies Homebrew is available
|
|
106
|
+
* 3. Adds the HashiCorp tap if not already present
|
|
107
|
+
* 4. Installs Terraform from the HashiCorp tap
|
|
108
|
+
* 5. Verifies the installation succeeded
|
|
109
|
+
*
|
|
110
|
+
* Prerequisites:
|
|
111
|
+
* - macOS 11 (Big Sur) or later
|
|
112
|
+
* - Homebrew package manager installed
|
|
113
|
+
* - Terminal access
|
|
114
|
+
*
|
|
115
|
+
* Using the HashiCorp tap ensures you receive official releases directly from HashiCorp
|
|
116
|
+
* rather than community-maintained packages.
|
|
117
|
+
*
|
|
118
|
+
* @returns {Promise<void>}
|
|
119
|
+
*/
|
|
120
|
+
async function install_macos() {
|
|
121
|
+
// Check if Terraform is already installed (idempotency check)
|
|
122
|
+
if (isTerraformInstalled()) {
|
|
123
|
+
const version = await getTerraformVersion();
|
|
124
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Verify Homebrew is available before proceeding
|
|
129
|
+
if (!brew.isInstalled()) {
|
|
130
|
+
console.log('Homebrew is not installed. Please install Homebrew first.');
|
|
131
|
+
console.log('Run: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Add the HashiCorp tap to get official Terraform releases
|
|
136
|
+
// The tap command is idempotent - it will succeed even if already tapped
|
|
137
|
+
console.log('Adding HashiCorp Homebrew tap...');
|
|
138
|
+
const tapResult = await brew.tap(HASHICORP_TAP);
|
|
139
|
+
if (!tapResult.success) {
|
|
140
|
+
console.log('Failed to add HashiCorp tap.');
|
|
141
|
+
console.log(tapResult.output);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Install Terraform from the HashiCorp tap
|
|
146
|
+
console.log('Installing Terraform via Homebrew...');
|
|
147
|
+
const installResult = await brew.install(BREW_FORMULA_NAME);
|
|
148
|
+
|
|
149
|
+
if (!installResult.success) {
|
|
150
|
+
console.log('Failed to install Terraform via Homebrew.');
|
|
151
|
+
console.log(installResult.output);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Verify the installation succeeded by checking if the command now exists
|
|
156
|
+
if (isTerraformInstalled()) {
|
|
157
|
+
const version = await getTerraformVersion();
|
|
158
|
+
console.log(`Terraform installed successfully (version ${version}).`);
|
|
159
|
+
} else {
|
|
160
|
+
console.log('Installation completed but Terraform command not found.');
|
|
161
|
+
console.log('You may need to restart your terminal or add Homebrew to your PATH.');
|
|
162
|
+
console.log('Run: eval "$(/opt/homebrew/bin/brew shellenv)"');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Install Terraform on Ubuntu/Debian using APT with the official HashiCorp repository
|
|
168
|
+
*
|
|
169
|
+
* This function:
|
|
170
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
171
|
+
* 2. Installs prerequisite packages (gnupg, software-properties-common, wget)
|
|
172
|
+
* 3. Downloads and installs HashiCorp's GPG key for package verification
|
|
173
|
+
* 4. Adds the official HashiCorp APT repository
|
|
174
|
+
* 5. Updates package lists and installs Terraform
|
|
175
|
+
* 6. Verifies the installation succeeded
|
|
176
|
+
*
|
|
177
|
+
* Prerequisites:
|
|
178
|
+
* - Ubuntu 20.04 or later, or Debian 10 (Buster) or later (64-bit)
|
|
179
|
+
* - sudo privileges
|
|
180
|
+
* - Internet connectivity
|
|
181
|
+
*
|
|
182
|
+
* IMPORTANT: Do not use 'snap install terraform'. The Snap package is maintained
|
|
183
|
+
* by the community, not HashiCorp. Use the official HashiCorp APT repository
|
|
184
|
+
* for production environments.
|
|
185
|
+
*
|
|
186
|
+
* @returns {Promise<void>}
|
|
187
|
+
*/
|
|
188
|
+
async function install_ubuntu() {
|
|
189
|
+
// Check if Terraform is already installed (idempotency check)
|
|
190
|
+
if (isTerraformInstalled()) {
|
|
191
|
+
const version = await getTerraformVersion();
|
|
192
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Step 1: Install prerequisite packages for GPG key management
|
|
197
|
+
console.log('Installing prerequisite packages...');
|
|
198
|
+
const updateResult = await shell.exec('sudo DEBIAN_FRONTEND=noninteractive apt-get update -y');
|
|
199
|
+
if (updateResult.code !== 0) {
|
|
200
|
+
console.log('Warning: Failed to update package lists. Continuing with installation...');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const prereqResult = await shell.exec(
|
|
204
|
+
'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y gnupg software-properties-common wget'
|
|
205
|
+
);
|
|
206
|
+
if (prereqResult.code !== 0) {
|
|
207
|
+
console.log('Failed to install prerequisite packages.');
|
|
208
|
+
console.log(prereqResult.stderr || prereqResult.stdout);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Step 2: Download and install HashiCorp's GPG key
|
|
213
|
+
console.log('Adding HashiCorp GPG key...');
|
|
214
|
+
const gpgResult = await shell.exec(
|
|
215
|
+
'wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg'
|
|
216
|
+
);
|
|
217
|
+
if (gpgResult.code !== 0) {
|
|
218
|
+
console.log('Failed to add HashiCorp GPG key.');
|
|
219
|
+
console.log(gpgResult.stderr || gpgResult.stdout);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Step 3: Add the HashiCorp APT repository
|
|
224
|
+
// The repository URL uses the distribution codename from /etc/os-release
|
|
225
|
+
console.log('Adding HashiCorp APT repository...');
|
|
226
|
+
const repoResult = await shell.exec(
|
|
227
|
+
'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] ' +
|
|
228
|
+
'https://apt.releases.hashicorp.com $(grep -oP \'(?<=UBUNTU_CODENAME=).*\' /etc/os-release || lsb_release -cs) main" | ' +
|
|
229
|
+
'sudo tee /etc/apt/sources.list.d/hashicorp.list'
|
|
230
|
+
);
|
|
231
|
+
if (repoResult.code !== 0) {
|
|
232
|
+
console.log('Failed to add HashiCorp repository.');
|
|
233
|
+
console.log(repoResult.stderr || repoResult.stdout);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Step 4: Update package lists and install Terraform
|
|
238
|
+
console.log('Updating package lists...');
|
|
239
|
+
const updateResult2 = await shell.exec('sudo DEBIAN_FRONTEND=noninteractive apt-get update -y');
|
|
240
|
+
if (updateResult2.code !== 0) {
|
|
241
|
+
console.log('Warning: Failed to update package lists after adding repository.');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log('Installing Terraform...');
|
|
245
|
+
const installResult = await shell.exec('sudo DEBIAN_FRONTEND=noninteractive apt-get install -y terraform');
|
|
246
|
+
if (installResult.code !== 0) {
|
|
247
|
+
console.log('Failed to install Terraform.');
|
|
248
|
+
console.log(installResult.stderr || installResult.stdout);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Verify the installation succeeded
|
|
253
|
+
if (isTerraformInstalled()) {
|
|
254
|
+
const version = await getTerraformVersion();
|
|
255
|
+
console.log(`Terraform installed successfully (version ${version}).`);
|
|
256
|
+
} else {
|
|
257
|
+
console.log('Installation completed but Terraform command not found.');
|
|
258
|
+
console.log('You may need to restart your terminal session.');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Install Terraform on Ubuntu running in WSL (Windows Subsystem for Linux)
|
|
264
|
+
*
|
|
265
|
+
* WSL Ubuntu follows the same process as native Ubuntu using the HashiCorp APT
|
|
266
|
+
* repository. This function delegates to install_ubuntu() because WSL provides
|
|
267
|
+
* a full Ubuntu environment with APT package management.
|
|
268
|
+
*
|
|
269
|
+
* Prerequisites:
|
|
270
|
+
* - Windows Subsystem for Linux with Ubuntu installed
|
|
271
|
+
* - WSL 2 recommended for best performance
|
|
272
|
+
* - sudo privileges within WSL
|
|
273
|
+
*
|
|
274
|
+
* Note: Terraform installed in WSL is only available within WSL. If you need
|
|
275
|
+
* Terraform in Windows PowerShell, install it separately using Chocolatey.
|
|
276
|
+
*
|
|
277
|
+
* @returns {Promise<void>}
|
|
278
|
+
*/
|
|
279
|
+
async function install_ubuntu_wsl() {
|
|
280
|
+
// WSL Ubuntu uses the same APT-based installation as native Ubuntu
|
|
281
|
+
await install_ubuntu();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Install Terraform on Raspberry Pi OS using manual binary installation
|
|
286
|
+
*
|
|
287
|
+
* This function:
|
|
288
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
289
|
+
* 2. Detects the system architecture (aarch64 for 64-bit, armv7l for 32-bit)
|
|
290
|
+
* 3. Downloads the appropriate ARM binary from HashiCorp releases
|
|
291
|
+
* 4. Extracts and installs the binary to /usr/local/bin
|
|
292
|
+
* 5. Verifies the installation succeeded
|
|
293
|
+
*
|
|
294
|
+
* Prerequisites:
|
|
295
|
+
* - Raspberry Pi OS (64-bit strongly recommended) - Bookworm or Bullseye
|
|
296
|
+
* - Raspberry Pi 3B+ or later (64-bit capable hardware)
|
|
297
|
+
* - sudo privileges
|
|
298
|
+
*
|
|
299
|
+
* IMPORTANT: The HashiCorp APT repository provides packages only for AMD64 (x86_64)
|
|
300
|
+
* architecture. For ARM-based Raspberry Pi systems, manual binary installation
|
|
301
|
+
* with the Linux ARM64 or ARM binary is required.
|
|
302
|
+
*
|
|
303
|
+
* @returns {Promise<void>}
|
|
304
|
+
*/
|
|
305
|
+
async function install_raspbian() {
|
|
306
|
+
// Check if Terraform is already installed (idempotency check)
|
|
307
|
+
if (isTerraformInstalled()) {
|
|
308
|
+
const version = await getTerraformVersion();
|
|
309
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Detect the system architecture to download the correct binary
|
|
314
|
+
const archResult = await shell.exec('uname -m');
|
|
315
|
+
const arch = archResult.stdout.trim();
|
|
316
|
+
|
|
317
|
+
// Determine the correct binary suffix based on architecture
|
|
318
|
+
// aarch64 = 64-bit ARM (recommended), armv7l = 32-bit ARM
|
|
319
|
+
let binaryArch;
|
|
320
|
+
if (arch === 'aarch64') {
|
|
321
|
+
binaryArch = 'linux_arm64';
|
|
322
|
+
} else if (arch === 'armv7l') {
|
|
323
|
+
binaryArch = 'linux_arm';
|
|
324
|
+
} else if (arch === 'x86_64') {
|
|
325
|
+
// For x86_64 on Raspberry Pi (unlikely but possible with emulation)
|
|
326
|
+
binaryArch = 'linux_amd64';
|
|
327
|
+
} else {
|
|
328
|
+
console.log(`Unsupported architecture: ${arch}`);
|
|
329
|
+
console.log('Terraform is available for arm64 (aarch64) and arm (armv7l) architectures.');
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
console.log(`Detected architecture: ${arch} (using ${binaryArch} binary)`);
|
|
334
|
+
|
|
335
|
+
// Install unzip if not present (required to extract the download)
|
|
336
|
+
if (!shell.commandExists('unzip')) {
|
|
337
|
+
console.log('Installing unzip...');
|
|
338
|
+
const unzipResult = await shell.exec('sudo DEBIAN_FRONTEND=noninteractive apt-get update -y && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y unzip');
|
|
339
|
+
if (unzipResult.code !== 0) {
|
|
340
|
+
console.log('Failed to install unzip.');
|
|
341
|
+
console.log(unzipResult.stderr || unzipResult.stdout);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Download the Terraform binary from HashiCorp releases
|
|
347
|
+
const downloadUrl = `https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_${binaryArch}.zip`;
|
|
348
|
+
console.log(`Downloading Terraform ${TERRAFORM_VERSION}...`);
|
|
349
|
+
const downloadResult = await shell.exec(`wget -q "${downloadUrl}" -O /tmp/terraform.zip`);
|
|
350
|
+
if (downloadResult.code !== 0) {
|
|
351
|
+
console.log('Failed to download Terraform binary.');
|
|
352
|
+
console.log(downloadResult.stderr || downloadResult.stdout);
|
|
353
|
+
console.log('');
|
|
354
|
+
console.log('If download fails with certificate error, try:');
|
|
355
|
+
console.log('sudo apt-get install -y ca-certificates');
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Extract the binary to /tmp
|
|
360
|
+
console.log('Extracting Terraform...');
|
|
361
|
+
const extractResult = await shell.exec('unzip -o -q /tmp/terraform.zip -d /tmp');
|
|
362
|
+
if (extractResult.code !== 0) {
|
|
363
|
+
console.log('Failed to extract Terraform binary.');
|
|
364
|
+
console.log(extractResult.stderr || extractResult.stdout);
|
|
365
|
+
await shell.exec('rm -f /tmp/terraform.zip');
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Move the binary to /usr/local/bin and set executable permissions
|
|
370
|
+
console.log('Installing Terraform to /usr/local/bin...');
|
|
371
|
+
const installResult = await shell.exec('sudo mv /tmp/terraform /usr/local/bin/ && sudo chmod +x /usr/local/bin/terraform');
|
|
372
|
+
if (installResult.code !== 0) {
|
|
373
|
+
console.log('Failed to install Terraform binary.');
|
|
374
|
+
console.log(installResult.stderr || installResult.stdout);
|
|
375
|
+
await shell.exec('rm -f /tmp/terraform.zip /tmp/terraform');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Clean up downloaded files
|
|
380
|
+
await shell.exec('rm -f /tmp/terraform.zip');
|
|
381
|
+
|
|
382
|
+
// Verify the installation succeeded
|
|
383
|
+
if (isTerraformInstalled()) {
|
|
384
|
+
const version = await getTerraformVersion();
|
|
385
|
+
console.log(`Terraform installed successfully (version ${version}).`);
|
|
386
|
+
} else {
|
|
387
|
+
console.log('Installation completed but Terraform command not found.');
|
|
388
|
+
console.log('Ensure /usr/local/bin is in your PATH:');
|
|
389
|
+
console.log('echo \'export PATH=$PATH:/usr/local/bin\' >> ~/.bashrc && source ~/.bashrc');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Install Terraform on Fedora using manual binary installation
|
|
395
|
+
*
|
|
396
|
+
* This function:
|
|
397
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
398
|
+
* 2. Downloads the appropriate AMD64 binary from HashiCorp releases
|
|
399
|
+
* 3. Extracts and installs the binary to /usr/local/bin
|
|
400
|
+
* 4. Verifies the installation succeeded
|
|
401
|
+
*
|
|
402
|
+
* Prerequisites:
|
|
403
|
+
* - Fedora 37 or later (64-bit)
|
|
404
|
+
* - sudo privileges
|
|
405
|
+
*
|
|
406
|
+
* IMPORTANT: HashiCorp's RPM repositories do not consistently support all Fedora
|
|
407
|
+
* versions. While Fedora 41+ may have repository support, older versions like
|
|
408
|
+
* Fedora 39 do not. Manual binary installation ensures compatibility across
|
|
409
|
+
* all Fedora versions.
|
|
410
|
+
*
|
|
411
|
+
* @returns {Promise<void>}
|
|
412
|
+
*/
|
|
413
|
+
async function install_fedora() {
|
|
414
|
+
// Check if Terraform is already installed (idempotency check)
|
|
415
|
+
if (isTerraformInstalled()) {
|
|
416
|
+
const version = await getTerraformVersion();
|
|
417
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Install prerequisite packages (wget and unzip) if not present
|
|
422
|
+
const needsWget = !shell.commandExists('wget');
|
|
423
|
+
const needsUnzip = !shell.commandExists('unzip');
|
|
424
|
+
|
|
425
|
+
if (needsWget || needsUnzip) {
|
|
426
|
+
console.log('Installing prerequisite packages...');
|
|
427
|
+
const packages = [];
|
|
428
|
+
if (needsWget) packages.push('wget');
|
|
429
|
+
if (needsUnzip) packages.push('unzip');
|
|
430
|
+
|
|
431
|
+
const prereqResult = await shell.exec(`sudo dnf install -y ${packages.join(' ')}`);
|
|
432
|
+
if (prereqResult.code !== 0) {
|
|
433
|
+
console.log('Failed to install prerequisite packages.');
|
|
434
|
+
console.log(prereqResult.stderr || prereqResult.stdout);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Download the Terraform binary from HashiCorp releases
|
|
440
|
+
const downloadUrl = `https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip`;
|
|
441
|
+
console.log(`Downloading Terraform ${TERRAFORM_VERSION}...`);
|
|
442
|
+
const downloadResult = await shell.exec(`wget -q "${downloadUrl}" -O /tmp/terraform.zip`);
|
|
443
|
+
if (downloadResult.code !== 0) {
|
|
444
|
+
console.log('Failed to download Terraform binary.');
|
|
445
|
+
console.log(downloadResult.stderr || downloadResult.stdout);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Extract the binary to /tmp
|
|
450
|
+
console.log('Extracting Terraform...');
|
|
451
|
+
const extractResult = await shell.exec('unzip -o -q /tmp/terraform.zip -d /tmp');
|
|
452
|
+
if (extractResult.code !== 0) {
|
|
453
|
+
console.log('Failed to extract Terraform binary.');
|
|
454
|
+
console.log(extractResult.stderr || extractResult.stdout);
|
|
455
|
+
await shell.exec('rm -f /tmp/terraform.zip');
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Move the binary to /usr/local/bin and set executable permissions
|
|
460
|
+
console.log('Installing Terraform to /usr/local/bin...');
|
|
461
|
+
const installResult = await shell.exec('sudo mv /tmp/terraform /usr/local/bin/ && sudo chmod +x /usr/local/bin/terraform');
|
|
462
|
+
if (installResult.code !== 0) {
|
|
463
|
+
console.log('Failed to install Terraform binary.');
|
|
464
|
+
console.log(installResult.stderr || installResult.stdout);
|
|
465
|
+
await shell.exec('rm -f /tmp/terraform.zip /tmp/terraform');
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Clean up downloaded files
|
|
470
|
+
await shell.exec('rm -f /tmp/terraform.zip');
|
|
471
|
+
|
|
472
|
+
// Verify the installation succeeded
|
|
473
|
+
if (isTerraformInstalled()) {
|
|
474
|
+
const version = await getTerraformVersion();
|
|
475
|
+
console.log(`Terraform installed successfully (version ${version}).`);
|
|
476
|
+
} else {
|
|
477
|
+
console.log('Installation completed but Terraform command not found.');
|
|
478
|
+
console.log('Ensure /usr/local/bin is in your PATH:');
|
|
479
|
+
console.log('echo \'export PATH=$PATH:/usr/local/bin\' >> ~/.bashrc && source ~/.bashrc');
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Install Terraform on Amazon Linux/RHEL using YUM with the official HashiCorp repository
|
|
485
|
+
*
|
|
486
|
+
* This function:
|
|
487
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
488
|
+
* 2. Installs yum-utils package for repository management
|
|
489
|
+
* 3. Adds the official HashiCorp YUM repository
|
|
490
|
+
* 4. Installs Terraform via yum
|
|
491
|
+
* 5. Verifies the installation succeeded
|
|
492
|
+
*
|
|
493
|
+
* Prerequisites:
|
|
494
|
+
* - Amazon Linux 2023 (AL2023), Amazon Linux 2 (AL2), or RHEL 7/8/9
|
|
495
|
+
* - sudo privileges
|
|
496
|
+
* - Internet connectivity
|
|
497
|
+
*
|
|
498
|
+
* Note: Amazon Linux 2023 uses DNF as the default package manager, but the
|
|
499
|
+
* yum command still works as it's aliased to dnf. This function uses yum
|
|
500
|
+
* for compatibility across both AL2 and AL2023.
|
|
501
|
+
*
|
|
502
|
+
* @returns {Promise<void>}
|
|
503
|
+
*/
|
|
504
|
+
async function install_amazon_linux() {
|
|
505
|
+
// Check if Terraform is already installed (idempotency check)
|
|
506
|
+
if (isTerraformInstalled()) {
|
|
507
|
+
const version = await getTerraformVersion();
|
|
508
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// Install yum-utils for repository management (provides yum-config-manager)
|
|
513
|
+
console.log('Installing yum-utils...');
|
|
514
|
+
const utilsResult = await shell.exec('sudo yum install -y yum-utils');
|
|
515
|
+
if (utilsResult.code !== 0) {
|
|
516
|
+
console.log('Failed to install yum-utils.');
|
|
517
|
+
console.log(utilsResult.stderr || utilsResult.stdout);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Detect if we're on Amazon Linux or RHEL to use the correct repository
|
|
522
|
+
// Amazon Linux uses the AmazonLinux repository, RHEL/CentOS uses the RHEL repository
|
|
523
|
+
const platform = os.detect();
|
|
524
|
+
const isAmazonLinux = platform.distro === 'amzn' || platform.distro === 'amazon' || platform.type === 'amazon_linux';
|
|
525
|
+
const repoUrl = isAmazonLinux
|
|
526
|
+
? 'https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo'
|
|
527
|
+
: 'https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo';
|
|
528
|
+
|
|
529
|
+
// Add the HashiCorp repository
|
|
530
|
+
console.log('Adding HashiCorp YUM repository...');
|
|
531
|
+
const repoResult = await shell.exec(`sudo yum-config-manager --add-repo ${repoUrl}`);
|
|
532
|
+
if (repoResult.code !== 0) {
|
|
533
|
+
console.log('Failed to add HashiCorp repository.');
|
|
534
|
+
console.log(repoResult.stderr || repoResult.stdout);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Install Terraform
|
|
539
|
+
console.log('Installing Terraform...');
|
|
540
|
+
const installResult = await shell.exec('sudo yum install -y terraform');
|
|
541
|
+
if (installResult.code !== 0) {
|
|
542
|
+
console.log('Failed to install Terraform.');
|
|
543
|
+
console.log(installResult.stderr || installResult.stdout);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Verify the installation succeeded
|
|
548
|
+
if (isTerraformInstalled()) {
|
|
549
|
+
const version = await getTerraformVersion();
|
|
550
|
+
console.log(`Terraform installed successfully (version ${version}).`);
|
|
551
|
+
} else {
|
|
552
|
+
console.log('Installation completed but Terraform command not found.');
|
|
553
|
+
console.log('You may need to restart your terminal session.');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Install Terraform on Windows using Chocolatey
|
|
559
|
+
*
|
|
560
|
+
* This function:
|
|
561
|
+
* 1. Checks if Terraform is already installed (idempotency)
|
|
562
|
+
* 2. Verifies Chocolatey is available
|
|
563
|
+
* 3. Installs Terraform via Chocolatey
|
|
564
|
+
* 4. Verifies the installation succeeded
|
|
565
|
+
*
|
|
566
|
+
* Prerequisites:
|
|
567
|
+
* - Windows 10 or Windows 11 (64-bit)
|
|
568
|
+
* - Administrator PowerShell or Command Prompt
|
|
569
|
+
* - Chocolatey package manager installed
|
|
570
|
+
*
|
|
571
|
+
* Note: HashiCorp does not maintain the Chocolatey package directly, but it is
|
|
572
|
+
* regularly updated and provides a convenient installation method. For production
|
|
573
|
+
* environments requiring the absolute latest version on release day, consider
|
|
574
|
+
* manual installation.
|
|
575
|
+
*
|
|
576
|
+
* @returns {Promise<void>}
|
|
577
|
+
*/
|
|
578
|
+
async function install_windows() {
|
|
579
|
+
// Check if Terraform is already installed (idempotency check)
|
|
580
|
+
if (isTerraformInstalled()) {
|
|
581
|
+
const version = await getTerraformVersion();
|
|
582
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Verify Chocolatey is available before proceeding
|
|
587
|
+
if (!choco.isInstalled()) {
|
|
588
|
+
console.log('Chocolatey is not installed. Please install Chocolatey first.');
|
|
589
|
+
console.log('Run in an Administrator PowerShell:');
|
|
590
|
+
console.log("Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))");
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Install Terraform via Chocolatey
|
|
595
|
+
console.log('Installing Terraform via Chocolatey...');
|
|
596
|
+
const result = await choco.install(CHOCO_PACKAGE_NAME);
|
|
597
|
+
|
|
598
|
+
if (!result.success) {
|
|
599
|
+
console.log('Failed to install Terraform via Chocolatey.');
|
|
600
|
+
console.log(result.output);
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Verify the installation - note that PATH may not be updated in current session
|
|
605
|
+
const isInstalled = await choco.isPackageInstalled(CHOCO_PACKAGE_NAME);
|
|
606
|
+
if (isInstalled) {
|
|
607
|
+
console.log('Terraform installed successfully via Chocolatey.');
|
|
608
|
+
console.log('');
|
|
609
|
+
console.log('Note: You may need to open a new terminal window for the PATH update to take effect.');
|
|
610
|
+
console.log('Then run: terraform --version');
|
|
611
|
+
} else {
|
|
612
|
+
console.log('Installation completed but could not verify Terraform package.');
|
|
613
|
+
console.log('Try opening a new terminal window and run: terraform --version');
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Install Terraform in Git Bash on Windows via Chocolatey/PowerShell
|
|
619
|
+
*
|
|
620
|
+
* Git Bash inherits the Windows PATH, so once Terraform is installed on Windows
|
|
621
|
+
* via Chocolatey, it is automatically available in Git Bash. This function
|
|
622
|
+
* invokes Chocolatey through PowerShell from Git Bash.
|
|
623
|
+
*
|
|
624
|
+
* This function:
|
|
625
|
+
* 1. Checks if Terraform is already available (from Windows PATH)
|
|
626
|
+
* 2. Invokes Chocolatey via PowerShell to install Terraform
|
|
627
|
+
* 3. Provides instructions for PATH updates
|
|
628
|
+
*
|
|
629
|
+
* Prerequisites:
|
|
630
|
+
* - Windows 10 or Windows 11 (64-bit)
|
|
631
|
+
* - Git Bash installed (comes with Git for Windows)
|
|
632
|
+
* - Chocolatey installed on Windows
|
|
633
|
+
*
|
|
634
|
+
* @returns {Promise<void>}
|
|
635
|
+
*/
|
|
636
|
+
async function install_gitbash() {
|
|
637
|
+
// Check if Terraform is already available (inherited from Windows PATH)
|
|
638
|
+
if (isTerraformInstalled()) {
|
|
639
|
+
const version = await getTerraformVersion();
|
|
640
|
+
console.log(`Terraform is already installed (version ${version}), skipping...`);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Check if Chocolatey is available via Windows path
|
|
645
|
+
const chocoPath = '/c/ProgramData/chocolatey/bin/choco.exe';
|
|
646
|
+
const chocoResult = await shell.exec(`"${chocoPath}" --version 2>/dev/null`);
|
|
647
|
+
|
|
648
|
+
if (chocoResult.code !== 0) {
|
|
649
|
+
console.log('Chocolatey is not installed on Windows.');
|
|
650
|
+
console.log('Please install Chocolatey first, then run this installer again.');
|
|
651
|
+
console.log('');
|
|
652
|
+
console.log('Or install Terraform manually from:');
|
|
653
|
+
console.log('https://developer.hashicorp.com/terraform/install');
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Install Terraform via Windows Chocolatey
|
|
658
|
+
console.log('Installing Terraform via Windows Chocolatey...');
|
|
659
|
+
const result = await shell.exec(`"${chocoPath}" install terraform -y`);
|
|
660
|
+
|
|
661
|
+
if (result.code !== 0) {
|
|
662
|
+
console.log('Failed to install Terraform via Chocolatey.');
|
|
663
|
+
console.log(result.stderr || result.stdout);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
console.log('Terraform installed successfully.');
|
|
668
|
+
console.log('');
|
|
669
|
+
console.log('Please close and reopen Git Bash for the terraform command to be available.');
|
|
670
|
+
console.log('');
|
|
671
|
+
console.log('If terraform is still not found, add this to your ~/.bashrc:');
|
|
672
|
+
console.log('export PATH=$PATH:/c/ProgramData/chocolatey/bin');
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Check if Terraform is installed on the current system.
|
|
677
|
+
* @returns {Promise<boolean>} True if Terraform is installed
|
|
678
|
+
*/
|
|
679
|
+
async function isInstalled() {
|
|
680
|
+
const platform = os.detect();
|
|
681
|
+
if (platform.type === 'macos') {
|
|
682
|
+
return brew.isFormulaInstalled(BREW_FORMULA_NAME);
|
|
683
|
+
}
|
|
684
|
+
if (platform.type === 'windows') {
|
|
685
|
+
return choco.isPackageInstalled(CHOCO_PACKAGE_NAME);
|
|
686
|
+
}
|
|
687
|
+
return shell.commandExists(TERRAFORM_COMMAND);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Check if this installer is supported on the current platform.
|
|
692
|
+
* Terraform is available on all major platforms.
|
|
693
|
+
* @returns {boolean} True if installation is supported on this platform
|
|
694
|
+
*/
|
|
695
|
+
function isEligible() {
|
|
696
|
+
const platform = os.detect();
|
|
697
|
+
return ['macos', 'ubuntu', 'debian', 'wsl', 'raspbian', 'amazon_linux', 'rhel', 'fedora', 'windows', 'gitbash'].includes(platform.type);
|
|
698
|
+
}
|
|
9
699
|
|
|
10
700
|
/**
|
|
11
|
-
*
|
|
701
|
+
* Main installation entry point - detects platform and runs appropriate installer
|
|
702
|
+
*
|
|
703
|
+
* This function detects the current operating system using the os utility module
|
|
704
|
+
* and dispatches to the appropriate platform-specific installer function.
|
|
705
|
+
*
|
|
706
|
+
* Supported platforms:
|
|
707
|
+
* - macos: Uses Homebrew with HashiCorp tap
|
|
708
|
+
* - ubuntu: Uses APT with HashiCorp repository
|
|
709
|
+
* - debian: Uses APT with HashiCorp repository (same as ubuntu)
|
|
710
|
+
* - wsl: Uses APT with HashiCorp repository (same as ubuntu)
|
|
711
|
+
* - raspbian: Uses manual binary installation (ARM)
|
|
712
|
+
* - amazon_linux: Uses YUM with HashiCorp repository
|
|
713
|
+
* - rhel: Uses YUM with HashiCorp repository (same as amazon_linux)
|
|
714
|
+
* - fedora: Uses manual binary installation (due to inconsistent repository support)
|
|
715
|
+
* - windows: Uses Chocolatey
|
|
716
|
+
* - gitbash: Uses Windows Chocolatey via Git Bash
|
|
717
|
+
*
|
|
718
|
+
* Unsupported platforms will receive a graceful message and the script
|
|
719
|
+
* will exit cleanly without errors.
|
|
12
720
|
*
|
|
13
721
|
* @returns {Promise<void>}
|
|
14
722
|
*/
|
|
15
723
|
async function install() {
|
|
16
724
|
const platform = os.detect();
|
|
17
725
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
726
|
+
// Map platform types to their corresponding installer functions
|
|
727
|
+
// Multiple platform types can map to the same installer (e.g., debian and ubuntu)
|
|
728
|
+
const installers = {
|
|
729
|
+
'macos': install_macos,
|
|
730
|
+
'ubuntu': install_ubuntu,
|
|
731
|
+
'debian': install_ubuntu,
|
|
732
|
+
'wsl': install_ubuntu_wsl,
|
|
733
|
+
'raspbian': install_raspbian,
|
|
734
|
+
'amazon_linux': install_amazon_linux,
|
|
735
|
+
'rhel': install_amazon_linux,
|
|
736
|
+
'fedora': install_fedora,
|
|
737
|
+
'windows': install_windows,
|
|
738
|
+
'gitbash': install_gitbash,
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
// Look up the installer for the detected platform
|
|
742
|
+
const installer = installers[platform.type];
|
|
743
|
+
|
|
744
|
+
// If no installer exists for this platform, inform the user gracefully
|
|
745
|
+
// Do not throw an error - just log a message and return cleanly
|
|
746
|
+
if (!installer) {
|
|
747
|
+
console.log(`Terraform is not available for ${platform.type}.`);
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Run the platform-specific installer
|
|
752
|
+
await installer();
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Export all functions for use as a module and for testing
|
|
756
|
+
module.exports = {
|
|
757
|
+
install,
|
|
758
|
+
isInstalled,
|
|
759
|
+
isEligible,
|
|
760
|
+
install_macos,
|
|
761
|
+
install_ubuntu,
|
|
762
|
+
install_ubuntu_wsl,
|
|
763
|
+
install_raspbian,
|
|
764
|
+
install_fedora,
|
|
765
|
+
install_amazon_linux,
|
|
766
|
+
install_windows,
|
|
767
|
+
install_gitbash,
|
|
768
|
+
// Export helper functions for potential reuse or testing
|
|
769
|
+
isTerraformInstalled,
|
|
770
|
+
getTerraformVersion,
|
|
771
|
+
};
|
|
41
772
|
|
|
773
|
+
// Allow direct execution: node terraform.js
|
|
42
774
|
if (require.main === module) {
|
|
43
|
-
install()
|
|
775
|
+
install().catch(err => {
|
|
776
|
+
console.error(err.message);
|
|
777
|
+
process.exit(1);
|
|
778
|
+
});
|
|
44
779
|
}
|