tfv 5.0.1 → 6.1.0
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/.github/workflows/publish.yml +43 -3
- package/README.md +253 -122
- package/demo.gif +0 -0
- package/demo.tape +230 -0
- package/index.js +0 -4
- package/lib/commands/apply.js +8 -3
- package/lib/commands/current.js +25 -0
- package/lib/commands/destroy.js +8 -3
- package/lib/commands/doctor.js +20 -0
- package/lib/commands/exec.js +33 -0
- package/lib/commands/fmt.js +26 -0
- package/lib/commands/init.js +26 -0
- package/lib/commands/install.js +22 -13
- package/lib/commands/list.js +20 -11
- package/lib/commands/pin.js +26 -0
- package/lib/commands/plan.js +8 -3
- package/lib/commands/prune.js +41 -0
- package/lib/commands/remove.js +17 -12
- package/lib/commands/shell-init.js +25 -0
- package/lib/commands/switch.js +28 -7
- package/lib/commands/upgrade.js +26 -0
- package/lib/commands/use.js +17 -13
- package/lib/commands/validate.js +21 -0
- package/lib/modules/current.js +52 -0
- package/lib/modules/doctor.js +160 -0
- package/lib/modules/exec.js +36 -0
- package/lib/modules/install.js +155 -89
- package/lib/modules/list.js +66 -105
- package/lib/modules/pin.js +35 -0
- package/lib/modules/prune.js +100 -0
- package/lib/modules/ps1.js +37 -29
- package/lib/modules/remote.js +68 -15
- package/lib/modules/remove.js +35 -21
- package/lib/modules/shell-init.js +226 -0
- package/lib/modules/switch.js +125 -41
- package/lib/modules/terraform-command.js +49 -67
- package/lib/modules/upgrade.js +93 -0
- package/lib/modules/use.js +58 -54
- package/lib/utils/formatVersions.js +57 -5
- package/lib/utils/paths.js +156 -0
- package/lib/utils/postInstall.js +37 -13
- package/lib/utils/store.js +17 -6
- package/package.json +11 -9
- package/test/extractTargets.test.js +75 -0
- package/test/formatVersions.test.js +126 -0
- package/test/moduleImports.test.js +45 -0
- package/test/paths.test.js +69 -0
- package/test/versionResolution.test.js +92 -0
package/demo.tape
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# tfv — demo tape
|
|
2
|
+
# Run with: vhs demo.tape
|
|
3
|
+
|
|
4
|
+
Output demo.gif
|
|
5
|
+
|
|
6
|
+
# ── Terminal settings ──────────────────────────────────────────────────────────
|
|
7
|
+
Set FontSize 14
|
|
8
|
+
Set Width 1000
|
|
9
|
+
Set Height 580
|
|
10
|
+
Set Theme "Catppuccin Mocha"
|
|
11
|
+
Set Shell "zsh"
|
|
12
|
+
Set Padding 24
|
|
13
|
+
Set TypingSpeed 40ms
|
|
14
|
+
Set PlaybackSpeed 1
|
|
15
|
+
|
|
16
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
17
|
+
# 1. HELP
|
|
18
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
19
|
+
Sleep 500ms
|
|
20
|
+
Type "tfv --help"
|
|
21
|
+
Enter
|
|
22
|
+
Sleep 3s
|
|
23
|
+
|
|
24
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
25
|
+
# 2. INSTALL MULTIPLE VERSIONS
|
|
26
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
27
|
+
|
|
28
|
+
# Install latest stable
|
|
29
|
+
Type "tfv install latest"
|
|
30
|
+
Enter
|
|
31
|
+
Sleep 5s
|
|
32
|
+
|
|
33
|
+
# Install a specific version
|
|
34
|
+
Type "tfv install 1.8.5"
|
|
35
|
+
Enter
|
|
36
|
+
Sleep 5s
|
|
37
|
+
|
|
38
|
+
# Install an older version using ^ (latest patch in series)
|
|
39
|
+
Type "tfv install 1.7.^"
|
|
40
|
+
Enter
|
|
41
|
+
Sleep 5s
|
|
42
|
+
|
|
43
|
+
# Install 1.6.x series
|
|
44
|
+
Type "tfv install 1.6.^"
|
|
45
|
+
Enter
|
|
46
|
+
Sleep 5s
|
|
47
|
+
|
|
48
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
49
|
+
# 3. LIST INSTALLED VERSIONS
|
|
50
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
51
|
+
Type "tfv list"
|
|
52
|
+
Enter
|
|
53
|
+
Sleep 2s
|
|
54
|
+
|
|
55
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
56
|
+
# 4. SWITCH BETWEEN VERSIONS — show terraform version changes
|
|
57
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
58
|
+
|
|
59
|
+
Type "tfv use 1.6.7"
|
|
60
|
+
Enter
|
|
61
|
+
Sleep 1500ms
|
|
62
|
+
Type "terraform version"
|
|
63
|
+
Enter
|
|
64
|
+
Sleep 1500ms
|
|
65
|
+
|
|
66
|
+
Type "tfv use 1.7.5"
|
|
67
|
+
Enter
|
|
68
|
+
Sleep 1500ms
|
|
69
|
+
Type "terraform version"
|
|
70
|
+
Enter
|
|
71
|
+
Sleep 1500ms
|
|
72
|
+
|
|
73
|
+
Type "tfv use 1.8.5"
|
|
74
|
+
Enter
|
|
75
|
+
Sleep 1500ms
|
|
76
|
+
Type "terraform version"
|
|
77
|
+
Enter
|
|
78
|
+
Sleep 1500ms
|
|
79
|
+
|
|
80
|
+
Type "tfv use latest"
|
|
81
|
+
Enter
|
|
82
|
+
Sleep 1500ms
|
|
83
|
+
Type "terraform version"
|
|
84
|
+
Enter
|
|
85
|
+
Sleep 2s
|
|
86
|
+
|
|
87
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
88
|
+
# 5. CURRENT — active version + PATH status
|
|
89
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
90
|
+
Type "tfv current"
|
|
91
|
+
Enter
|
|
92
|
+
Sleep 2s
|
|
93
|
+
|
|
94
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
95
|
+
# 6. AUTO-SWITCH — reads required_version from .tf file
|
|
96
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
97
|
+
Hide
|
|
98
|
+
Type "mkdir -p /tmp/tfv-demo-tf && printf 'terraform { required_version = \\042~> 1.7\\042 }\\n' > /tmp/tfv-demo-tf/versions.tf && cd /tmp/tfv-demo-tf"
|
|
99
|
+
Enter
|
|
100
|
+
Sleep 500ms
|
|
101
|
+
Type "clear"
|
|
102
|
+
Enter
|
|
103
|
+
Sleep 200ms
|
|
104
|
+
Show
|
|
105
|
+
|
|
106
|
+
Type "tfv auto-switch"
|
|
107
|
+
Enter
|
|
108
|
+
Sleep 2s
|
|
109
|
+
|
|
110
|
+
Type "terraform version"
|
|
111
|
+
Enter
|
|
112
|
+
Sleep 1500ms
|
|
113
|
+
|
|
114
|
+
Hide
|
|
115
|
+
Type "cd -"
|
|
116
|
+
Enter
|
|
117
|
+
Sleep 300ms
|
|
118
|
+
Type "clear"
|
|
119
|
+
Enter
|
|
120
|
+
Sleep 200ms
|
|
121
|
+
Show
|
|
122
|
+
|
|
123
|
+
# AUTO-SWITCH from .terraform-version file
|
|
124
|
+
Hide
|
|
125
|
+
Type "mkdir -p /tmp/tfv-demo-pin && echo '1.6.7' > /tmp/tfv-demo-pin/.terraform-version && cd /tmp/tfv-demo-pin"
|
|
126
|
+
Enter
|
|
127
|
+
Sleep 500ms
|
|
128
|
+
Type "clear"
|
|
129
|
+
Enter
|
|
130
|
+
Sleep 200ms
|
|
131
|
+
Show
|
|
132
|
+
|
|
133
|
+
Type "tfv auto-switch"
|
|
134
|
+
Enter
|
|
135
|
+
Sleep 2s
|
|
136
|
+
|
|
137
|
+
Type "terraform version"
|
|
138
|
+
Enter
|
|
139
|
+
Sleep 1500ms
|
|
140
|
+
|
|
141
|
+
Hide
|
|
142
|
+
Type "cd -"
|
|
143
|
+
Enter
|
|
144
|
+
Sleep 300ms
|
|
145
|
+
Type "clear"
|
|
146
|
+
Enter
|
|
147
|
+
Sleep 200ms
|
|
148
|
+
Show
|
|
149
|
+
|
|
150
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
151
|
+
# 7. PIN — lock version for teammates
|
|
152
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
153
|
+
Hide
|
|
154
|
+
Type "tfv use latest"
|
|
155
|
+
Enter
|
|
156
|
+
Sleep 500ms
|
|
157
|
+
Type "clear"
|
|
158
|
+
Enter
|
|
159
|
+
Sleep 200ms
|
|
160
|
+
Show
|
|
161
|
+
|
|
162
|
+
Type "tfv pin"
|
|
163
|
+
Enter
|
|
164
|
+
Sleep 500ms
|
|
165
|
+
|
|
166
|
+
Type "cat .terraform-version"
|
|
167
|
+
Enter
|
|
168
|
+
Sleep 1500ms
|
|
169
|
+
|
|
170
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
171
|
+
# 8. UPGRADE — latest patch in current series
|
|
172
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
173
|
+
Type "tfv use 1.8.5"
|
|
174
|
+
Enter
|
|
175
|
+
Sleep 1000ms
|
|
176
|
+
|
|
177
|
+
Type "tfv upgrade"
|
|
178
|
+
Enter
|
|
179
|
+
Sleep 5s
|
|
180
|
+
|
|
181
|
+
Type "terraform version"
|
|
182
|
+
Enter
|
|
183
|
+
Sleep 2s
|
|
184
|
+
|
|
185
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
186
|
+
# 9. REMOVE versions
|
|
187
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
188
|
+
Type "tfv remove 1.6.7"
|
|
189
|
+
Enter
|
|
190
|
+
Sleep 1s
|
|
191
|
+
|
|
192
|
+
Type "tfv list"
|
|
193
|
+
Enter
|
|
194
|
+
Sleep 2s
|
|
195
|
+
|
|
196
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
197
|
+
# 10. OPENTOFU — --provider tofu switches to OpenTofu; omit for terraform default
|
|
198
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
199
|
+
|
|
200
|
+
# No --provider needed for terraform (it's the default)
|
|
201
|
+
Type "tfv list"
|
|
202
|
+
Enter
|
|
203
|
+
Sleep 1500ms
|
|
204
|
+
|
|
205
|
+
# Add --provider tofu to target OpenTofu instead
|
|
206
|
+
Type "tfv install latest --provider tofu"
|
|
207
|
+
Enter
|
|
208
|
+
Sleep 5s
|
|
209
|
+
|
|
210
|
+
Type "tfv use latest --provider tofu"
|
|
211
|
+
Enter
|
|
212
|
+
Sleep 1500ms
|
|
213
|
+
|
|
214
|
+
Type "tfv current --provider tofu"
|
|
215
|
+
Enter
|
|
216
|
+
Sleep 1500ms
|
|
217
|
+
|
|
218
|
+
Type "tofu version"
|
|
219
|
+
Enter
|
|
220
|
+
Sleep 2s
|
|
221
|
+
|
|
222
|
+
# List available remote OpenTofu versions
|
|
223
|
+
Type "tfv list --remote --provider tofu"
|
|
224
|
+
Enter
|
|
225
|
+
Sleep 4s
|
|
226
|
+
|
|
227
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
228
|
+
# END
|
|
229
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
230
|
+
Sleep 2s
|
package/index.js
CHANGED
|
@@ -6,10 +6,6 @@ const {join} = require('path')
|
|
|
6
6
|
yargs
|
|
7
7
|
.commandDir(join(__dirname, 'lib', 'commands'))
|
|
8
8
|
.alias('help', 'h')
|
|
9
|
-
.alias('version', 'v')
|
|
10
9
|
.scriptName('tfv')
|
|
11
|
-
.demandCommand(1, 'You need at least one command before moving on')
|
|
12
|
-
.strictOptions()
|
|
13
|
-
// .strictCommands()
|
|
14
10
|
.showHelpOnFail()
|
|
15
11
|
.argv
|
package/lib/commands/apply.js
CHANGED
|
@@ -11,12 +11,17 @@ exports.builder = (yargs) => {
|
|
|
11
11
|
describe: 'Terraform file(s) to extract targets from',
|
|
12
12
|
type: 'array',
|
|
13
13
|
})
|
|
14
|
+
.option('provider', {
|
|
15
|
+
alias: 'p',
|
|
16
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
17
|
+
type: 'string',
|
|
18
|
+
default: 'terraform',
|
|
19
|
+
})
|
|
14
20
|
.epilog('Accepts all terraform flags after --\nExample:\n tfv apply --file main.tf --file network.tf -- -auto-approve -target=<TARGET> -var="env=prod"')
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
exports.handler = async (argv) => {
|
|
18
|
-
const {file, _} = argv;
|
|
19
|
-
// Extra args come after -- in the command line
|
|
24
|
+
const {file, _, provider} = argv;
|
|
20
25
|
const extraArgs = _.slice(1);
|
|
21
|
-
await runTerraformCommand('apply', file, extraArgs);
|
|
26
|
+
await runTerraformCommand('apply', file, extraArgs, provider);
|
|
22
27
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { current } = require('../modules/current');
|
|
4
|
+
|
|
5
|
+
exports.command = 'current'
|
|
6
|
+
exports.aliases = ['which']
|
|
7
|
+
exports.desc = 'Show the currently active terraform or opentofu version'
|
|
8
|
+
exports.builder = (yargs) => {
|
|
9
|
+
return yargs
|
|
10
|
+
.option('provider', {
|
|
11
|
+
alias: 'p',
|
|
12
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: 'terraform',
|
|
15
|
+
})
|
|
16
|
+
.epilog([
|
|
17
|
+
'Examples:',
|
|
18
|
+
' tfv current',
|
|
19
|
+
' tfv which --provider tofu',
|
|
20
|
+
].join('\n'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.handler = async (argv) => {
|
|
24
|
+
await current(argv.provider);
|
|
25
|
+
}
|
package/lib/commands/destroy.js
CHANGED
|
@@ -11,12 +11,17 @@ exports.builder = (yargs) => {
|
|
|
11
11
|
describe: 'Terraform file(s) to extract targets from',
|
|
12
12
|
type: 'array',
|
|
13
13
|
})
|
|
14
|
+
.option('provider', {
|
|
15
|
+
alias: 'p',
|
|
16
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
17
|
+
type: 'string',
|
|
18
|
+
default: 'terraform',
|
|
19
|
+
})
|
|
14
20
|
.epilog('Accepts all terraform flags after --\nExample:\n tfv destroy --file main.tf --file network.tf -- -auto-approve -target=<TARGET> -var="env=prod"')
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
exports.handler = async (argv) => {
|
|
18
|
-
const {file, _} = argv;
|
|
19
|
-
// Extra args come after -- in the command line
|
|
24
|
+
const {file, _, provider} = argv;
|
|
20
25
|
const extraArgs = _.slice(1);
|
|
21
|
-
await runTerraformCommand('destroy', file, extraArgs);
|
|
26
|
+
await runTerraformCommand('destroy', file, extraArgs, provider);
|
|
22
27
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { doctor } = require('../modules/doctor');
|
|
4
|
+
|
|
5
|
+
exports.command = 'doctor'
|
|
6
|
+
exports.desc = 'Run diagnostics: PATH, binaries, store, shell config'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.epilog([
|
|
10
|
+
'Checks PATH order, active binaries, store directories,',
|
|
11
|
+
'shell config, and PATH conflicts.',
|
|
12
|
+
'',
|
|
13
|
+
'Example:',
|
|
14
|
+
' tfv doctor',
|
|
15
|
+
].join('\n'))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.handler = async () => {
|
|
19
|
+
await doctor();
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { exec } = require('../modules/exec');
|
|
4
|
+
|
|
5
|
+
exports.command = 'exec <ver>'
|
|
6
|
+
exports.desc = 'Run a terraform/tofu command with a specific version without switching the active version'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.positional('ver', {
|
|
10
|
+
describe: 'Installed version to use for this run',
|
|
11
|
+
type: 'string',
|
|
12
|
+
})
|
|
13
|
+
.option('provider', {
|
|
14
|
+
alias: 'p',
|
|
15
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
16
|
+
type: 'string',
|
|
17
|
+
default: 'terraform',
|
|
18
|
+
})
|
|
19
|
+
.epilog([
|
|
20
|
+
'Pass terraform/tofu args after --',
|
|
21
|
+
'',
|
|
22
|
+
'Examples:',
|
|
23
|
+
' tfv exec 1.9.0 -- version',
|
|
24
|
+
' tfv exec 1.8.0 -- plan -var="env=prod"',
|
|
25
|
+
' tfv exec 1.7.3 --provider tofu -- validate',
|
|
26
|
+
].join('\n'))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.handler = async (argv) => {
|
|
30
|
+
const { ver, provider, _ } = argv;
|
|
31
|
+
const extraArgs = _.slice(1);
|
|
32
|
+
await exec(ver, extraArgs, provider);
|
|
33
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { runTerraformCommand } = require('../modules/terraform-command');
|
|
4
|
+
|
|
5
|
+
exports.command = 'fmt'
|
|
6
|
+
exports.desc = 'Run terraform fmt. Accepts all terraform flags after --'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.option('provider', {
|
|
10
|
+
alias: 'p',
|
|
11
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
12
|
+
type: 'string',
|
|
13
|
+
default: 'terraform',
|
|
14
|
+
})
|
|
15
|
+
.epilog([
|
|
16
|
+
'Examples:',
|
|
17
|
+
' tfv fmt',
|
|
18
|
+
' tfv fmt -- -recursive',
|
|
19
|
+
' tfv fmt -- -check',
|
|
20
|
+
].join('\n'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.handler = async (argv) => {
|
|
24
|
+
const extraArgs = argv._.slice(1);
|
|
25
|
+
await runTerraformCommand('fmt', null, extraArgs, argv.provider);
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { runTerraformCommand } = require('../modules/terraform-command');
|
|
4
|
+
|
|
5
|
+
exports.command = 'init'
|
|
6
|
+
exports.desc = 'Run terraform init. Accepts all terraform flags after --'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.option('provider', {
|
|
10
|
+
alias: 'p',
|
|
11
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
12
|
+
type: 'string',
|
|
13
|
+
default: 'terraform',
|
|
14
|
+
})
|
|
15
|
+
.epilog([
|
|
16
|
+
'Examples:',
|
|
17
|
+
' tfv init',
|
|
18
|
+
' tfv init -- -upgrade',
|
|
19
|
+
' tfv init -- -backend-config=backend.hcl',
|
|
20
|
+
].join('\n'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.handler = async (argv) => {
|
|
24
|
+
const extraArgs = argv._.slice(1);
|
|
25
|
+
await runTerraformCommand('init', null, extraArgs, argv.provider);
|
|
26
|
+
}
|
package/lib/commands/install.js
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {install} = require('../modules/install');
|
|
3
|
+
const { install } = require('../modules/install');
|
|
5
4
|
|
|
6
|
-
exports.command = 'install <
|
|
5
|
+
exports.command = 'install <ver>'
|
|
7
6
|
exports.aliases = ['i']
|
|
8
|
-
exports.desc = 'Install a terraform version'
|
|
7
|
+
exports.desc = 'Install a terraform or opentofu version'
|
|
9
8
|
exports.builder = (yargs) => {
|
|
10
9
|
return yargs
|
|
11
10
|
.option('arch', {
|
|
12
11
|
alias: 'a',
|
|
13
|
-
describe: 'Specify system architecture. Defaults
|
|
12
|
+
describe: 'Specify system architecture (arm64, amd64, etc). Defaults to your system arch.',
|
|
14
13
|
type: 'string',
|
|
15
|
-
default: ''
|
|
14
|
+
default: '',
|
|
16
15
|
})
|
|
17
|
-
.
|
|
16
|
+
.option('provider', {
|
|
17
|
+
alias: 'p',
|
|
18
|
+
describe: 'Provider to install: terraform (default) or tofu/opentofu',
|
|
19
|
+
type: 'string',
|
|
20
|
+
default: 'terraform',
|
|
21
|
+
})
|
|
22
|
+
.epilog([
|
|
23
|
+
'Version formats: latest, x.x.x (exact), x^ (latest major), x.x.^ (latest minor)',
|
|
24
|
+
'Examples:',
|
|
25
|
+
' tfv install latest',
|
|
26
|
+
' tfv install 1.7.3',
|
|
27
|
+
' tfv install 1.7.^',
|
|
28
|
+
' tfv install latest --provider tofu',
|
|
29
|
+
].join('\n'))
|
|
18
30
|
}
|
|
19
31
|
|
|
20
|
-
exports.handler = async () => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
await install(version, arch);
|
|
32
|
+
exports.handler = async (argv) => {
|
|
33
|
+
const { ver, arch, provider } = argv;
|
|
34
|
+
await install(ver, arch, provider);
|
|
25
35
|
}
|
|
26
|
-
|
package/lib/commands/list.js
CHANGED
|
@@ -1,29 +1,38 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {list} = require('../modules/list');
|
|
3
|
+
const { list } = require('../modules/list');
|
|
5
4
|
|
|
6
|
-
exports.command = 'list
|
|
5
|
+
exports.command = 'list'
|
|
7
6
|
exports.aliases = ['ls']
|
|
8
|
-
exports.desc = 'List installed or available terraform versions'
|
|
7
|
+
exports.desc = 'List installed or available terraform/opentofu versions'
|
|
9
8
|
exports.builder = (yargs) => {
|
|
10
9
|
return yargs
|
|
11
10
|
.option('local', {
|
|
12
11
|
alias: 'l',
|
|
13
|
-
describe: 'List
|
|
12
|
+
describe: 'List versions installed locally (default)',
|
|
14
13
|
type: 'boolean',
|
|
15
14
|
default: true,
|
|
16
15
|
})
|
|
17
16
|
.option('remote', {
|
|
18
17
|
alias: 'r',
|
|
19
|
-
describe: 'List all available
|
|
18
|
+
describe: 'List all available remote versions',
|
|
20
19
|
type: 'boolean',
|
|
21
20
|
})
|
|
22
|
-
.
|
|
21
|
+
.option('provider', {
|
|
22
|
+
alias: 'p',
|
|
23
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
24
|
+
type: 'string',
|
|
25
|
+
default: 'terraform',
|
|
26
|
+
})
|
|
27
|
+
.epilog([
|
|
28
|
+
'Examples:',
|
|
29
|
+
' tfv ls List locally installed terraform versions',
|
|
30
|
+
' tfv ls --remote List all available terraform versions',
|
|
31
|
+
' tfv ls --remote --provider tofu List all available opentofu versions',
|
|
32
|
+
].join('\n'))
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
exports.handler = async () => {
|
|
26
|
-
const {local, remote} =
|
|
27
|
-
await list(local, remote);
|
|
35
|
+
exports.handler = async (argv) => {
|
|
36
|
+
const { local, remote, provider } = argv;
|
|
37
|
+
await list(local, remote, provider);
|
|
28
38
|
}
|
|
29
|
-
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { pin } = require('../modules/pin');
|
|
4
|
+
|
|
5
|
+
exports.command = 'pin [ver]'
|
|
6
|
+
exports.desc = 'Pin the active (or specified) version to a .terraform-version file'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.option('provider', {
|
|
10
|
+
alias: 'p',
|
|
11
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
12
|
+
type: 'string',
|
|
13
|
+
default: 'terraform',
|
|
14
|
+
})
|
|
15
|
+
.epilog([
|
|
16
|
+
'Creates a .terraform-version file in the current directory.',
|
|
17
|
+
'Examples:',
|
|
18
|
+
' tfv pin Pin currently active version',
|
|
19
|
+
' tfv pin 1.7.3 Pin a specific version',
|
|
20
|
+
' tfv pin --provider tofu',
|
|
21
|
+
].join('\n'))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
exports.handler = async (argv) => {
|
|
25
|
+
await pin(argv.ver, argv.provider);
|
|
26
|
+
}
|
package/lib/commands/plan.js
CHANGED
|
@@ -11,12 +11,17 @@ exports.builder = (yargs) => {
|
|
|
11
11
|
describe: 'Terraform file(s) to extract targets from',
|
|
12
12
|
type: 'array',
|
|
13
13
|
})
|
|
14
|
+
.option('provider', {
|
|
15
|
+
alias: 'p',
|
|
16
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
17
|
+
type: 'string',
|
|
18
|
+
default: 'terraform',
|
|
19
|
+
})
|
|
14
20
|
.epilog('Accepts all terraform flags after --\nExample:\n tfv plan --file main.tf --file network.tf -- -auto-approve -target=<TARGET> -var="env=prod"')
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
exports.handler = async (argv) => {
|
|
18
|
-
const {file, _} = argv;
|
|
19
|
-
// Extra args come after -- in the command line
|
|
24
|
+
const {file, _, provider} = argv;
|
|
20
25
|
const extraArgs = _.slice(1);
|
|
21
|
-
await runTerraformCommand('plan', file, extraArgs);
|
|
26
|
+
await runTerraformCommand('plan', file, extraArgs, provider);
|
|
22
27
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { prune } = require('../modules/prune');
|
|
4
|
+
|
|
5
|
+
exports.command = 'prune'
|
|
6
|
+
exports.desc = 'Remove all non-active installed versions to free disk space'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.option('keep', {
|
|
10
|
+
alias: 'k',
|
|
11
|
+
describe: 'Keep the N most recent versions in addition to the active one',
|
|
12
|
+
type: 'number',
|
|
13
|
+
default: 0,
|
|
14
|
+
})
|
|
15
|
+
.option('provider', {
|
|
16
|
+
alias: 'p',
|
|
17
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
18
|
+
type: 'string',
|
|
19
|
+
default: 'terraform',
|
|
20
|
+
})
|
|
21
|
+
.option('yes', {
|
|
22
|
+
alias: 'y',
|
|
23
|
+
describe: 'Skip confirmation prompt',
|
|
24
|
+
type: 'boolean',
|
|
25
|
+
default: false,
|
|
26
|
+
})
|
|
27
|
+
.epilog([
|
|
28
|
+
'Always keeps the currently active version.',
|
|
29
|
+
'',
|
|
30
|
+
'Examples:',
|
|
31
|
+
' tfv prune # remove all but active',
|
|
32
|
+
' tfv prune --keep 2 # remove all but active + 2 most recent',
|
|
33
|
+
' tfv prune --provider tofu',
|
|
34
|
+
' tfv prune --yes # skip confirmation',
|
|
35
|
+
].join('\n'))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.handler = async (argv) => {
|
|
39
|
+
const { provider, keep, yes } = argv;
|
|
40
|
+
await prune(provider, keep, yes);
|
|
41
|
+
}
|
package/lib/commands/remove.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {remove} = require('../modules/remove');
|
|
3
|
+
const { remove } = require('../modules/remove');
|
|
5
4
|
|
|
6
|
-
exports.command = 'remove <
|
|
5
|
+
exports.command = 'remove <ver>'
|
|
7
6
|
exports.aliases = ['rm']
|
|
8
|
-
exports.desc = 'Remove terraform versions from tfv store'
|
|
7
|
+
exports.desc = 'Remove terraform/opentofu versions from tfv store'
|
|
9
8
|
exports.builder = (yargs) => {
|
|
10
9
|
return yargs
|
|
11
|
-
.option('
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
.option('provider', {
|
|
11
|
+
alias: 'p',
|
|
12
|
+
describe: 'Provider: terraform (default) or tofu/opentofu',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: 'terraform',
|
|
14
15
|
})
|
|
15
|
-
.epilog(
|
|
16
|
+
.epilog([
|
|
17
|
+
'Examples:',
|
|
18
|
+
' tfv rm 1.5.7 1.4.6',
|
|
19
|
+
' tfv rm 1.7.3 --provider tofu',
|
|
20
|
+
].join('\n'))
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
exports.handler = async () => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
await remove(
|
|
23
|
+
exports.handler = async (argv) => {
|
|
24
|
+
const versions = argv._.slice(1);
|
|
25
|
+
const { provider } = argv;
|
|
26
|
+
await remove(versions, provider);
|
|
22
27
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { shellInit } = require('../modules/shell-init');
|
|
4
|
+
|
|
5
|
+
exports.command = 'shell-init <shell>'
|
|
6
|
+
exports.desc = 'Generate shell hook for automatic version switching on cd'
|
|
7
|
+
exports.builder = (yargs) => {
|
|
8
|
+
return yargs
|
|
9
|
+
.positional('shell', {
|
|
10
|
+
describe: 'Shell to generate hook for',
|
|
11
|
+
choices: ['bash', 'zsh', 'fish', 'powershell', 'pwsh'],
|
|
12
|
+
})
|
|
13
|
+
.epilog([
|
|
14
|
+
'Outputs a shell script to stdout intended to be eval\'d.',
|
|
15
|
+
'Setup instructions are printed to stderr.',
|
|
16
|
+
'',
|
|
17
|
+
'Bash/Zsh: eval "$(tfv shell-init zsh)" # add to ~/.zshrc',
|
|
18
|
+
'Fish: tfv shell-init fish | source # add to config.fish',
|
|
19
|
+
'PowerShell: Invoke-Expression (tfv shell-init powershell | Out-String)',
|
|
20
|
+
].join('\n'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.handler = (argv) => {
|
|
24
|
+
shellInit(argv.shell);
|
|
25
|
+
}
|