hereya-cli 0.11.0 → 0.13.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/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2025 Novopattern
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md CHANGED
@@ -20,7 +20,7 @@ $ npm install -g hereya-cli
20
20
  $ hereya COMMAND
21
21
  running command...
22
22
  $ hereya (--version)
23
- hereya-cli/0.11.0 linux-x64 node-v22.12.0
23
+ hereya-cli/0.13.0 linux-x64 node-v22.12.0
24
24
  $ hereya --help [COMMAND]
25
25
  USAGE
26
26
  $ hereya COMMAND
@@ -55,7 +55,7 @@ Add a package to the project.
55
55
 
56
56
  ```
57
57
  USAGE
58
- $ hereya add PACKAGE [--chdir <value>] [-p <value>]
58
+ $ hereya add PACKAGE [--chdir <value>] [--debug] [-p <value>]
59
59
 
60
60
  ARGUMENTS
61
61
  PACKAGE The package to add. Packages are gitHub repositories. Use the format owner/repository
@@ -64,6 +64,7 @@ FLAGS
64
64
  -p, --parameter=<value>... [default: ] parameter for the package, in the form of 'key=value'. Can be specified
65
65
  multiple times.
66
66
  --chdir=<value> directory to run command in
67
+ --debug enable debug mode
67
68
 
68
69
  DESCRIPTION
69
70
  Add a package to the project.
@@ -72,7 +73,7 @@ EXAMPLES
72
73
  $ hereya add cloudy/docker_postgres
73
74
  ```
74
75
 
75
- _See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/add/index.ts)_
76
+ _See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/add/index.ts)_
76
77
 
77
78
  ## `hereya bootstrap INFRASTRUCTURETYPE`
78
79
 
@@ -97,7 +98,7 @@ EXAMPLES
97
98
  $ hereya bootstrap local
98
99
  ```
99
100
 
100
- _See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/bootstrap/index.ts)_
101
+ _See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/bootstrap/index.ts)_
101
102
 
102
103
  ## `hereya deploy`
103
104
 
@@ -105,11 +106,12 @@ Deploy a hereya project using the project deployment package
105
106
 
106
107
  ```
107
108
  USAGE
108
- $ hereya deploy -w <value> [--chdir <value>]
109
+ $ hereya deploy -w <value> [--chdir <value>] [--debug]
109
110
 
110
111
  FLAGS
111
112
  -w, --workspace=<value> (required) name of the workspace to deploy the packages for
112
113
  --chdir=<value> directory to run command in
114
+ --debug enable debug mode
113
115
 
114
116
  DESCRIPTION
115
117
  Deploy a hereya project using the project deployment package
@@ -118,7 +120,7 @@ EXAMPLES
118
120
  $ hereya deploy
119
121
  ```
120
122
 
121
- _See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/deploy/index.ts)_
123
+ _See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/deploy/index.ts)_
122
124
 
123
125
  ## `hereya down`
124
126
 
@@ -126,11 +128,12 @@ Destroy all packages in the project.
126
128
 
127
129
  ```
128
130
  USAGE
129
- $ hereya down [--chdir <value>] [--deploy] [-w <value>]
131
+ $ hereya down [--chdir <value>] [--debug] [--deploy] [-w <value>]
130
132
 
131
133
  FLAGS
132
134
  -w, --workspace=<value> name of the workspace to install the packages for
133
135
  --chdir=<value> directory to run command in
136
+ --debug enable debug mode
134
137
  --deploy destroy deployment companion packages
135
138
 
136
139
  DESCRIPTION
@@ -140,7 +143,7 @@ EXAMPLES
140
143
  $ hereya down
141
144
  ```
142
145
 
143
- _See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/down/index.ts)_
146
+ _See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/down/index.ts)_
144
147
 
145
148
  ## `hereya env [NAME]`
146
149
 
@@ -171,7 +174,7 @@ EXAMPLES
171
174
  $ hereya env -w dev -l
172
175
  ```
173
176
 
174
- _See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/env/index.ts)_
177
+ _See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/env/index.ts)_
175
178
 
176
179
  ## `hereya help [COMMAND]`
177
180
 
@@ -217,7 +220,7 @@ EXAMPLES
217
220
  $ hereya init myProject -w=defaultWorkspace --chdir=./myProject
218
221
  ```
219
222
 
220
- _See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/init/index.ts)_
223
+ _See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/init/index.ts)_
221
224
 
222
225
  ## `hereya remove PACKAGE`
223
226
 
@@ -225,13 +228,14 @@ Remove a package from the project.
225
228
 
226
229
  ```
227
230
  USAGE
228
- $ hereya remove PACKAGE [--chdir <value>]
231
+ $ hereya remove PACKAGE [--chdir <value>] [--debug]
229
232
 
230
233
  ARGUMENTS
231
234
  PACKAGE The package to remove. Packages are gitHub repositories. Use the format owner/repository
232
235
 
233
236
  FLAGS
234
237
  --chdir=<value> directory to run command in
238
+ --debug enable debug mode
235
239
 
236
240
  DESCRIPTION
237
241
  Remove a package from the project.
@@ -240,7 +244,7 @@ EXAMPLES
240
244
  $ hereya remove cloudy/docker_postgres
241
245
  ```
242
246
 
243
- _See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/remove/index.ts)_
247
+ _See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/remove/index.ts)_
244
248
 
245
249
  ## `hereya run CMD`
246
250
 
@@ -266,7 +270,7 @@ EXAMPLES
266
270
  $ hereya run -w uat -- node index.js
267
271
  ```
268
272
 
269
- _See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/run/index.ts)_
273
+ _See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/run/index.ts)_
270
274
 
271
275
  ## `hereya unbootstrap INFRASTRUCTURETYPE`
272
276
 
@@ -291,7 +295,7 @@ EXAMPLES
291
295
  $ hereya unbootstrap local
292
296
  ```
293
297
 
294
- _See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/unbootstrap/index.ts)_
298
+ _See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/unbootstrap/index.ts)_
295
299
 
296
300
  ## `hereya undeploy`
297
301
 
@@ -299,11 +303,12 @@ Undeploy a hereya project by removing all resources.
299
303
 
300
304
  ```
301
305
  USAGE
302
- $ hereya undeploy -w <value> [--chdir <value>]
306
+ $ hereya undeploy -w <value> [--chdir <value>] [--debug]
303
307
 
