contensis-cli 1.0.0-beta.83 → 1.0.0-beta.85
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/dist/commands/dev.js +23 -2
- package/dist/commands/dev.js.map +2 -2
- package/dist/localisation/en-GB.js +52 -0
- package/dist/localisation/en-GB.js.map +2 -2
- package/dist/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.js +56 -0
- package/dist/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.js.map +7 -0
- package/dist/providers/file-provider.js +4 -2
- package/dist/providers/file-provider.js.map +2 -2
- package/dist/services/ContensisCliService.js +3 -53
- package/dist/services/ContensisCliService.js.map +2 -2
- package/dist/services/ContensisDevService.js +203 -0
- package/dist/services/ContensisDevService.js.map +7 -0
- package/dist/shell.js +2 -9
- package/dist/shell.js.map +2 -2
- package/dist/util/git.js +119 -0
- package/dist/util/git.js.map +7 -0
- package/dist/util/os.js +39 -0
- package/dist/util/os.js.map +7 -0
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +8 -2
- package/src/commands/dev.ts +29 -2
- package/src/localisation/en-GB.ts +85 -0
- package/src/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.ts +44 -0
- package/src/models/JsModules.d.ts +1 -0
- package/src/providers/file-provider.ts +5 -2
- package/src/services/ContensisCliService.ts +24 -78
- package/src/services/ContensisDevService.ts +243 -0
- package/src/shell.ts +3 -12
- package/src/util/git.ts +118 -0
- package/src/util/os.ts +7 -0
- package/src/version.ts +1 -1
|
@@ -4,7 +4,9 @@ import {
|
|
|
4
4
|
MigrateModelsResult,
|
|
5
5
|
MigrateStatus,
|
|
6
6
|
} from 'migratortron';
|
|
7
|
+
import { GitHelper } from '~/util/git';
|
|
7
8
|
import { Logger } from '~/util/logger';
|
|
9
|
+
import { winSlash } from '~/util/os';
|
|
8
10
|
|
|
9
11
|
export const LogMessages = {
|
|
10
12
|
app: {
|
|
@@ -411,4 +413,87 @@ export const LogMessages = {
|
|
|
411
413
|
id
|
|
412
414
|
)}`,
|
|
413
415
|
},
|
|
416
|
+
devinit: {
|
|
417
|
+
intro: () => `Contensis developer environment initialisation`,
|
|
418
|
+
//`This will initialise your local working directory to develop with the current connected Contensis project`,
|
|
419
|
+
projectDetails: (
|
|
420
|
+
name: string,
|
|
421
|
+
env: string,
|
|
422
|
+
projectId: string,
|
|
423
|
+
git: GitHelper
|
|
424
|
+
) =>
|
|
425
|
+
`Project: ${Logger.highlightText(name)} set arg --name to override
|
|
426
|
+
- Home: ${Logger.standardText(process.cwd())}
|
|
427
|
+
- Repository: ${git.home}
|
|
428
|
+
|
|
429
|
+
Connect to Contensis instance: ${Logger.standardText(env)}
|
|
430
|
+
- Project id: ${Logger.standardText(projectId)}`,
|
|
431
|
+
developmentKey: (name: string, existing: boolean) =>
|
|
432
|
+
` - ${
|
|
433
|
+
!existing ? 'Create development API key' : 'Development API key found'
|
|
434
|
+
}: ${Logger[!existing ? 'highlightText' : 'standardText'](name)}`,
|
|
435
|
+
deploymentKey: (name: string, existing: boolean) =>
|
|
436
|
+
` - ${
|
|
437
|
+
!existing ? 'Create deployment API key' : 'Deployment API key found'
|
|
438
|
+
}: ${Logger[!existing ? 'highlightText' : 'standardText'](name)}`,
|
|
439
|
+
ciIntro: (git: GitHelper) =>
|
|
440
|
+
`We will create API keys with permissions to use this project with Contensis, and add a job to your CI that will deploy a container build. We will ask you to add secrets/variables to your git repository to give your workflow permission to push a Block to Contensis.
|
|
441
|
+
|
|
442
|
+
You could visit ${git.secretsUri} to check that you can see repository settings`,
|
|
443
|
+
ciDetails: (filename: string) =>
|
|
444
|
+
`Add push-block job to CI file: ${Logger.highlightText(filename)}\n`,
|
|
445
|
+
confirm: () =>
|
|
446
|
+
`Confirm these details are correct so we can make changes to your project`,
|
|
447
|
+
accessTokenPrompt: () =>
|
|
448
|
+
`Please supply the access token for the Delivery API (optional)`,
|
|
449
|
+
createDevKey: (keyName: string, existing: boolean) =>
|
|
450
|
+
`${
|
|
451
|
+
!existing ? 'Created' : 'Checked permissions for'
|
|
452
|
+
} development API key ${Logger.standardText(keyName)}`,
|
|
453
|
+
createDeployKey: (keyName: string, existing: boolean) =>
|
|
454
|
+
`${
|
|
455
|
+
!existing ? 'Created' : 'Checked permissions for'
|
|
456
|
+
} deployment API key ${Logger.standardText(keyName)}`,
|
|
457
|
+
createKeyFail: (keyName: string, existing: boolean) =>
|
|
458
|
+
`Failed to ${
|
|
459
|
+
!existing ? 'create' : 'update'
|
|
460
|
+
} API key ${Logger.highlightText(keyName)}`,
|
|
461
|
+
writeEnvFile: () => `Written .env file to project home directory`,
|
|
462
|
+
useEnvFileTip: () =>
|
|
463
|
+
`You should alter existing project code that connects a Contensis client to use the variables from this file`,
|
|
464
|
+
writeCiFile: (ciFilePath: string) =>
|
|
465
|
+
`Updated CI file ${Logger.standardText(winSlash(ciFilePath))}`,
|
|
466
|
+
ciBlockTip: (blockId: string, env: string, projectId: string) =>
|
|
467
|
+
`A job is included to deploy your built container image to ${Logger.standardText(
|
|
468
|
+
projectId
|
|
469
|
+
)} at ${Logger.standardText(env)} in a block called ${Logger.standardText(
|
|
470
|
+
blockId
|
|
471
|
+
)}`,
|
|
472
|
+
addGitSecretsIntro: () =>
|
|
473
|
+
`We have ceated an API key that allows you to deploy your app image to a Contensis Block but we need you to add these details to your GitLab repository.`,
|
|
474
|
+
addGitSecretsHelp: (git: GitHelper, id: string, secret: string) =>
|
|
475
|
+
`Add secrets or variables in your repository's settings page\n\nGo to ${Logger.highlightText(
|
|
476
|
+
git.secretsUri
|
|
477
|
+
)}\n\n${
|
|
478
|
+
git.type === 'github'
|
|
479
|
+
? `Add a "New repository secret"`
|
|
480
|
+
: `Expand "Variables" and hit "Add variable"`
|
|
481
|
+
}\n\n ${
|
|
482
|
+
git.type === 'github' ? `Secret name:` : `Key:`
|
|
483
|
+
} ${Logger.highlightText(`CONTENSIS_CLIENT_ID`)}\n ${
|
|
484
|
+
git.type === 'github' ? `Secret:` : `Value:`
|
|
485
|
+
} ${Logger.highlightText(
|
|
486
|
+
id
|
|
487
|
+
)}\n\n ${`Add one more secret/variable to the repository`}\n\n ${
|
|
488
|
+
git.type === 'github' ? `Secret name:` : `Key:`
|
|
489
|
+
} ${Logger.highlightText(`CONTENSIS_SHARED_SECRET`)}\n ${
|
|
490
|
+
git.type === 'github' ? `Secret:` : `Value:`
|
|
491
|
+
} ${Logger.highlightText(secret)}`,
|
|
492
|
+
success: () => `Contensis developer environment initialisation complete`,
|
|
493
|
+
partialSuccess: () =>
|
|
494
|
+
`Contensis developer environment initialisation completed with errors`,
|
|
495
|
+
failed: () => `Contensis developer environment initialisation failed`,
|
|
496
|
+
startProjectTip: () =>
|
|
497
|
+
`Start up your project in the normal way for development`,
|
|
498
|
+
},
|
|
414
499
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import ContensisCli from '~/services/ContensisCliService';
|
|
2
|
+
|
|
3
|
+
interface ISiteConfigYaml {
|
|
4
|
+
alias: string;
|
|
5
|
+
projectId: string;
|
|
6
|
+
accessToken: string;
|
|
7
|
+
clientId: string;
|
|
8
|
+
sharedSecret: string;
|
|
9
|
+
blocks: {
|
|
10
|
+
id: string;
|
|
11
|
+
baseUri: string;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const mapSiteConfigYaml = async (cli: ContensisCli) => {
|
|
16
|
+
const credentials = await cli.GetCredentials(cli.env.lastUserId);
|
|
17
|
+
|
|
18
|
+
const blocks = [];
|
|
19
|
+
const blocksRaw = await cli.PrintBlocks();
|
|
20
|
+
|
|
21
|
+
for (const block of blocksRaw || []) {
|
|
22
|
+
const versions = await cli.PrintBlockVersions(
|
|
23
|
+
block.id,
|
|
24
|
+
'default',
|
|
25
|
+
'latest'
|
|
26
|
+
);
|
|
27
|
+
if (versions?.[0]) {
|
|
28
|
+
blocks.push({
|
|
29
|
+
id: versions[0].id,
|
|
30
|
+
baseUri: versions[0].previewUrl,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const siteConfig: ISiteConfigYaml = {
|
|
36
|
+
alias: cli.currentEnv,
|
|
37
|
+
projectId: cli.currentProject,
|
|
38
|
+
accessToken: '',
|
|
39
|
+
clientId: credentials?.current?.account || '',
|
|
40
|
+
sharedSecret: credentials?.current?.password || '',
|
|
41
|
+
blocks,
|
|
42
|
+
};
|
|
43
|
+
return siteConfig;
|
|
44
|
+
};
|
|
@@ -25,14 +25,17 @@ export const readFile = (filePath: string) => {
|
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
export const readFiles = (directory: string) => {
|
|
28
|
+
export const readFiles = (directory: string, createDirectory = true) => {
|
|
29
29
|
const directoryPath = localPath(directory);
|
|
30
30
|
if (fs.existsSync(directoryPath)) {
|
|
31
31
|
const files = fs.readdirSync(directoryPath);
|
|
32
32
|
return files;
|
|
33
|
-
} else {
|
|
33
|
+
} else if (createDirectory) {
|
|
34
34
|
fs.mkdirSync(directoryPath, { recursive: true });
|
|
35
35
|
return [];
|
|
36
|
+
} else {
|
|
37
|
+
throw new Error(`ENOENT: Directory does not exist ${directoryPath}`);
|
|
38
|
+
// return undefined;
|
|
36
39
|
}
|
|
37
40
|
};
|
|
38
41
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { execFile, spawn } from 'child_process';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import fetch from 'node-fetch';
|
|
@@ -24,7 +23,7 @@ import ContensisAuthService from './ContensisAuthService';
|
|
|
24
23
|
|
|
25
24
|
import { LogMessages } from '~/localisation/en-GB';
|
|
26
25
|
|
|
27
|
-
import {
|
|
26
|
+
import { readJsonFile } from '~/providers/file-provider';
|
|
28
27
|
import SessionCacheProvider from '../providers/SessionCacheProvider';
|
|
29
28
|
import CredentialProvider from '~/providers/CredentialProvider';
|
|
30
29
|
|
|
@@ -49,6 +48,7 @@ import { diffLogStrings } from '~/util/diff';
|
|
|
49
48
|
import { logError, Logger } from '~/util/logger';
|
|
50
49
|
import { promiseDelay } from '~/util/timers';
|
|
51
50
|
|
|
51
|
+
|
|
52
52
|
type OutputFormat = 'json' | 'csv' | 'xml';
|
|
53
53
|
|
|
54
54
|
type OutputOptions = {
|
|
@@ -73,6 +73,17 @@ interface IImportOptions {
|
|
|
73
73
|
sourceProjectId?: string;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
export type OutputOptionsConstructorArg = OutputOptions &
|
|
77
|
+
IConnectOptions &
|
|
78
|
+
IImportOptions;
|
|
79
|
+
|
|
80
|
+
export interface ContensisCliConstructor {
|
|
81
|
+
new (
|
|
82
|
+
args: string[],
|
|
83
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
84
|
+
contensisOpts?: Partial<MigrateRequest>
|
|
85
|
+
): ContensisCli;
|
|
86
|
+
}
|
|
76
87
|
let insecurePasswordWarningShown = false;
|
|
77
88
|
|
|
78
89
|
class ContensisCli {
|
|
@@ -143,7 +154,12 @@ class ContensisCli {
|
|
|
143
154
|
|
|
144
155
|
constructor(
|
|
145
156
|
args: string[],
|
|
146
|
-
outputOpts?:
|
|
157
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
158
|
+
contensisOpts?: Partial<MigrateRequest>
|
|
159
|
+
);
|
|
160
|
+
constructor(
|
|
161
|
+
args: string[],
|
|
162
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
147
163
|
contensisOpts: Partial<MigrateRequest> = {}
|
|
148
164
|
) {
|
|
149
165
|
// console.log('args: ', JSON.stringify(args, null, 2));
|
|
@@ -204,80 +220,6 @@ class ContensisCli {
|
|
|
204
220
|
}
|
|
205
221
|
}
|
|
206
222
|
|
|
207
|
-
ExecRequestHandler = async (blockIds: string[], overrideArgs?: string[]) => {
|
|
208
|
-
const { log } = this;
|
|
209
|
-
// const getPrefixOld = log.getPrefix;
|
|
210
|
-
const exeHome = path.join(appRootDir, 'reqhan');
|
|
211
|
-
const exe = 'Zengenti.Contensis.RequestHandler.LocalDevelopment';
|
|
212
|
-
const exePath = path.join(exeHome, exe);
|
|
213
|
-
const siteConfigPath = path.join(appRootDir, 'site_config.yaml');
|
|
214
|
-
|
|
215
|
-
const args = overrideArgs
|
|
216
|
-
? typeof overrideArgs?.[0] === 'string' &&
|
|
217
|
-
overrideArgs[0].includes(' ', 2)
|
|
218
|
-
? overrideArgs[0].split(' ')
|
|
219
|
-
: overrideArgs
|
|
220
|
-
: []; // args could be [ '-c .\\site_config.yaml' ] or [ '-c', '.\\site_config.yaml' ]
|
|
221
|
-
|
|
222
|
-
// Add required args
|
|
223
|
-
if (!args.find(a => a === '-c')) args.push('-c', siteConfigPath);
|
|
224
|
-
|
|
225
|
-
// const child = execFile(exePath, args);
|
|
226
|
-
|
|
227
|
-
const child = spawn(exePath, args, { stdio: 'inherit' });
|
|
228
|
-
|
|
229
|
-
log.raw('');
|
|
230
|
-
log.info(`Launching request handler...`);
|
|
231
|
-
if (overrideArgs?.length)
|
|
232
|
-
this.log.warning(
|
|
233
|
-
`Spawning process: ${JSON.stringify(child.spawnargs, null, 2)}`
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
let isRunning = false;
|
|
237
|
-
|
|
238
|
-
// Log child output through event listeners
|
|
239
|
-
child?.stdout?.on('data', data => {
|
|
240
|
-
isRunning = true;
|
|
241
|
-
log.raw(data);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
child?.stderr?.on('data', data => {
|
|
245
|
-
log.error(data);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
child.on('spawn', () => {
|
|
249
|
-
isRunning = true;
|
|
250
|
-
log.help(
|
|
251
|
-
`You may see a firewall popup requesting network access, it is safe to approve`
|
|
252
|
-
);
|
|
253
|
-
// log.getPrefix = () => Logger.infoText(`[rqh]`);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
child.on('exit', code => {
|
|
257
|
-
isRunning = false;
|
|
258
|
-
|
|
259
|
-
log[code === 0 ? 'success' : 'warning'](
|
|
260
|
-
`Request handler exited with code ${code}\n`
|
|
261
|
-
);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
child.on('error', error => {
|
|
265
|
-
isRunning = false;
|
|
266
|
-
log.error(`Could not launch request handler due to error \n${error}`);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
270
|
-
|
|
271
|
-
// keep the method running until we can return
|
|
272
|
-
while (true === true) {
|
|
273
|
-
if (!isRunning) {
|
|
274
|
-
// log.getPrefix = getPrefixOld; // restore logger state
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
|
|
281
223
|
PrintEnvironments = () => {
|
|
282
224
|
const { log, messages } = this;
|
|
283
225
|
const { currentEnvironment, environments = {} } = this.cache;
|
|
@@ -1913,6 +1855,8 @@ class ContensisCli {
|
|
|
1913
1855
|
);
|
|
1914
1856
|
}
|
|
1915
1857
|
});
|
|
1858
|
+
|
|
1859
|
+
return blocks;
|
|
1916
1860
|
}
|
|
1917
1861
|
|
|
1918
1862
|
if (err) {
|
|
@@ -1957,6 +1901,8 @@ class ContensisCli {
|
|
|
1957
1901
|
: undefined
|
|
1958
1902
|
);
|
|
1959
1903
|
});
|
|
1904
|
+
|
|
1905
|
+
return blocks;
|
|
1960
1906
|
}
|
|
1961
1907
|
|
|
1962
1908
|
if (err) {
|
|
@@ -2361,7 +2307,7 @@ class ContensisCli {
|
|
|
2361
2307
|
|
|
2362
2308
|
export const cliCommand = (
|
|
2363
2309
|
commandArgs: string[],
|
|
2364
|
-
outputOpts:
|
|
2310
|
+
outputOpts: OutputOptionsConstructorArg,
|
|
2365
2311
|
contensisOpts: Partial<MigrateRequest> = {}
|
|
2366
2312
|
) => {
|
|
2367
2313
|
return new ContensisCli(['', '', ...commandArgs], outputOpts, contensisOpts);
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { execFile, spawn } from 'child_process';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import { MigrateRequest } from 'migratortron';
|
|
6
|
+
import { stringify } from 'yaml';
|
|
7
|
+
|
|
8
|
+
import ContensisCli, {
|
|
9
|
+
OutputOptionsConstructorArg,
|
|
10
|
+
} from './ContensisCliService';
|
|
11
|
+
import { mapSiteConfigYaml } from '~/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml';
|
|
12
|
+
import { appRootDir, writeFile } from '~/providers/file-provider';
|
|
13
|
+
import { jsonFormatter } from '~/util/json.formatter';
|
|
14
|
+
import { GitHelper } from '~/util/git';
|
|
15
|
+
|
|
16
|
+
class ContensisDev extends ContensisCli {
|
|
17
|
+
constructor(
|
|
18
|
+
args: string[],
|
|
19
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
20
|
+
contensisOpts: Partial<MigrateRequest> = {}
|
|
21
|
+
) {
|
|
22
|
+
super(args, outputOpts, contensisOpts);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
DevelopmentInit = async (projectHome: string, opts: any) => {
|
|
26
|
+
const { currentEnv, currentProject, log, messages } = this;
|
|
27
|
+
const contensis = await this.ConnectContensis();
|
|
28
|
+
|
|
29
|
+
if (contensis) {
|
|
30
|
+
// Retrieve keys list for env
|
|
31
|
+
const [keysErr, apiKeys] = await contensis.apiKeys.GetKeys();
|
|
32
|
+
if (keysErr) {
|
|
33
|
+
log.error(messages.keys.noList(currentEnv));
|
|
34
|
+
log.error(jsonFormatter(keysErr));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const apiKeyExists = (findKey: string) =>
|
|
38
|
+
apiKeys?.find(
|
|
39
|
+
k => k.name.trim().toLowerCase() === findKey?.trim().toLowerCase()
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Retrieve git info
|
|
43
|
+
const git = new GitHelper(projectHome);
|
|
44
|
+
|
|
45
|
+
// Retrieve ci workflow info
|
|
46
|
+
const workflowFiles = git.workflows;
|
|
47
|
+
|
|
48
|
+
// Set variables for logging etc.
|
|
49
|
+
let ciFileName = git.ciFileName;
|
|
50
|
+
|
|
51
|
+
const devKey = `${git.name} development`;
|
|
52
|
+
const deployKey = `${git.name} deployment`;
|
|
53
|
+
const blockId = git.name;
|
|
54
|
+
|
|
55
|
+
// Start render console output
|
|
56
|
+
log.raw('');
|
|
57
|
+
log.success(messages.devinit.intro());
|
|
58
|
+
log.raw('');
|
|
59
|
+
log.raw(
|
|
60
|
+
log.infoText(
|
|
61
|
+
messages.devinit.projectDetails(
|
|
62
|
+
git.name,
|
|
63
|
+
currentEnv,
|
|
64
|
+
currentProject,
|
|
65
|
+
git
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
log.raw(
|
|
70
|
+
log.infoText(
|
|
71
|
+
messages.devinit.developmentKey(devKey, !!apiKeyExists(devKey))
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
log.raw(
|
|
75
|
+
log.infoText(
|
|
76
|
+
messages.devinit.deploymentKey(deployKey, !!apiKeyExists(deployKey))
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
log.raw('');
|
|
80
|
+
|
|
81
|
+
if (Array.isArray(workflowFiles) && workflowFiles.length > 1) {
|
|
82
|
+
// Choose GitHub workflow file (if multiple)
|
|
83
|
+
({ ciFileName } = await inquirer.prompt([
|
|
84
|
+
{
|
|
85
|
+
type: 'list',
|
|
86
|
+
message: `Multiple GitHub workflow files found\n${log.infoText(
|
|
87
|
+
`Tell us which GitHub workflow builds the container image after each push:`
|
|
88
|
+
)}`,
|
|
89
|
+
name: 'ciFileName',
|
|
90
|
+
choices: workflowFiles,
|
|
91
|
+
default: workflowFiles.find(f => f.includes('docker')),
|
|
92
|
+
},
|
|
93
|
+
]));
|
|
94
|
+
log.raw('');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
|
|
98
|
+
log.help(messages.devinit.ciIntro(git));
|
|
99
|
+
|
|
100
|
+
// Confirm prompt
|
|
101
|
+
const { confirm } = await inquirer.prompt([
|
|
102
|
+
{
|
|
103
|
+
type: 'confirm',
|
|
104
|
+
message: messages.devinit.confirm(),
|
|
105
|
+
name: 'confirm',
|
|
106
|
+
default: false,
|
|
107
|
+
},
|
|
108
|
+
]);
|
|
109
|
+
log.raw('');
|
|
110
|
+
if (!confirm) return;
|
|
111
|
+
|
|
112
|
+
// Access token prompt
|
|
113
|
+
const { accessToken } = await inquirer.prompt([
|
|
114
|
+
{
|
|
115
|
+
type: 'input',
|
|
116
|
+
message: messages.devinit.accessTokenPrompt(),
|
|
117
|
+
name: 'accessToken',
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
120
|
+
log.raw('');
|
|
121
|
+
|
|
122
|
+
// Magic happens...
|
|
123
|
+
|
|
124
|
+
// Arrange API keys for development and deployment
|
|
125
|
+
log.success(messages.devinit.createDevKey(devKey, false));
|
|
126
|
+
log.success(messages.devinit.createDeployKey(deployKey, true));
|
|
127
|
+
|
|
128
|
+
// Update or create a file called .env in project home
|
|
129
|
+
log.success(messages.devinit.writeEnvFile());
|
|
130
|
+
// log.help(messages.devinit.useEnvFileTip());
|
|
131
|
+
|
|
132
|
+
// Update CI file -- different for GH/GL -- create a sample one with build?
|
|
133
|
+
log.success(messages.devinit.writeCiFile(`./${ciFileName}`));
|
|
134
|
+
log.info(
|
|
135
|
+
messages.devinit.ciBlockTip(blockId, currentEnv, currentProject)
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Echo Deployment API key to console, ask user to add secrets to repo
|
|
139
|
+
log.warning(messages.devinit.addGitSecretsIntro());
|
|
140
|
+
log.help(
|
|
141
|
+
messages.devinit.addGitSecretsHelp(git, '123-456', '789-012-345')
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
log.success(messages.devinit.success());
|
|
145
|
+
log.help(messages.devinit.startProjectTip());
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
ExecRequestHandler = async (blockIds: string[], overrideArgs?: string[]) => {
|
|
150
|
+
// if no request handler exe
|
|
151
|
+
// download it.
|
|
152
|
+
|
|
153
|
+
// if update arg, redownload it
|
|
154
|
+
|
|
155
|
+
const { log } = this;
|
|
156
|
+
// const getPrefixOld = log.getPrefix;
|
|
157
|
+
const exeHome = path.join(appRootDir, 'reqhan');
|
|
158
|
+
const exe = 'Zengenti.Contensis.RequestHandler.LocalDevelopment';
|
|
159
|
+
const exePath = path.join(exeHome, exe);
|
|
160
|
+
const siteConfigPath = path.join(appRootDir, 'site_config.yaml');
|
|
161
|
+
|
|
162
|
+
const siteConfig = await mapSiteConfigYaml(this);
|
|
163
|
+
writeFile('site_config.yaml', stringify(siteConfig));
|
|
164
|
+
|
|
165
|
+
const args = overrideArgs
|
|
166
|
+
? typeof overrideArgs?.[0] === 'string' &&
|
|
167
|
+
overrideArgs[0].includes(' ', 2)
|
|
168
|
+
? overrideArgs[0].split(' ')
|
|
169
|
+
: overrideArgs
|
|
170
|
+
: []; // args could be [ '-c .\\site_config.yaml' ] or [ '-c', '.\\site_config.yaml' ]
|
|
171
|
+
|
|
172
|
+
// Add required args
|
|
173
|
+
if (!args.find(a => a === '-c')) args.push('-c', siteConfigPath);
|
|
174
|
+
|
|
175
|
+
// const child = execFile(exePath, args);
|
|
176
|
+
|
|
177
|
+
const child = spawn(exePath, args, { stdio: 'inherit' });
|
|
178
|
+
|
|
179
|
+
// log.raw('');
|
|
180
|
+
log.info(`Launching request handler...`);
|
|
181
|
+
if (overrideArgs?.length)
|
|
182
|
+
this.log.warning(
|
|
183
|
+
`Spawning process with supplied args: ${JSON.stringify(
|
|
184
|
+
child.spawnargs,
|
|
185
|
+
null,
|
|
186
|
+
2
|
|
187
|
+
)}`
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
let isRunning = false;
|
|
191
|
+
|
|
192
|
+
// Log child output through event listeners
|
|
193
|
+
child?.stdout?.on('data', data => {
|
|
194
|
+
isRunning = true;
|
|
195
|
+
log.raw(data);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
child?.stderr?.on('data', data => {
|
|
199
|
+
log.error(data);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
child.on('spawn', () => {
|
|
203
|
+
isRunning = true;
|
|
204
|
+
log.help(
|
|
205
|
+
`You may see a firewall popup requesting network access, it is safe to approve`
|
|
206
|
+
);
|
|
207
|
+
// log.getPrefix = () => Logger.infoText(`[rqh]`);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
child.on('exit', code => {
|
|
211
|
+
isRunning = false;
|
|
212
|
+
|
|
213
|
+
log[code === 0 ? 'success' : 'warning'](
|
|
214
|
+
`Request handler exited with code ${code}\n`
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
child.on('error', error => {
|
|
219
|
+
isRunning = false;
|
|
220
|
+
log.error(`Could not launch request handler due to error \n${error}`);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
224
|
+
|
|
225
|
+
// keep the method running until we can return
|
|
226
|
+
while (true === true) {
|
|
227
|
+
if (!isRunning) {
|
|
228
|
+
// log.getPrefix = getPrefixOld; // restore logger state
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
export const devCommand = (
|
|
236
|
+
commandArgs: string[],
|
|
237
|
+
outputOpts: OutputOptionsConstructorArg,
|
|
238
|
+
contensisOpts: Partial<MigrateRequest> = {}
|
|
239
|
+
) => {
|
|
240
|
+
return new ContensisDev(['', '', ...commandArgs], outputOpts, contensisOpts);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export default ContensisDev;
|
package/src/shell.ts
CHANGED
|
@@ -259,16 +259,7 @@ export const shell = () => {
|
|
|
259
259
|
// after successful connect / login / set project
|
|
260
260
|
if (typeof process.argv?.[2] !== 'undefined')
|
|
261
261
|
return {
|
|
262
|
-
quit
|
|
263
|
-
process.removeAllListeners('exit');
|
|
264
|
-
|
|
265
|
-
if (error) {
|
|
266
|
-
Logger.error(error.message);
|
|
267
|
-
process.exit(1);
|
|
268
|
-
} else {
|
|
269
|
-
process.exit(0);
|
|
270
|
-
}
|
|
271
|
-
},
|
|
262
|
+
quit: ContensisCli.quit,
|
|
272
263
|
restart() {},
|
|
273
264
|
} as any;
|
|
274
265
|
if (!globalShell) globalShell = new ContensisShell();
|
|
@@ -282,9 +273,9 @@ process.on('uncaughtException', function (err) {
|
|
|
282
273
|
|
|
283
274
|
process.on('SIGINT', () => {
|
|
284
275
|
Logger.warning('received SIGINT');
|
|
276
|
+
shell().quit();
|
|
285
277
|
// setTimeout(() => {
|
|
286
|
-
//
|
|
287
|
-
// }, 1000);
|
|
278
|
+
// }, 2000);
|
|
288
279
|
});
|
|
289
280
|
|
|
290
281
|
process.on('SIGTERM', () => {
|