hereya-cli 0.12.0 → 0.13.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/LICENSE +13 -0
- package/README.md +31 -25
- package/dist/commands/add/index.d.ts +1 -0
- package/dist/commands/add/index.js +19 -9
- package/dist/commands/deploy/index.d.ts +1 -0
- package/dist/commands/deploy/index.js +16 -1
- package/dist/commands/down/index.d.ts +1 -0
- package/dist/commands/down/index.js +11 -1
- package/dist/commands/remove/index.d.ts +1 -0
- package/dist/commands/remove/index.js +17 -7
- package/dist/commands/undeploy/index.d.ts +1 -0
- package/dist/commands/undeploy/index.js +12 -4
- package/dist/commands/up/index.d.ts +1 -0
- package/dist/commands/up/index.js +21 -5
- package/dist/infrastructure/index.js +57 -51
- package/dist/lib/log.d.ts +4 -0
- package/dist/lib/log.js +29 -0
- package/dist/lib/package/github.d.ts +1 -1
- package/dist/lib/package/github.js +17 -17
- package/dist/lib/package/index.js +0 -2
- package/dist/lib/shell.d.ts +2 -0
- package/dist/lib/shell.js +8 -1
- package/oclif.manifest.json +115 -79
- package/package.json +4 -3
|
@@ -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
|
}
|
|
@@ -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
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
85
|
-
|
|
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
|
|
112
|
-
|
|
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
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
}
|
package/dist/lib/log.js
ADDED
|
@@ -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
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { GetRepoContentInput, GetRepoContentOutput, PackageManager } from './common.js';
|
|
2
2
|
export declare class GitHubPackageManager implements PackageManager {
|
|
3
|
-
getRepoContent({ owner, path, repo }: GetRepoContentInput): Promise<GetRepoContentOutput>;
|
|
3
|
+
getRepoContent({ owner, path: filePath, repo }: GetRepoContentInput): Promise<GetRepoContentOutput>;
|
|
4
4
|
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { downloadPackage } from './index.js';
|
|
2
5
|
export class GitHubPackageManager {
|
|
3
|
-
async getRepoContent({ owner, path, repo }) {
|
|
4
|
-
const
|
|
6
|
+
async getRepoContent({ owner, path: filePath, repo }) {
|
|
7
|
+
const pkgUrl = `https://github.com/${owner}/${repo}`;
|
|
8
|
+
const tmpFolder = path.join(os.tmpdir(), 'hereya', 'github', owner, repo);
|
|
5
9
|
try {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
path,
|
|
12
|
-
repo
|
|
13
|
-
});
|
|
14
|
-
if (response.status !== 200) {
|
|
10
|
+
const destPath = await downloadPackage(pkgUrl, tmpFolder);
|
|
11
|
+
if (await fs.stat(path.join(destPath, filePath))) {
|
|
12
|
+
const content = await fs.readFile(path.join(destPath, filePath), 'utf8');
|
|
13
|
+
// remove the tmp folder
|
|
14
|
+
await fs.rm(destPath, { recursive: true });
|
|
15
15
|
return {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
content,
|
|
17
|
+
found: true,
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
found: false,
|
|
22
|
+
reason: `File ${filePath} not found in ${pkgUrl}`,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
26
|
return {
|
|
27
27
|
found: false,
|
|
28
|
-
reason: error.message
|
|
28
|
+
reason: error.message,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -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
|
package/dist/lib/shell.d.ts
CHANGED
|
@@ -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) {
|