304
308
  FLAGS
305
309
  -w, --workspace=<value> (required) name of the workspace to undeploy the packages for
306
310
  --chdir=<value> directory to run command in
311
+ --debug enable debug mode
307
312
 
308
313
  DESCRIPTION
309
314
  Undeploy a hereya project by removing all resources.
@@ -312,7 +317,7 @@ EXAMPLES
312
317
  $ hereya undeploy
313
318
  ```
314
319
 
315
- _See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/undeploy/index.ts)_
320
+ _See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/undeploy/index.ts)_
316
321
 
317
322
  ## `hereya up`
318
323
 
@@ -320,11 +325,12 @@ Provision all packages in the project.
320
325
 
321
326
  ```
322
327
  USAGE
323
- $ hereya up [--chdir <value>] [--deploy] [-w <value>]
328
+ $ hereya up [--chdir <value>] [--debug] [--deploy] [-w <value>]
324
329
 
325
330
  FLAGS
326
331
  -w, --workspace=<value> name of the workspace to install the packages for
327
332
  --chdir=<value> directory to run command in
333
+ --debug enable debug mode
328
334
  --deploy provision deployment companion packages
329
335
 
330
336
  DESCRIPTION
@@ -334,7 +340,7 @@ EXAMPLES
334
340
  $ hereya up
335
341
  ```
336
342
 
337
- _See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/up/index.ts)_
343
+ _See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/up/index.ts)_
338
344
 
339
345
  ## `hereya workspace create NAME`
340
346
 
@@ -354,7 +360,7 @@ EXAMPLES
354
360
  $ hereya workspace create dev
355
361
  ```
356
362
 
357
- _See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/create/index.ts)_
363
+ _See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/create/index.ts)_
358
364
 
359
365
  ## `hereya workspace delete NAME`
360
366
 
@@ -374,7 +380,7 @@ EXAMPLES
374
380
  $ hereya workspace delete dev
375
381
  ```
376
382
 
377
- _See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/delete/index.ts)_
383
+ _See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/delete/index.ts)_
378
384
 
379
385
  ## `hereya workspace env [NAME]`
380
386
 
@@ -400,7 +406,7 @@ EXAMPLES
400
406
  $ hereya workspace env myEnv -w dev
401
407
  ```
402
408
 
403
- _See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/env/index.ts)_
409
+ _See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/env/index.ts)_
404
410
 
405
411
  ## `hereya workspace env set`
406
412
 
@@ -424,7 +430,7 @@ EXAMPLES
424
430
  $ hereya workspace env set -w my-workspace -n myVar -v my-value -i aws -s
425
431
  ```
426
432
 
427
- _See code: [src/commands/workspace/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/env/set/index.ts)_
433
+ _See code: [src/commands/workspace/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/env/set/index.ts)_
428
434
 
429
435
  ## `hereya workspace env unset`
430
436
 
@@ -445,7 +451,7 @@ EXAMPLES
445
451
  $ hereya workspace env unset -w my-workspace -n myVar
446
452
  ```
447
453
 
448
- _See code: [src/commands/workspace/env/unset/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/env/unset/index.ts)_
454
+ _See code: [src/commands/workspace/env/unset/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/env/unset/index.ts)_
449
455
 
450
456
  ## `hereya workspace install PACKAGE`
451
457
 
@@ -471,7 +477,7 @@ EXAMPLES
471
477
  $ hereya workspace install hereya/aws-cognito
472
478
  ```
473
479
 
474
- _See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/install/index.ts)_
480
+ _See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/install/index.ts)_
475
481
 
476
482
  ## `hereya workspace uninstall PACKAGE`
477
483
 
@@ -497,5 +503,5 @@ EXAMPLES
497
503
  $ hereya workspace uninstall hereya/aws-cognito
498
504
  ```
499
505
 
500
- _See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.11.0/src/commands/workspace/uninstall/index.ts)_
506
+ _See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.13.0/src/commands/workspace/uninstall/index.ts)_
501
507
  <!-- commandsstop -->
@@ -7,6 +7,7 @@ export default class Add extends Command {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
11
  parameter: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
12
  };
12
13
  run(): Promise<void>;
@@ -4,33 +4,39 @@ import { provisionPackage } from '../../infrastructure/index.js';
4
4
  import { getConfigManager } from '../../lib/config/index.js';
5
5
  import { getEnvManager } from '../../lib/env/index.js';
6
6
  import { logEnv } from '../../lib/env-utils.js';
7
+ import { getLogger } from '../../lib/log.js';
7
8
  import { arrayOfStringToObject } from '../../lib/object-utils.js';
8
9
  import { getParameterManager } from '../../lib/parameter/index.js';
