terruvim-cli 0.0.1
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 +374 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +244 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/oclif.manifest.json +39 -0
- package/package.json +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
terruvim-cli
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
Terruvim CLI
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
[](https://oclif.io)
|
|
8
|
+
[](https://npmjs.org/package/terruvim-cli)
|
|
9
|
+
[](https://npmjs.org/package/terruvim-cli)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
<!-- toc -->
|
|
13
|
+
* [Usage](#usage)
|
|
14
|
+
* [Commands](#commands)
|
|
15
|
+
<!-- tocstop -->
|
|
16
|
+
# Usage
|
|
17
|
+
<!-- usage -->
|
|
18
|
+
```sh-session
|
|
19
|
+
$ npm install -g terruvim-cli
|
|
20
|
+
$ terruvim COMMAND
|
|
21
|
+
running command...
|
|
22
|
+
$ terruvim (--version)
|
|
23
|
+
terruvim-cli/0.0.1 linux-x64 node-v22.21.1
|
|
24
|
+
$ terruvim --help [COMMAND]
|
|
25
|
+
USAGE
|
|
26
|
+
$ terruvim COMMAND
|
|
27
|
+
...
|
|
28
|
+
```
|
|
29
|
+
<!-- usagestop -->
|
|
30
|
+
# Commands
|
|
31
|
+
<!-- commands -->
|
|
32
|
+
* [`terruvim help [COMMAND]`](#terruvim-help-command)
|
|
33
|
+
* [`terruvim init [NAME]`](#terruvim-init-name)
|
|
34
|
+
* [`terruvim plugins`](#terruvim-plugins)
|
|
35
|
+
* [`terruvim plugins add PLUGIN`](#terruvim-plugins-add-plugin)
|
|
36
|
+
* [`terruvim plugins:inspect PLUGIN...`](#terruvim-pluginsinspect-plugin)
|
|
37
|
+
* [`terruvim plugins install PLUGIN`](#terruvim-plugins-install-plugin)
|
|
38
|
+
* [`terruvim plugins link PATH`](#terruvim-plugins-link-path)
|
|
39
|
+
* [`terruvim plugins remove [PLUGIN]`](#terruvim-plugins-remove-plugin)
|
|
40
|
+
* [`terruvim plugins reset`](#terruvim-plugins-reset)
|
|
41
|
+
* [`terruvim plugins uninstall [PLUGIN]`](#terruvim-plugins-uninstall-plugin)
|
|
42
|
+
* [`terruvim plugins unlink [PLUGIN]`](#terruvim-plugins-unlink-plugin)
|
|
43
|
+
* [`terruvim plugins update`](#terruvim-plugins-update)
|
|
44
|
+
|
|
45
|
+
## `terruvim help [COMMAND]`
|
|
46
|
+
|
|
47
|
+
Display help for terruvim.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
USAGE
|
|
51
|
+
$ terruvim help [COMMAND...] [-n]
|
|
52
|
+
|
|
53
|
+
ARGUMENTS
|
|
54
|
+
[COMMAND...] Command to show help for.
|
|
55
|
+
|
|
56
|
+
FLAGS
|
|
57
|
+
-n, --nested-commands Include all nested commands in the output.
|
|
58
|
+
|
|
59
|
+
DESCRIPTION
|
|
60
|
+
Display help for terruvim.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.36/src/commands/help.ts)_
|
|
64
|
+
|
|
65
|
+
## `terruvim init [NAME]`
|
|
66
|
+
|
|
67
|
+
Scaffold a new Terruvim project via Interactive Wizard
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
USAGE
|
|
71
|
+
$ terruvim init [NAME] [-f]
|
|
72
|
+
|
|
73
|
+
ARGUMENTS
|
|
74
|
+
[NAME] Name of the project directory
|
|
75
|
+
|
|
76
|
+
FLAGS
|
|
77
|
+
-f, --force Overwrite existing files
|
|
78
|
+
|
|
79
|
+
DESCRIPTION
|
|
80
|
+
Scaffold a new Terruvim project via Interactive Wizard
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
_See code: [src/commands/init.ts](https://github.com/vlad-vorobei/terruvim-cli/blob/v0.0.1/src/commands/init.ts)_
|
|
84
|
+
|
|
85
|
+
## `terruvim plugins`
|
|
86
|
+
|
|
87
|
+
List installed plugins.
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
USAGE
|
|
91
|
+
$ terruvim plugins [--json] [--core]
|
|
92
|
+
|
|
93
|
+
FLAGS
|
|
94
|
+
--core Show core plugins.
|
|
95
|
+
|
|
96
|
+
GLOBAL FLAGS
|
|
97
|
+
--json Format output as json.
|
|
98
|
+
|
|
99
|
+
DESCRIPTION
|
|
100
|
+
List installed plugins.
|
|
101
|
+
|
|
102
|
+
EXAMPLES
|
|
103
|
+
$ terruvim plugins
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/index.ts)_
|
|
107
|
+
|
|
108
|
+
## `terruvim plugins add PLUGIN`
|
|
109
|
+
|
|
110
|
+
Installs a plugin into terruvim.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
USAGE
|
|
114
|
+
$ terruvim plugins add PLUGIN... [--json] [-f] [-h] [-s | -v]
|
|
115
|
+
|
|
116
|
+
ARGUMENTS
|
|
117
|
+
PLUGIN... Plugin to install.
|
|
118
|
+
|
|
119
|
+
FLAGS
|
|
120
|
+
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
|
|
121
|
+
-h, --help Show CLI help.
|
|
122
|
+
-s, --silent Silences npm output.
|
|
123
|
+
-v, --verbose Show verbose npm output.
|
|
124
|
+
|
|
125
|
+
GLOBAL FLAGS
|
|
126
|
+
--json Format output as json.
|
|
127
|
+
|
|
128
|
+
DESCRIPTION
|
|
129
|
+
Installs a plugin into terruvim.
|
|
130
|
+
|
|
131
|
+
Uses npm to install plugins.
|
|
132
|
+
|
|
133
|
+
Installation of a user-installed plugin will override a core plugin.
|
|
134
|
+
|
|
135
|
+
Use the TERRUVIM_NPM_LOG_LEVEL environment variable to set the npm loglevel.
|
|
136
|
+
Use the TERRUVIM_NPM_REGISTRY environment variable to set the npm registry.
|
|
137
|
+
|
|
138
|
+
ALIASES
|
|
139
|
+
$ terruvim plugins add
|
|
140
|
+
|
|
141
|
+
EXAMPLES
|
|
142
|
+
Install a plugin from npm registry.
|
|
143
|
+
|
|
144
|
+
$ terruvim plugins add myplugin
|
|
145
|
+
|
|
146
|
+
Install a plugin from a github url.
|
|
147
|
+
|
|
148
|
+
$ terruvim plugins add https://github.com/someuser/someplugin
|
|
149
|
+
|
|
150
|
+
Install a plugin from a github slug.
|
|
151
|
+
|
|
152
|
+
$ terruvim plugins add someuser/someplugin
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## `terruvim plugins:inspect PLUGIN...`
|
|
156
|
+
|
|
157
|
+
Displays installation properties of a plugin.
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
USAGE
|
|
161
|
+
$ terruvim plugins inspect PLUGIN...
|
|
162
|
+
|
|
163
|
+
ARGUMENTS
|
|
164
|
+
PLUGIN... [default: .] Plugin to inspect.
|
|
165
|
+
|
|
166
|
+
FLAGS
|
|
167
|
+
-h, --help Show CLI help.
|
|
168
|
+
-v, --verbose
|
|
169
|
+
|
|
170
|
+
GLOBAL FLAGS
|
|
171
|
+
--json Format output as json.
|
|
172
|
+
|
|
173
|
+
DESCRIPTION
|
|
174
|
+
Displays installation properties of a plugin.
|
|
175
|
+
|
|
176
|
+
EXAMPLES
|
|
177
|
+
$ terruvim plugins inspect myplugin
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/inspect.ts)_
|
|
181
|
+
|
|
182
|
+
## `terruvim plugins install PLUGIN`
|
|
183
|
+
|
|
184
|
+
Installs a plugin into terruvim.
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
USAGE
|
|
188
|
+
$ terruvim plugins install PLUGIN... [--json] [-f] [-h] [-s | -v]
|
|
189
|
+
|
|
190
|
+
ARGUMENTS
|
|
191
|
+
PLUGIN... Plugin to install.
|
|
192
|
+
|
|
193
|
+
FLAGS
|
|
194
|
+
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
|
|
195
|
+
-h, --help Show CLI help.
|
|
196
|
+
-s, --silent Silences npm output.
|
|
197
|
+
-v, --verbose Show verbose npm output.
|
|
198
|
+
|
|
199
|
+
GLOBAL FLAGS
|
|
200
|
+
--json Format output as json.
|
|
201
|
+
|
|
202
|
+
DESCRIPTION
|
|
203
|
+
Installs a plugin into terruvim.
|
|
204
|
+
|
|
205
|
+
Uses npm to install plugins.
|
|
206
|
+
|
|
207
|
+
Installation of a user-installed plugin will override a core plugin.
|
|
208
|
+
|
|
209
|
+
Use the TERRUVIM_NPM_LOG_LEVEL environment variable to set the npm loglevel.
|
|
210
|
+
Use the TERRUVIM_NPM_REGISTRY environment variable to set the npm registry.
|
|
211
|
+
|
|
212
|
+
ALIASES
|
|
213
|
+
$ terruvim plugins add
|
|
214
|
+
|
|
215
|
+
EXAMPLES
|
|
216
|
+
Install a plugin from npm registry.
|
|
217
|
+
|
|
218
|
+
$ terruvim plugins install myplugin
|
|
219
|
+
|
|
220
|
+
Install a plugin from a github url.
|
|
221
|
+
|
|
222
|
+
$ terruvim plugins install https://github.com/someuser/someplugin
|
|
223
|
+
|
|
224
|
+
Install a plugin from a github slug.
|
|
225
|
+
|
|
226
|
+
$ terruvim plugins install someuser/someplugin
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/install.ts)_
|
|
230
|
+
|
|
231
|
+
## `terruvim plugins link PATH`
|
|
232
|
+
|
|
233
|
+
Links a plugin into the CLI for development.
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
USAGE
|
|
237
|
+
$ terruvim plugins link PATH [-h] [--install] [-v]
|
|
238
|
+
|
|
239
|
+
ARGUMENTS
|
|
240
|
+
PATH [default: .] path to plugin
|
|
241
|
+
|
|
242
|
+
FLAGS
|
|
243
|
+
-h, --help Show CLI help.
|
|
244
|
+
-v, --verbose
|
|
245
|
+
--[no-]install Install dependencies after linking the plugin.
|
|
246
|
+
|
|
247
|
+
DESCRIPTION
|
|
248
|
+
Links a plugin into the CLI for development.
|
|
249
|
+
|
|
250
|
+
Installation of a linked plugin will override a user-installed or core plugin.
|
|
251
|
+
|
|
252
|
+
e.g. If you have a user-installed or core plugin that has a 'hello' command, installing a linked plugin with a 'hello'
|
|
253
|
+
command will override the user-installed or core plugin implementation. This is useful for development work.
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
EXAMPLES
|
|
257
|
+
$ terruvim plugins link myplugin
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/link.ts)_
|
|
261
|
+
|
|
262
|
+
## `terruvim plugins remove [PLUGIN]`
|
|
263
|
+
|
|
264
|
+
Removes a plugin from the CLI.
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
USAGE
|
|
268
|
+
$ terruvim plugins remove [PLUGIN...] [-h] [-v]
|
|
269
|
+
|
|
270
|
+
ARGUMENTS
|
|
271
|
+
[PLUGIN...] plugin to uninstall
|
|
272
|
+
|
|
273
|
+
FLAGS
|
|
274
|
+
-h, --help Show CLI help.
|
|
275
|
+
-v, --verbose
|
|
276
|
+
|
|
277
|
+
DESCRIPTION
|
|
278
|
+
Removes a plugin from the CLI.
|
|
279
|
+
|
|
280
|
+
ALIASES
|
|
281
|
+
$ terruvim plugins unlink
|
|
282
|
+
$ terruvim plugins remove
|
|
283
|
+
|
|
284
|
+
EXAMPLES
|
|
285
|
+
$ terruvim plugins remove myplugin
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## `terruvim plugins reset`
|
|
289
|
+
|
|
290
|
+
Remove all user-installed and linked plugins.
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
USAGE
|
|
294
|
+
$ terruvim plugins reset [--hard] [--reinstall]
|
|
295
|
+
|
|
296
|
+
FLAGS
|
|
297
|
+
--hard Delete node_modules and package manager related files in addition to uninstalling plugins.
|
|
298
|
+
--reinstall Reinstall all plugins after uninstalling.
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/reset.ts)_
|
|
302
|
+
|
|
303
|
+
## `terruvim plugins uninstall [PLUGIN]`
|
|
304
|
+
|
|
305
|
+
Removes a plugin from the CLI.
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
USAGE
|
|
309
|
+
$ terruvim plugins uninstall [PLUGIN...] [-h] [-v]
|
|
310
|
+
|
|
311
|
+
ARGUMENTS
|
|
312
|
+
[PLUGIN...] plugin to uninstall
|
|
313
|
+
|
|
314
|
+
FLAGS
|
|
315
|
+
-h, --help Show CLI help.
|
|
316
|
+
-v, --verbose
|
|
317
|
+
|
|
318
|
+
DESCRIPTION
|
|
319
|
+
Removes a plugin from the CLI.
|
|
320
|
+
|
|
321
|
+
ALIASES
|
|
322
|
+
$ terruvim plugins unlink
|
|
323
|
+
$ terruvim plugins remove
|
|
324
|
+
|
|
325
|
+
EXAMPLES
|
|
326
|
+
$ terruvim plugins uninstall myplugin
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/uninstall.ts)_
|
|
330
|
+
|
|
331
|
+
## `terruvim plugins unlink [PLUGIN]`
|
|
332
|
+
|
|
333
|
+
Removes a plugin from the CLI.
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
USAGE
|
|
337
|
+
$ terruvim plugins unlink [PLUGIN...] [-h] [-v]
|
|
338
|
+
|
|
339
|
+
ARGUMENTS
|
|
340
|
+
[PLUGIN...] plugin to uninstall
|
|
341
|
+
|
|
342
|
+
FLAGS
|
|
343
|
+
-h, --help Show CLI help.
|
|
344
|
+
-v, --verbose
|
|
345
|
+
|
|
346
|
+
DESCRIPTION
|
|
347
|
+
Removes a plugin from the CLI.
|
|
348
|
+
|
|
349
|
+
ALIASES
|
|
350
|
+
$ terruvim plugins unlink
|
|
351
|
+
$ terruvim plugins remove
|
|
352
|
+
|
|
353
|
+
EXAMPLES
|
|
354
|
+
$ terruvim plugins unlink myplugin
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## `terruvim plugins update`
|
|
358
|
+
|
|
359
|
+
Update installed plugins.
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
USAGE
|
|
363
|
+
$ terruvim plugins update [-h] [-v]
|
|
364
|
+
|
|
365
|
+
FLAGS
|
|
366
|
+
-h, --help Show CLI help.
|
|
367
|
+
-v, --verbose
|
|
368
|
+
|
|
369
|
+
DESCRIPTION
|
|
370
|
+
Update installed plugins.
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/update.ts)_
|
|
374
|
+
<!-- commandsstop -->
|
package/bin/dev.cmd
ADDED
package/bin/dev.js
ADDED
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Init extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { Command, Flags, Args } from '@oclif/core';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import { execa } from 'execa';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import degit from 'degit';
|
|
8
|
+
import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt';
|
|
9
|
+
inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt);
|
|
10
|
+
const AWS_REGIONS = [
|
|
11
|
+
'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2',
|
|
12
|
+
'eu-central-1', 'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-north-1',
|
|
13
|
+
'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1',
|
|
14
|
+
'ca-central-1', 'sa-east-1'
|
|
15
|
+
];
|
|
16
|
+
export default class Init extends Command {
|
|
17
|
+
static description = 'Scaffold a new Terruvim project via Interactive Wizard';
|
|
18
|
+
static args = {
|
|
19
|
+
name: Args.string({ description: 'Name of the project directory', required: false }),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
force: Flags.boolean({ char: 'f', description: 'Overwrite existing files' }),
|
|
23
|
+
};
|
|
24
|
+
async run() {
|
|
25
|
+
const { args, flags } = await this.parse(Init);
|
|
26
|
+
this.log('🚀 Welcome to Terruvim Project Wizard\n');
|
|
27
|
+
let projectName = args.name || '';
|
|
28
|
+
let projectDir = '';
|
|
29
|
+
let forceOverwrite = flags.force;
|
|
30
|
+
while (true) {
|
|
31
|
+
if (!projectName) {
|
|
32
|
+
const nameResponse = await inquirer.prompt([{
|
|
33
|
+
name: 'name',
|
|
34
|
+
message: 'What is the name of your project?',
|
|
35
|
+
type: 'input',
|
|
36
|
+
default: 'my-terruvim-app',
|
|
37
|
+
}]);
|
|
38
|
+
projectName = nameResponse.name;
|
|
39
|
+
}
|
|
40
|
+
projectDir = path.resolve(process.cwd(), projectName);
|
|
41
|
+
const exists = await fs.pathExists(projectDir);
|
|
42
|
+
if (exists && !forceOverwrite) {
|
|
43
|
+
const actionResponse = await inquirer.prompt([{
|
|
44
|
+
name: 'action',
|
|
45
|
+
message: `Directory "${projectName}" already exists. What do you want to do?`,
|
|
46
|
+
type: 'list',
|
|
47
|
+
choices: [
|
|
48
|
+
{ name: 'Overwrite (⚠️ Destructive)', value: 'overwrite' },
|
|
49
|
+
{ name: 'Rename project', value: 'rename' },
|
|
50
|
+
{ name: 'Abort', value: 'abort' }
|
|
51
|
+
]
|
|
52
|
+
}]);
|
|
53
|
+
if (actionResponse.action === 'abort') {
|
|
54
|
+
this.log('Aborting...');
|
|
55
|
+
return this.exit(0);
|
|
56
|
+
}
|
|
57
|
+
else if (actionResponse.action === 'rename') {
|
|
58
|
+
projectName = '';
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
else if (actionResponse.action === 'overwrite') {
|
|
62
|
+
forceOverwrite = true;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const answers = await inquirer.prompt([
|
|
71
|
+
{
|
|
72
|
+
name: 'providerName',
|
|
73
|
+
message: 'What is the provider?',
|
|
74
|
+
type: 'list',
|
|
75
|
+
choices: [
|
|
76
|
+
{ name: 'AWS', value: 'aws', checked: true },
|
|
77
|
+
{ name: 'Azure', value: 'azure', disabled: true },
|
|
78
|
+
{ name: 'Google Cloud', value: 'gcp', disabled: true },
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'awsRegion',
|
|
83
|
+
message: 'Select AWS Region:',
|
|
84
|
+
type: 'autocomplete',
|
|
85
|
+
when: (answers) => answers.providerName === 'aws',
|
|
86
|
+
source: async (_answers, input) => {
|
|
87
|
+
if (!input)
|
|
88
|
+
return AWS_REGIONS;
|
|
89
|
+
return AWS_REGIONS.filter(region => region.includes(input.toLowerCase()));
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'templateType',
|
|
94
|
+
message: 'Which architecture do you want to use?',
|
|
95
|
+
type: 'list',
|
|
96
|
+
choices: [
|
|
97
|
+
{ name: 'Django Project (Default)', value: 'default', checked: true },
|
|
98
|
+
{ name: 'Monolith (Simple)', value: 'monolith', disabled: true },
|
|
99
|
+
{ name: 'Microservices (Advanced)', value: 'microservices', disabled: true },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'environments',
|
|
104
|
+
message: 'Select environments to configure:',
|
|
105
|
+
type: 'checkbox',
|
|
106
|
+
choices: [
|
|
107
|
+
{ name: 'Development', value: 'dev', checked: true },
|
|
108
|
+
{ name: 'Staging', value: 'stage' },
|
|
109
|
+
{ name: 'Production', value: 'prod' },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'installDependencies',
|
|
114
|
+
message: 'Do you want to install dependencies now?',
|
|
115
|
+
type: 'confirm',
|
|
116
|
+
default: true,
|
|
117
|
+
}
|
|
118
|
+
]);
|
|
119
|
+
if (forceOverwrite && await fs.pathExists(projectDir)) {
|
|
120
|
+
const cleanupSpinner = ora(`Cleaning up ${projectDir}...`).start();
|
|
121
|
+
await fs.emptyDir(projectDir);
|
|
122
|
+
cleanupSpinner.succeed('Directory cleaned');
|
|
123
|
+
}
|
|
124
|
+
const downloadSpinner = ora('Downloading template structure...').start();
|
|
125
|
+
const repo = 'https://github.com/Terruvim/terruvim-templates.git';
|
|
126
|
+
const subfolder = answers.templateType;
|
|
127
|
+
const source = `${repo}/${subfolder}#main`;
|
|
128
|
+
try {
|
|
129
|
+
const emitter = degit(source, {
|
|
130
|
+
cache: false,
|
|
131
|
+
force: true,
|
|
132
|
+
verbose: true,
|
|
133
|
+
});
|
|
134
|
+
await emitter.clone(projectDir);
|
|
135
|
+
downloadSpinner.succeed('Template downloaded successfully');
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
downloadSpinner.fail('Failed to download template');
|
|
139
|
+
this.error(`Check if repository exists and you have internet connection.\nDetails: ${error}`);
|
|
140
|
+
}
|
|
141
|
+
const configSpinner = ora('Configuring environments...').start();
|
|
142
|
+
try {
|
|
143
|
+
const pkgJsonPath = path.join(projectDir, 'package.json');
|
|
144
|
+
if (await fs.pathExists(pkgJsonPath)) {
|
|
145
|
+
const pkgJson = await fs.readJson(pkgJsonPath);
|
|
146
|
+
pkgJson.name = projectName;
|
|
147
|
+
await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
148
|
+
}
|
|
149
|
+
const pulumiYamlPath = path.join(projectDir, 'Pulumi.yaml');
|
|
150
|
+
if (await fs.pathExists(pulumiYamlPath)) {
|
|
151
|
+
let yamlContent = await fs.readFile(pulumiYamlPath, 'utf8');
|
|
152
|
+
yamlContent = yamlContent.replace(/^name:.*$/m, `name: ${projectName}`);
|
|
153
|
+
yamlContent = yamlContent.replace(/^description:.*$/m, `description: Deploy ${projectName.toUpperCase()} infra with Terruvim`);
|
|
154
|
+
await fs.writeFile(pulumiYamlPath, yamlContent);
|
|
155
|
+
}
|
|
156
|
+
const envsDir = path.join(projectDir, 'envs');
|
|
157
|
+
const knownEnvs = ['dev', 'stage', 'prod'];
|
|
158
|
+
if (await fs.pathExists(envsDir)) {
|
|
159
|
+
for (const env of knownEnvs) {
|
|
160
|
+
if (!answers.environments.includes(env)) {
|
|
161
|
+
const fileToRemove = path.join(envsDir, `infrastructure.${env}.json`);
|
|
162
|
+
if (await fs.pathExists(fileToRemove)) {
|
|
163
|
+
await fs.remove(fileToRemove);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const readmePath = path.join(projectDir, 'AWS-README.md');
|
|
169
|
+
if (await fs.pathExists(readmePath)) {
|
|
170
|
+
let readmeContent = await fs.readFile(readmePath, 'utf8');
|
|
171
|
+
readmeContent = readmeContent.replace(/{{PROJECT_NAME}}/g, projectName);
|
|
172
|
+
await fs.writeFile(readmePath, readmeContent);
|
|
173
|
+
}
|
|
174
|
+
const stacksToGenerate = [...answers.environments, 'root'];
|
|
175
|
+
const targetPulumiDir = path.join(projectDir, 'pulumi');
|
|
176
|
+
await fs.ensureDir(targetPulumiDir);
|
|
177
|
+
for (const env of stacksToGenerate) {
|
|
178
|
+
const fileName = `Pulumi.${projectName}-${env}.yaml`;
|
|
179
|
+
const filePath = path.join(targetPulumiDir, fileName);
|
|
180
|
+
let content = '';
|
|
181
|
+
if (answers.providerName === 'aws') {
|
|
182
|
+
const profileName = `${projectName}-${env}`;
|
|
183
|
+
const region = answers.awsRegion || 'us-east-1';
|
|
184
|
+
content = `config:
|
|
185
|
+
aws:profile: ${profileName}
|
|
186
|
+
aws:region: ${region}
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
content = `config:\n`;
|
|
191
|
+
}
|
|
192
|
+
await fs.writeFile(filePath, content);
|
|
193
|
+
}
|
|
194
|
+
configSpinner.succeed('Configuration files generated');
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
configSpinner.fail('Configuration failed');
|
|
198
|
+
this.error(error);
|
|
199
|
+
}
|
|
200
|
+
if (answers.installDependencies) {
|
|
201
|
+
const installSpinner = ora('Installing dependencies...').start();
|
|
202
|
+
try {
|
|
203
|
+
await execa('npm', ['install'], {
|
|
204
|
+
cwd: projectDir,
|
|
205
|
+
});
|
|
206
|
+
installSpinner.succeed('Dependencies installed');
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
installSpinner.fail('Dependency installation failed');
|
|
210
|
+
this.warn('You can run "npm install" manually later.');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
this.log('\n==================================================');
|
|
214
|
+
this.log('🎉 Project setup complete!');
|
|
215
|
+
this.log('==================================================\n');
|
|
216
|
+
this.log(`📂 Project Location: ${projectDir}\n`);
|
|
217
|
+
this.log('👉 Next Steps:\n');
|
|
218
|
+
this.log(`1. Navigate to project:\n $ cd ${projectName}\n`);
|
|
219
|
+
if (!answers.installDependencies) {
|
|
220
|
+
this.log('2. Install dependencies:\n $ npm install\n');
|
|
221
|
+
}
|
|
222
|
+
this.log('🐳 Docker Requirement:');
|
|
223
|
+
this.log(' Ensure Docker is running! It is required for initial local builds.\n');
|
|
224
|
+
this.log('🔮 Pulumi Setup:');
|
|
225
|
+
this.log(' 1. Sign up or Login: https://app.pulumi.com/signup');
|
|
226
|
+
this.log(' 2. Authenticate CLI: $ pulumi login\n');
|
|
227
|
+
if (answers.providerName === 'aws') {
|
|
228
|
+
this.log('☁️ AWS Configuration:');
|
|
229
|
+
this.log(' You need an AWS Account and IAM User credentials with infrastructure access.');
|
|
230
|
+
this.log(' Ensure AWS CLI is installed and configured.\n');
|
|
231
|
+
this.log('🔐 Configure your ~/.aws/credentials file with the following profiles:\n');
|
|
232
|
+
this.log(` [${projectName}-root]`);
|
|
233
|
+
this.log(' aws_access_key_id=<YOUR_ACCESS_KEY>');
|
|
234
|
+
this.log(' aws_secret_access_key=<YOUR_SECRET_KEY>\n');
|
|
235
|
+
answers.environments.forEach(env => {
|
|
236
|
+
this.log(` [${projectName}-${env}]`);
|
|
237
|
+
this.log(' aws_access_key_id=<YOUR_ACCESS_KEY>');
|
|
238
|
+
this.log(' aws_secret_access_key=<YOUR_SECRET_KEY>\n');
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
this.log('🚀 Happy coding!');
|
|
242
|
+
return this.exit(0);
|
|
243
|
+
}
|
|
244
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commands": {
|
|
3
|
+
"init": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {
|
|
6
|
+
"name": {
|
|
7
|
+
"description": "Name of the project directory",
|
|
8
|
+
"name": "name",
|
|
9
|
+
"required": false
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"description": "Scaffold a new Terruvim project via Interactive Wizard",
|
|
13
|
+
"flags": {
|
|
14
|
+
"force": {
|
|
15
|
+
"char": "f",
|
|
16
|
+
"description": "Overwrite existing files",
|
|
17
|
+
"name": "force",
|
|
18
|
+
"allowNo": false,
|
|
19
|
+
"type": "boolean"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"hasDynamicHelp": false,
|
|
23
|
+
"hiddenAliases": [],
|
|
24
|
+
"id": "init",
|
|
25
|
+
"pluginAlias": "terruvim-cli",
|
|
26
|
+
"pluginName": "terruvim-cli",
|
|
27
|
+
"pluginType": "core",
|
|
28
|
+
"strict": true,
|
|
29
|
+
"enableJsonFlag": false,
|
|
30
|
+
"isESM": true,
|
|
31
|
+
"relativePath": [
|
|
32
|
+
"dist",
|
|
33
|
+
"commands",
|
|
34
|
+
"init.js"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"version": "0.0.1"
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "terruvim-cli",
|
|
3
|
+
"description": "CLI tool to scaffold and deploy Terruvim infrastructure on AWS using Pulumi",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"author": "Vlad Vorobei <vladyslavvorobei@gmail.com>",
|
|
6
|
+
"bin": {
|
|
7
|
+
"terruvim-cli": "./bin/run.js"
|
|
8
|
+
},
|
|
9
|
+
"bugs": "https://github.com/vlad-vorobei/terruvim-cli/issues",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@oclif/core": "^4",
|
|
12
|
+
"@oclif/plugin-help": "^6",
|
|
13
|
+
"@oclif/plugin-plugins": "^5",
|
|
14
|
+
"degit": "^2.8.4",
|
|
15
|
+
"execa": "^9.6.1",
|
|
16
|
+
"fs-extra": "^11.3.2",
|
|
17
|
+
"inquirer": "^9.3.8",
|
|
18
|
+
"inquirer-autocomplete-prompt": "^3.0.1",
|
|
19
|
+
"ora": "^9.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@eslint/compat": "^1",
|
|
23
|
+
"@oclif/prettier-config": "^0.2.1",
|
|
24
|
+
"@oclif/test": "^4",
|
|
25
|
+
"@types/chai": "^4",
|
|
26
|
+
"@types/degit": "^2.8.6",
|
|
27
|
+
"@types/fs-extra": "^11.0.4",
|
|
28
|
+
"@types/inquirer": "^9.0.9",
|
|
29
|
+
"@types/inquirer-autocomplete-prompt": "^3.0.3",
|
|
30
|
+
"@types/mocha": "^10",
|
|
31
|
+
"@types/node": "^18",
|
|
32
|
+
"chai": "^4",
|
|
33
|
+
"eslint": "^9",
|
|
34
|
+
"eslint-config-oclif": "^6",
|
|
35
|
+
"eslint-config-prettier": "^10",
|
|
36
|
+
"mocha": "^10",
|
|
37
|
+
"oclif": "^4",
|
|
38
|
+
"shx": "^0.3.3",
|
|
39
|
+
"ts-node": "^10",
|
|
40
|
+
"typescript": "^5"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"/bin",
|
|
47
|
+
"/dist",
|
|
48
|
+
"/oclif.manifest.json"
|
|
49
|
+
],
|
|
50
|
+
"homepage": "https://github.com/vlad-vorobei/terruvim-cli",
|
|
51
|
+
"keywords": [
|
|
52
|
+
"oclif",
|
|
53
|
+
"terruvim",
|
|
54
|
+
"infrastructure",
|
|
55
|
+
"pulumi",
|
|
56
|
+
"aws"
|
|
57
|
+
],
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"main": "dist/index.js",
|
|
60
|
+
"type": "module",
|
|
61
|
+
"oclif": {
|
|
62
|
+
"bin": "terruvim",
|
|
63
|
+
"dirname": "terruvim",
|
|
64
|
+
"commands": "./dist/commands",
|
|
65
|
+
"plugins": [
|
|
66
|
+
"@oclif/plugin-help",
|
|
67
|
+
"@oclif/plugin-plugins"
|
|
68
|
+
],
|
|
69
|
+
"topicSeparator": " ",
|
|
70
|
+
"topics": {}
|
|
71
|
+
},
|
|
72
|
+
"repository": {
|
|
73
|
+
"type": "git",
|
|
74
|
+
"url": "https://github.com/vlad-vorobei/terruvim-cli.git"
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"build": "shx rm -rf dist && tsc -b",
|
|
78
|
+
"lint": "eslint",
|
|
79
|
+
"postpack": "shx rm -f oclif.manifest.json",
|
|
80
|
+
"posttest": "npm run lint",
|
|
81
|
+
"prepack": "oclif manifest && oclif readme",
|
|
82
|
+
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
83
|
+
"version": "oclif readme && git add README.md"
|
|
84
|
+
},
|
|
85
|
+
"types": "dist/index.d.ts"
|
|
86
|
+
}
|