10
+ import { setDebug } from '../../lib/shell.js';
9
11
  export default class Add extends Command {
10
12
  static args = {
11
13
  package: Args.string({
12
14
  description: 'The package to add. Packages are gitHub repositories. Use the format owner/repository',
13
- required: true
15
+ required: true,
14
16
  }),
15
17
  };
16
18
  static description = 'Add a package to the project.';
17
- static examples = [
18
- '<%= config.bin %> <%= command.id %> cloudy/docker_postgres',
19
- ];
19
+ static examples = ['<%= config.bin %> <%= command.id %> cloudy/docker_postgres'];
20
20
  static flags = {
21
21
  chdir: Flags.string({
22
22
  description: 'directory to run command in',
23
23
  required: false,
24
24
  }),
25
+ debug: Flags.boolean({
26
+ default: false,
27
+ description: 'enable debug mode',
28
+ }),
25
29
  parameter: Flags.string({
26
30
  char: 'p',
27
31
  default: [],
28
- description: 'parameter for the package, in the form of \'key=value\'. Can be specified multiple times.',
32
+ description: "parameter for the package, in the form of 'key=value'. Can be specified multiple times.",
29
33
  multiple: true,
30
34
  }),
31
35
  };
32
36
  async run() {
33
37
  const { args, flags } = await this.parse(Add);
38
+ setDebug(flags.debug);
39
+ const logger = getLogger();
34
40
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
35
41
  const configManager = getConfigManager();
36
42
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -56,6 +62,7 @@ export default class Add extends Command {
56
62
  userSpecifiedParameters,
57
63
  workspace: config.workspace,
58
64
  });
65
+ logger.log(`Provisioning package ${args.package}`);
59
66
  const provisionOutput = await provisionPackage({
60
67
  env: workspaceEnv,
61
68
  package: args.package,
@@ -68,8 +75,8 @@ export default class Add extends Command {
68
75
  this.error(provisionOutput.reason);
69
76
  }
70
77
  const { env, metadata } = provisionOutput;
71
- this.log(`Package ${args.package} added successfully`);
72
- this.log(`Saving exported environment variables`);
78
+ logger.done(`Package ${args.package} provisioned successfully`);
79
+ logger.log(`Saving exported environment variables`);
73
80
  const envManager = getEnvManager();
74
81
  await envManager.addProjectEnv({
75
82
  env,
@@ -77,11 +84,14 @@ export default class Add extends Command {
77
84
  projectRootDir,
78
85
  workspace: config.workspace,
79
86
  });
87
+ logger.done('Saved exported environment variables');
88
+ logger.log('Adding package to hereya manifest');
80
89
  await configManager.addPackage({
81
90
  metadata,
82
91
  package: args.package,
83
92
  projectRootDir,
84
93
  });
94
+ logger.done('Package added to hereya manifest');
85
95
  const { config: newConfig } = await configManager.loadConfig({ projectRootDir });
86
96
  await backend.saveState(newConfig);
87
97
  const { filePath, saved } = await parameterManager.savePackageParameters({
@@ -91,8 +101,8 @@ export default class Add extends Command {
91
101
  workspace: config.workspace,
92
102
  });
93
103
  if (saved) {
94
- this.log(`Saved the following parameters for the package in ${filePath}:`);
95
- logEnv(parameters, this.log.bind(this));
104
+ await logger.done(`Saved the following parameters for the package in ${filePath}:`);
105
+ logEnv(parameters, (msg) => logger.done(msg));
96
106
  }
97
107
  }
98
108
  }
@@ -4,6 +4,7 @@ export default class Deploy extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
8
  workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
9
  };
9
10
  run(): Promise<void>;
@@ -5,7 +5,9 @@ import { destroyPackage, provisionPackage } from '../../infrastructure/index.js'
5
5
  import { getConfigManager } from '../../lib/config/index.js';
6
6
  import { getEnvManager } from '../../lib/env/index.js';
7
7
  import { logEnv } from '../../lib/env-utils.js';
8
+ import { getLogger } from '../../lib/log.js';
8
9
  import { getParameterManager } from '../../lib/parameter/index.js';
10
+ import { setDebug } from '../../lib/shell.js';
9
11
  import Up from '../up/index.js';
10
12
  export default class Deploy extends Command {
11
13
  static description = 'Deploy a hereya project using the project deployment package';
@@ -17,6 +19,10 @@ export default class Deploy extends Command {
17
19
  description: 'directory to run command in',
18
20
  required: false,
19
21
  }),
22
+ debug: Flags.boolean({
23
+ default: false,
24
+ description: 'enable debug mode',
25
+ }),
20
26
  workspace: Flags.string({
21
27
  char: 'w',
22
28
  description: 'name of the workspace to deploy the packages for',
@@ -25,6 +31,8 @@ export default class Deploy extends Command {
25
31
  };
26
32
  async run() {
27
33
  const { flags } = await this.parse(Deploy);
34
+ setDebug(flags.debug);
35
+ const logger = getLogger();
28
36
  const projectRootDir = path.resolve(flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR || process.cwd());
29
37
  const configManager = getConfigManager();
30
38
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -59,6 +67,9 @@ export default class Deploy extends Command {
59
67
  projectRootDir,
60
68
  workspace,
61
69
  });
70
+ if (removedPackages.length > 0) {
71
+ logger.log(`Destroying ${removedPackages.length} removed packages`);
72
+ }
62
73
  await Promise.all(removedPackages.map(async (packageName) => {
63
74
  const { parameters } = await parameterManager.getPackageParameters({
64
75
  package: packageName,
@@ -78,9 +89,12 @@ export default class Deploy extends Command {
78
89
  if (!destroyOutput.success) {
79
90
  this.error(destroyOutput.reason);
80
91
  }
81
- this.log(`Package ${packageName} un-deployed successfully`);
82
92
  }));
93
+ if (removedPackages.length > 0) {
94
+ logger.done(`Destroyed ${removedPackages.length} removed packages`);
95
+ }
83
96
  await Up.run(['--chdir', projectRootDir, '--workspace', workspace, '--deploy']);
97
+ logger.log(`Provisioning ${deployPackages.length} deployment packages`);
84
98
  const { env: newProjectEnv } = await envManager.getProjectEnv({
85
99
  markSecret: true,
86
100
  projectRootDir,
@@ -108,5 +122,6 @@ export default class Deploy extends Command {
108
122
  this.log(`Package ${packageName} deployed successfully`);
109
123
  logEnv(provisionOutput.env, this.log.bind(this));
110
124
  }));
125
+ logger.done(`Provisioned ${deployPackages.length} deployment packages`);
111
126
  }
112
127
  }
@@ -4,6 +4,7 @@ export default class Down extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
8
  deploy: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
9
  workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
10
  };
@@ -3,7 +3,9 @@ import { getBackend } from '../../backend/index.js';
3
3
  import { destroyPackage } from '../../infrastructure/index.js';
4
4
  import { getConfigManager } from '../../lib/config/index.js';
5
5
  import { getEnvManager } from '../../lib/env/index.js';
6
+ import { getLogger } from '../../lib/log.js';
6
7
  import { getParameterManager } from '../../lib/parameter/index.js';
8
+ import { setDebug } from '../../lib/shell.js';
7
9
  export default class Down extends Command {
8
10
  static description = 'Destroy all packages in the project.';
9
11
  static examples = [
@@ -14,6 +16,10 @@ export default class Down extends Command {
14
16
  description: 'directory to run command in',
15
17
  required: false,
16
18
  }),
19
+ debug: Flags.boolean({
20
+ default: false,
21
+ description: 'enable debug mode',
22
+ }),
17
23
  deploy: Flags.boolean({
18
24
  description: 'destroy deployment companion packages',
19
25
  required: false,
@@ -26,6 +32,8 @@ export default class Down extends Command {
26
32
  };
27
33
  async run() {
28
34
  const { flags } = await this.parse(Down);
35
+ setDebug(flags.debug);
36
+ const logger = getLogger();
29
37
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
30
38
  const configManager = getConfigManager();
31
39
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -46,6 +54,7 @@ export default class Down extends Command {
46
54
  }
47
55
  const { env: workspaceEnv } = getWorkspaceEnvOutput;
48
56
  const parameterManager = getParameterManager();
57
+ logger.log(`Destroying ${packages.length} packages`);
49
58
  const result = await Promise.all(packages.map(async (packageName) => {
50
59
  const { parameters } = await parameterManager.getPackageParameters({
51
60
  package: packageName,
@@ -63,10 +72,10 @@ export default class Down extends Command {
63
72
  if (!destroyOutput.success) {
64
73
  this.error(destroyOutput.reason);
65
74
  }
66
- this.log(`Package ${packageName} destroyed successfully`);
67
75
  const { env, metadata } = destroyOutput;
68
76
  return { env, metadata, packageName };
69
77
  }));
78
+ logger.done(`Destroyed ${packages.length} packages`);
70
79
  const envManager = getEnvManager();
71
80
  for (const { env, metadata } of result) {
72
81
  // eslint-disable-next-line no-await-in-loop
@@ -77,6 +86,7 @@ export default class Down extends Command {
77
86
  workspace,
78
87
  });
79
88
  }
89
+ logger.done(`Removed environment variables of ${packages.length} packages`);
80
90
  const { config: newConfig } = await configManager.loadConfig({ projectRootDir });
81
91
  await backend.saveState(newConfig);
82
92
  }
@@ -7,6 +7,7 @@ export default class Remove extends Command {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
10
11
  };
11
12
  run(): Promise<void>;
12
13
  }
@@ -3,26 +3,32 @@ import { getBackend } from '../../backend/index.js';
3
3
  import { destroyPackage } from '../../infrastructure/index.js';
4
4
  import { getConfigManager } from '../../lib/config/index.js';
5
5
  import { getEnvManager } from '../../lib/env/index.js';
6
+ import { getLogger } from '../../lib/log.js';
6
7
  import { getParameterManager } from '../../lib/parameter/index.js';
8
+ import { setDebug } from '../../lib/shell.js';
7
9
  export default class Remove extends Command {
8
10
  static args = {
9
11
  package: Args.string({
10
12
  description: 'The package to remove. Packages are gitHub repositories. Use the format owner/repository',
11
- required: true
13
+ required: true,
12
14
  }),
13
15
  };
14
16
  static description = 'Remove a package from the project.';
15
- static examples = [
16
- '<%= config.bin %> <%= command.id %> cloudy/docker_postgres',
17
- ];
17
+ static examples = ['<%= config.bin %> <%= command.id %> cloudy/docker_postgres'];
18
18
  static flags = {
19
19
  chdir: Flags.string({
20
20
  description: 'directory to run command in',
21
21
  required: false,
22
22
  }),
23
+ debug: Flags.boolean({
24
+ default: false,
25
+ description: 'enable debug mode',
26
+ }),
23
27
  };
24
28
  async run() {
25
29
  const { args, flags } = await this.parse(Remove);
30
+ setDebug(flags.debug);
31
+ const logger = getLogger();
26
32
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
27
33
  const configManager = getConfigManager();
28
34
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -50,6 +56,7 @@ export default class Remove extends Command {
50
56
  projectRootDir,
51
57
  workspace: config.workspace,
52
58
  });
59
+ logger.log(`Destroying package ${args.package}`);
53
60
  const destroyOutput = await destroyPackage({
54
61
  env: workspaceEnv,
55
62
  package: args.package,
@@ -63,21 +70,24 @@ export default class Remove extends Command {
63
70
  }
64
71
  const { env, metadata } = destroyOutput;
65
72
  if (!metadata.deploy) {
66
- this.log(`Infrastructure resources for ${args.package} have been destroyed`);
73
+ logger.done(`Destroyed infrastructure resources for ${args.package}`);
67
74
  }
68
- this.log('removing package env vars from project');
75
+ logger.log('removing package env vars from project');
69
76
  const envManager = getEnvManager();
70
77
  await envManager.removeProjectEnv({
71
78
  env,
72
79
  infra: metadata.infra,
73
80
  projectRootDir,
74
- workspace: config.workspace
81
+ workspace: config.workspace,
75
82
  });
83
+ logger.done('removed package env vars from project');
84
+ logger.log('removing package from hereya manifest');
76
85
  await configManager.removePackage({
77
86
  metadata,
78
87
  package: args.package,
79
88
  projectRootDir,
80
89
  });
90
+ logger.done('removed package from hereya manifest');
81
91
  const { config: newConfig } = await configManager.loadConfig({ projectRootDir });
82
92
  await backend.saveState(newConfig);
83
93
  }
@@ -4,6 +4,7 @@ export default class Undeploy extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
8
  workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
9
  };
9
10
  run(): Promise<void>;
@@ -4,18 +4,22 @@ import { getBackend } from '../../backend/index.js';
4
4
  import { destroyPackage } from '../../infrastructure/index.js';
5
5
  import { getConfigManager } from '../../lib/config/index.js';
6
6
  import { getEnvManager } from '../../lib/env/index.js';
7
+ import { getLogger } from '../../lib/log.js';
7
8
  import { getParameterManager } from '../../lib/parameter/index.js';
9
+ import { setDebug } from '../../lib/shell.js';
8
10
  import Down from '../down/index.js';
9
11
  export default class Undeploy extends Command {
10
12
  static description = 'Undeploy a hereya project by removing all resources.';
11
- static examples = [
12
- '<%= config.bin %> <%= command.id %>',
13
- ];
13
+ static examples = ['<%= config.bin %> <%= command.id %>'];
14
14
  static flags = {
15
15
  chdir: Flags.string({
16
16
  description: 'directory to run command in',
17
17
  required: false,
18
18
  }),
19
+ debug: Flags.boolean({
20
+ default: false,
21
+ description: 'enable debug mode',
22
+ }),
19
23
  workspace: Flags.string({
20
24
  char: 'w',
21
25
  description: 'name of the workspace to undeploy the packages for',
@@ -24,6 +28,8 @@ export default class Undeploy extends Command {
24
28
  };
25
29
  async run() {
26
30
  const { flags } = await this.parse(Undeploy);
31
+ setDebug(flags.debug);
32
+ const logger = getLogger();
27
33
  const projectRootDir = path.resolve(flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR || process.cwd());
28
34
  const configManager = getConfigManager();
29
35
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -50,6 +56,7 @@ export default class Undeploy extends Command {
50
56
  projectRootDir,
51
57
  workspace,
52
58
  });
59
+ logger.log(`Destroying ${deployPackages.length} deployment packages`);
53
60
  await Promise.all(deployPackages.map(async (packageName) => {
54
61
  const { parameters } = await parameterManager.getPackageParameters({
55
62
  package: packageName,
@@ -64,13 +71,14 @@ export default class Undeploy extends Command {
64
71
  project: config.project,
65
72
  projectEnv,
66
73
  projectRootDir,
67
- workspace
74
+ workspace,
68
75
  });
69
76
  if (!destroyOutput.success) {
70
77
  this.error(destroyOutput.reason);
71
78
  }
72
79
  this.log(`Package ${packageName} un-deployed successfully`);
73
80
  }));
81
+ logger.done(`Destroyed ${deployPackages.length} deployment packages`);
74
82
  await Down.run(['--chdir', projectRootDir, '--workspace', workspace, '--deploy']);
75
83
  }
76
84
  }
@@ -4,6 +4,7 @@ export default class Up extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  chdir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
8
  deploy: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
9
  workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
10
  };
@@ -3,17 +3,21 @@ import { getBackend } from '../../backend/index.js';
3
3
  import { destroyPackage, provisionPackage } from '../../infrastructure/index.js';
4
4
  import { getConfigManager } from '../../lib/config/index.js';
5
5
  import { getEnvManager } from '../../lib/env/index.js';
6
+ import { getLogger } from '../../lib/log.js';
6
7
  import { getParameterManager } from '../../lib/parameter/index.js';
8
+ import { setDebug } from '../../lib/shell.js';
7
9
  export default class Up extends Command {
8
10
  static description = 'Provision all packages in the project.';
9
- static examples = [
10
- '<%= config.bin %> <%= command.id %>',
11
- ];
11
+ static examples = ['<%= config.bin %> <%= command.id %>'];
12
12
  static flags = {
13
13
  chdir: Flags.string({
14
14
  description: 'directory to run command in',
15
15
  required: false,
16
16
  }),
17
+ debug: Flags.boolean({
18
+ default: false,
19
+ description: 'enable debug mode',
20
+ }),
17
21
  deploy: Flags.boolean({
18
22
  description: 'provision deployment companion packages',
19
23
  required: false,
@@ -26,6 +30,8 @@ export default class Up extends Command {
26
30
  };
27
31
  async run() {
28
32
  const { flags } = await this.parse(Up);
33
+ setDebug(flags.debug);
34
+ const logger = getLogger();
29
35
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
30
36
  const configManager = getConfigManager();
31
37
  const loadConfigOutput = await configManager.loadConfig({ projectRootDir });
@@ -54,6 +60,9 @@ export default class Up extends Command {
54
60
  }
55
61
  const { env: workspaceEnv } = getWorkspaceEnvOutput;
56
62
  const parameterManager = getParameterManager();
63
+ if (removedPackages.length > 0) {
64
+ logger.log(`Destroying ${removedPackages.length} removed packages`);
65
+ }
57
66
  const removed = await Promise.all(removedPackages.map(async (packageName) => {
58
67
  const { parameters } = await parameterManager.getPackageParameters({
59
68
  package: packageName,
@@ -71,10 +80,13 @@ export default class Up extends Command {
71
80
  if (!destroyOutput.success) {
72
81
  this.error(destroyOutput.reason);
73
82
  }
74
- this.log(`Package ${packageName} destroyed successfully`);
75
83
  const { env, metadata } = destroyOutput;
76
84
  return { env, metadata, packageName };
77
85
  }));
86
+ if (removedPackages.length > 0) {
87
+ logger.done(`Destroyed ${removedPackages.length} removed packages`);
88
+ }
89
+ logger.log(`Provisioning ${packages.length} packages`);
78
90
  const added = await Promise.all(packages.map(async (packageName) => {
79
91
  const { parameters } = await parameterManager.getPackageParameters({
80
92
  package: packageName,
@@ -93,9 +105,9 @@ export default class Up extends Command {
93
105
  this.error(provisionOutput.reason);
94
106
  }
95
107
  const { env, metadata } = provisionOutput;
96
- this.log(`Package ${packageName} provisioned successfully`);
97
108
  return { env, metadata, packageName };
98
109
  }));
110
+ logger.done(`Provisioned ${packages.length} packages`);
99
111
  const envManager = getEnvManager();
100
112
  for (const { env, metadata } of removed) {
101
113
  // eslint-disable-next-line no-await-in-loop
@@ -108,6 +120,9 @@ export default class Up extends Command {
108
120
  }),
109
121
  ]);
110
122
  }
123
+ if (removedPackages.length > 0) {
124
+ logger.done(`Removed env vars from ${removedPackages.length} removed packages`);
125
+ }
111
126
  for (const { env, metadata } of added) {
112
127
  // eslint-disable-next-line no-await-in-loop
113
128
  await envManager.addProjectEnv({
@@ -117,6 +132,7 @@ export default class Up extends Command {
117
132
  workspace,
118
133
  });
119
134
  }
135
+ logger.done('Saved exported environment variables');
120
136
  const { config: newConfig } = await configManager.loadConfig({ projectRootDir });
121
137
  await backend.saveState(newConfig);
122
138
  }
@@ -4,7 +4,10 @@ export interface Iac {
4
4
  }
5
5
  export declare enum IacType {
6
6
  cdk = "cdk",
7
- terraform = "terraform"
7
+ opentf = "opentf",
8
+ opentofu = "opentofu",
9
+ terraform = "terraform",
10
+ tofu = "tofu"
8
11
  }
9
12
  export type ApplyInput = {
10
13
  env: {
@@ -1,5 +1,8 @@
1
1
  export var IacType;
2
2
  (function (IacType) {
3
3
  IacType["cdk"] = "cdk";
4
+ IacType["opentf"] = "opentf";
5
+ IacType["opentofu"] = "opentofu";
4
6
  IacType["terraform"] = "terraform";
7
+ IacType["tofu"] = "tofu";
5
8
  })(IacType || (IacType = {}));
package/dist/iac/index.js CHANGED
@@ -8,6 +8,15 @@ export function getIac({ type }) {
8
8
  case IacType.terraform: {
9
9
  return { iac: terraform, supported: true };
10
10
  }
11
+ case IacType.opentofu: {
12
+ return { iac: terraform, supported: true };
13
+ }
14
+ case IacType.opentf: {
15
+ return { iac: terraform, supported: true };
16
+ }
17
+ case IacType.tofu: {
18
+ return { iac: terraform, supported: true };
19
+ }
11
20
  case IacType.cdk: {
12
21
  return { iac: cdk, supported: true };
13
22
  }
@@ -2,8 +2,9 @@ import { ApplyInput, ApplyOutput, DestroyInput, DestroyOutput, Iac } from './com
2
2
  export declare class Terraform implements Iac {
3
3
  apply(input: ApplyInput): Promise<ApplyOutput>;
4
4
  destroy(input: DestroyInput): Promise<DestroyOutput>;
5
- private downloadTerraform;
5
+ downloadTerraform(): Promise<boolean>;
6
6
  private getEnv;
7
7
  private getTerraformBinary;
8
+ private getWithRedirect;
8
9
  private terraformBinPath;
9
10
  }
@@ -114,20 +114,20 @@ export class Terraform {
114
114
  }
115
115
  async downloadTerraform() {
116
116
  const TERRAFORM_DOWNLOAD_URLS = new Map([
117
- ['darwin_arm64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_darwin_arm64.zip'],
118
- ['darwin_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_darwin_amd64.zip'],
119
- ['freebsd_arm', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_freebsd_arm.zip'],
120
- ['freebsd_ia32', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_freebsd_386.zip'],
121
- ['freebsd_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_freebsd_amd64.zip'],
122
- ['linux_arm', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_arm.zip'],
123
- ['linux_arm64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_arm64.zip'],
124
- ['linux_ia32', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_386.zip'],
125
- ['linux_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip'],
126
- ['openbsd_ia32', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_openbsd_386.zip'],
127
- ['openbsd_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_openbsd_amd64.zip'],
128
- ['sunos_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_solaris_amd64.zip'],
129
- ['win32_ia32', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_windows_386.zip'],
130
- ['win32_x64', 'https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_windows_amd64.zip'],
117
+ ['darwin_arm64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_darwin_arm64.zip'],
118
+ ['darwin_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_darwin_amd64.zip'],
119
+ ['freebsd_arm', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_freebsd_arm.zip'],
120
+ ['freebsd_ia32', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_freebsd_386.zip'],
121
+ ['freebsd_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_freebsd_amd64.zip'],
122
+ ['linux_arm', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_linux_arm.zip'],
123
+ ['linux_arm64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_linux_arm64.zip'],
124
+ ['linux_ia32', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_linux_386.zip'],
125
+ ['linux_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_linux_amd64.zip'],
126
+ ['openbsd_ia32', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_openbsd_386.zip'],
127
+ ['openbsd_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_openbsd_amd64.zip'],
128
+ ['sunos_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_solaris_amd64.zip'],
129
+ ['win32_ia32', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_windows_386.zip'],
130
+ ['win32_x64', 'https://github.com/opentofu/opentofu/releases/download/v1.9.0/tofu_1.9.0_windows_amd64.zip'],
131
131
  ]);
132
132
  const tfPath = this.terraformBinPath();
133
133
  try {
@@ -155,8 +155,7 @@ export class Terraform {
155
155
  }
156
156
  }
157
157
  await new Promise((resolve, reject) => {
158
- https
159
- .get(url, async (response) => {
158
+ this.getWithRedirect(url, async (response) => {
160
159
  try {
161
160
  await pipeline(response, decompress({ path: path.dirname(tfPath) }));
162
161
  await fs.promises.chmod(tfPath, '0755');
@@ -165,8 +164,7 @@ export class Terraform {
165
164
  throw new Error(`could not download terraform: ${error}`);
166
165
  }
167
166
  resolve(null);
168
- })
169
- .on('error', (error) => reject(error));
167
+ }, reject);
170
168
  });
171
169
  return true;
172
170
  }
@@ -192,7 +190,22 @@ export class Terraform {
192
190
  await this.downloadTerraform();
193
191
  return this.terraformBinPath();
194
192
  }
193
+ async getWithRedirect(url, handler, reject) {
194
+ https
195
+ .get(url, (response) => {
196
+ if (response.statusCode === 302) {
197
+ const { location } = response.headers;
198
+ if (location) {
199
+ this.getWithRedirect(location, handler, reject);
200
+ }
201
+ }
202
+ else {
203
+ handler(response);
204
+ }
205
+ })
206
+ .on('error', (error) => reject(error));
207
+ }
195
208
  terraformBinPath() {
196
- return path.join(os.homedir(), '.hereya', 'iac', 'terraform', os.platform() === 'win32' ? 'terraform.exe' : 'terraform');
209
+ return path.join(os.homedir(), '.hereya', 'iac', 'terraform', 'tofu_1', os.platform() === 'win32' ? 'tofu.exe' : 'tofu');
197
210
  }
198
211
  }
@@ -10,19 +10,19 @@ export function getInfrastructure(input) {
10
10
  case InfrastructureType.local: {
11
11
  return {
12
12
  infrastructure: localInfrastructure,
13
- supported: true
13
+ supported: true,
14
14
  };
15
15
  }
16
16
  case InfrastructureType.aws: {
17
17
  return {
18
18
  infrastructure: awsInfrastructure,
19
- supported: true
19
+ supported: true,
20
20
  };
21
21
  }
22
22
  default: {
23
23
  return {
24
24
  reason: `Infrastructure type ${input.type} is not supported yet!`,
25
- supported: false
25
+ supported: false,
26
26
  };
27
27
  }
28
28
  }
@@ -38,7 +38,6 @@ export async function destroyPackage(input) {
38
38
  return { reason: infrastructure$.reason, success: false };
39
39
  }
40
40
  if (metadata.deploy && input.skipDeploy) {
41
- console.log(`Skipping un-deployment of ${input.package}...`);
42
41
  return { env: {}, metadata, success: true };
43
42
  }
44
43
  const { infrastructure } = infrastructure$;
@@ -46,31 +45,33 @@ export async function destroyPackage(input) {
46
45
  const id$ = await backend.getProvisioningId({
47
46
  packageCanonicalName: canonicalName,
48
47
  project: input.project,
49
- workspace: input.workspace
48
+ workspace: input.workspace,
50
49
  });
51
50
  if (!id$.success) {
52
51
  return { reason: id$.reason, success: false };
53
52
  }
54
53
  const { id } = id$;
55
- const destroyOutput = metadata.deploy ? await infrastructure.undeploy({
56
- canonicalName,
57
- env: input.env,
58
- iacType: metadata.iac,
59
- id,
60
- parameters: input.parameters,
61
- pkgName,
62
- pkgUrl: packageUri,
63
- projectEnv: input.projectEnv ?? {},
64
- projectRootDir: input.projectRootDir,
65
- }) : await infrastructure.destroy({
66
- canonicalName,
67
- env: input.env,
68
- iacType: metadata.iac,
69
- id,
70
- parameters: input.parameters,
71
- pkgName,
72
- pkgUrl: packageUri,
73
- });
54
+ const destroyOutput = metadata.deploy
55
+ ? await infrastructure.undeploy({
56
+ canonicalName,
57
+ env: input.env,
58
+ iacType: metadata.iac,
59
+ id,
60
+ parameters: input.parameters,
61
+ pkgName,
62
+ pkgUrl: packageUri,
63
+ projectEnv: input.projectEnv ?? {},
64
+ projectRootDir: input.projectRootDir,
65
+ })
66
+ : await infrastructure.destroy({
67
+ canonicalName,
68
+ env: input.env,
69
+ iacType: metadata.iac,
70
+ id,
71
+ parameters: input.parameters,
72
+ pkgName,
73
+ pkgUrl: packageUri,
74
+ });
74
75
  if (!destroyOutput.success) {
75
76
  return { reason: destroyOutput.reason, success: false };
76
77
  }
@@ -79,10 +80,12 @@ export async function destroyPackage(input) {
79
80
  ...input,
80
81
  package: depName,
81
82
  })));
82
- if (!depsOutput.every(output => output.success)) {
83
+ if (!depsOutput.every((output) => output.success)) {
83
84
  return {
84
- reason: `Failed to destroy all dependencies: ${depsOutput.filter(o => !o.success).map(o => !o.success && o.reason)}`,
85
- success: false
85
+ reason: `Failed to destroy all dependencies: ${depsOutput
86
+ .filter((o) => !o.success)
87
+ .map((o) => !o.success && o.reason)}`,
88
+ success: false,
86
89
  };
87
90
  }
88
91
  return { env: destroyOutput.env, metadata, success: true };
@@ -98,7 +101,6 @@ export async function provisionPackage(input) {
98
101
  return { reason: infrastructure$.reason, success: false };
99
102
  }
100
103
  if (metadata.deploy && input.skipDeploy) {
101
- console.log(`Skipping deployment of ${input.package}...`);
102
104
  return { env: {}, metadata, success: true };
103
105
  }
104
106
  const dependencies = metadata.dependencies ?? {};
@@ -106,10 +108,12 @@ export async function provisionPackage(input) {
106
108
  ...input,
107
109
  package: depName,
108
110
  })));
109
- if (!depsOutput.every(output => output.success)) {
111
+ if (!depsOutput.every((output) => output.success)) {
110
112
  return {
111
- reason: `Failed to provision all dependencies: ${depsOutput.filter(o => !o.success).map(o => !o.success && o.reason)}`,
112
- success: false
113
+ reason: `Failed to provision all dependencies: ${depsOutput
114
+ .filter((o) => !o.success)
115
+ .map((o) => !o.success && o.reason)}`,
116
+ success: false,
113
117
  };
114
118
  }
115
119
  let depsEnv = {};
@@ -126,31 +130,33 @@ export async function provisionPackage(input) {
126
130
  const id$ = await backend.getProvisioningId({
127
131
  packageCanonicalName: canonicalName,
128
132
  project: input.project,
129
- workspace: input.workspace
133
+ workspace: input.workspace,
130
134
  });
131
135
  if (!id$.success) {
132
136
  return { reason: id$.reason, success: false };
133
137
  }
134
138
  const { id } = id$;
135
- const provisionOutput = metadata.deploy ? await infrastructure.deploy({
136
- canonicalName,
137
- env: { ...input.env, ...depsEnv },
138
- iacType: metadata.iac,
139
- id,
140
- parameters: input.parameters,
141
- pkgName,
142
- pkgUrl: packageUri,
143
- projectEnv: input.projectEnv ?? {},
144
- projectRootDir: input.projectRootDir,
145
- }) : await infrastructure.provision({
146
- canonicalName,
147
- env: input.env,
148
- iacType: metadata.iac,
149
- id,
150
- parameters: input.parameters,
151
- pkgName,
152
- pkgUrl: packageUri,
153
- });
139
+ const provisionOutput = metadata.deploy
140
+ ? await infrastructure.deploy({
141
+ canonicalName,
142
+ env: { ...input.env, ...depsEnv },
143
+ iacType: metadata.iac,
144
+ id,
145
+ parameters: input.parameters,
146
+ pkgName,
147
+ pkgUrl: packageUri,
148
+ projectEnv: input.projectEnv ?? {},
149
+ projectRootDir: input.projectRootDir,
150
+ })
151
+ : await infrastructure.provision({
152
+ canonicalName,
153
+ env: input.env,
154
+ iacType: metadata.iac,
155
+ id,
156
+ parameters: input.parameters,
157
+ pkgName,
158
+ pkgUrl: packageUri,
159
+ });
154
160
  if (!provisionOutput.success) {
155
161
  return { reason: provisionOutput.reason, success: false };
156
162
  }
@@ -0,0 +1,4 @@
1
+ export declare function getLogger(): {
2
+ done(message: string): void;
3
+ log(message: string): void;
4
+ };
@@ -0,0 +1,29 @@
1
+ import cliSpinners from 'cli-spinners';
2
+ import ora from 'ora';
3
+ let spinner = null;
4
+ const logger = {
5
+ done(message) {
6
+ if (!spinner) {
7
+ spinner = ora({
8
+ spinner: cliSpinners.aesthetic,
9
+ text: message,
10
+ });
11
+ }
12
+ spinner.succeed(message);
13
+ spinner = null;
14
+ },
15
+ log(message) {
16
+ if (spinner) {
17
+ spinner.text = message;
18
+ return;
19
+ }
20
+ spinner = ora({
21
+ spinner: cliSpinners.aesthetic,
22
+ text: message,
23
+ });
24
+ spinner.start();
25
+ },
26
+ };
27
+ export function getLogger() {
28
+ return logger;
29
+ }
@@ -55,11 +55,9 @@ export function getPackageCanonicalName(packageName) {
55
55
  }
56
56
  export async function downloadPackage(pkgUrl, destPath) {
57
57
  if (await isNotEmpty(destPath)) {
58
- console.log(`Package already downloaded at ${destPath}`);
59
58
  return destPath;
60
59
  }
61
60
  await fs.mkdir(destPath, { recursive: true });
62
- console.log(`Downloading package from ${pkgUrl}`);
63
61
  // Initialize simple-git
64
62
  const git = simpleGit();
65
63
  // Clone repository into temp directory
@@ -1,6 +1,8 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  /// <reference types="node" resolution-mode="require"/>
3
3
  import { StdioOptions, spawnSync } from 'node:child_process';
4
+ export declare function setDebug(value: boolean): void;
5
+ export declare function isDebug(): boolean;
4
6
  export type RunShellOptions = {
5
7
  directory?: string;
6
8
  env?: NodeJS.ProcessEnv;
package/dist/lib/shell.js CHANGED
@@ -1,4 +1,11 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ let debug = false;
3
+ export function setDebug(value) {
4
+ debug = value;
5
+ }
6
+ export function isDebug() {
7
+ return debug;
8
+ }
2
9
  export function runShell(cmd, args, options = {}) {
3
10
  // Run the command
4
11
  const result = spawnSync(cmd, args, {
@@ -6,7 +13,7 @@ export function runShell(cmd, args, options = {}) {
6
13
  encoding: 'utf8',
7
14
  env: { ...process.env, ...options.env },
8
15
  shell: true,
9
- stdio: options.stdio ?? 'inherit',
16
+ stdio: options.stdio ?? (isDebug() ? 'inherit' : 'ignore'),
10
17
  });
11
18
  // Throw an error if the command failed
12
19
  if (result.status !== 0) {
@@ -22,6 +22,12 @@
22
22
  "multiple": false,
23
23
  "type": "option"
24
24
  },
25
+ "debug": {
26
+ "description": "enable debug mode",
27
+ "name": "debug",
28
+ "allowNo": false,
29
+ "type": "boolean"
30
+ },
25
31
  "parameter": {
26
32
  "char": "p",
27
33
  "description": "parameter for the package, in the form of 'key=value'. Can be specified multiple times.",
@@ -64,6 +70,12 @@
64
70
  "multiple": false,
65
71
  "type": "option"
66
72
  },
73
+ "debug": {
74
+ "description": "enable debug mode",
75
+ "name": "debug",
76
+ "allowNo": false,
77
+ "type": "boolean"
78
+ },
67
79
  "workspace": {
68
80
  "char": "w",
69
81
  "description": "name of the workspace to deploy the packages for",
@@ -145,6 +157,12 @@
145
157
  "multiple": false,
146
158
  "type": "option"
147
159
  },
160
+ "debug": {
161
+ "description": "enable debug mode",
162
+ "name": "debug",
163
+ "allowNo": false,
164
+ "type": "boolean"
165
+ },
148
166
  "deploy": {
149
167
  "description": "destroy deployment companion packages",
150
168
  "name": "deploy",
@@ -307,6 +325,12 @@
307
325
  "hasDynamicHelp": false,
308
326
  "multiple": false,
309
327
  "type": "option"
328
+ },
329
+ "debug": {
330
+ "description": "enable debug mode",
331
+ "name": "debug",
332
+ "allowNo": false,
333
+ "type": "boolean"
310
334
  }
311
335
  },
312
336
  "hasDynamicHelp": false,
@@ -429,6 +453,12 @@
429
453
  "multiple": false,
430
454
  "type": "option"
431
455
  },
456
+ "debug": {
457
+ "description": "enable debug mode",
458
+ "name": "debug",
459
+ "allowNo": false,
460
+ "type": "boolean"
461
+ },
432
462
  "workspace": {
433
463
  "char": "w",
434
464
  "description": "name of the workspace to undeploy the packages for",
@@ -471,6 +501,12 @@
471
501
  "multiple": false,
472
502
  "type": "option"
473
503
  },
504
+ "debug": {
505
+ "description": "enable debug mode",
506
+ "name": "debug",
507
+ "allowNo": false,
508
+ "type": "boolean"
509
+ },
474
510
  "deploy": {
475
511
  "description": "provision deployment companion packages",
476
512
  "name": "deploy",
@@ -848,5 +884,5 @@
848
884
  ]
849
885
  }
850
886
  },
851
- "version": "0.11.0"
887
+ "version": "0.13.0"
852
888
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hereya-cli",
3
3
  "description": "Infrastructure as Package",
4
- "version": "0.11.0",
4
+ "version": "0.13.0",
5
5
  "author": "Hereya Developers",
6
6
  "bin": {
7
7
  "hereya": "./bin/run.js"
@@ -20,8 +20,10 @@
20
20
  "@oclif/plugin-help": "^6",
21
21
  "@oclif/plugin-plugins": "^5",
22
22
  "@octokit/rest": "^20.1.1",
23
+ "cli-spinners": "^3.2.0",
23
24
  "glob": "^10.4.1",
24
25
  "ignore": "^5.3.1",
26
+ "ora": "^8.1.1",
25
27
  "simple-git": "^3.24.0",
26
28
  "unzip-stream": "^0.3.4",
27
29
  "yaml": "^2.4.2",
@@ -29,7 +31,7 @@
29
31
  },
30
32
  "devDependencies": {
31
33
  "@oclif/prettier-config": "^0.2.1",
32
- "@oclif/test": "^4",
34
+ "@oclif/test": "^4.1.8",
33
35
  "@types/chai": "^4",
34
36
  "@types/mocha": "^10",
35
37
  "@types/mock-fs": "^4.13.4",