@corva/create-app 0.43.0-2 → 0.43.0-4

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.
@@ -1,17 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawnSync } = require('child_process');
3
+ const { sync: spawnSync } = require('cross-spawn');
4
4
  const { resolve } = require('path');
5
5
 
6
- const cmd = [
7
- 'node',
6
+ const cmd = 'node';
7
+ const originalCwd = process.cwd()
8
+
9
+ process.chdir(__dirname)
10
+
11
+ const preparedOriginalArgs = process.argv.slice(2)
12
+ // after changing the cwd need to pass the original path
13
+ .concat(['--original-cwd', originalCwd])
14
+ // leave spaces in place for arguments
15
+ .map(a => a.includes(" ") ? `"${a}"` : a);
16
+
17
+ const args = [
8
18
  '--no-warnings',
9
19
  '--experimental-json-modules',
10
- resolve(__dirname, 'cca.js'),
11
- ...process.argv.slice(2),
12
- ];
20
+ 'cca.js',
21
+ ].concat(preparedOriginalArgs);
13
22
 
14
- const { signal, status, error } = spawnSync(cmd.map((a) => `"${a}"`).join(' '), { stdio: 'inherit', shell: true });
23
+ const { signal, status, error } = spawnSync(cmd, args, {
24
+ stdio: 'inherit',
25
+ shell: true,
26
+ });
15
27
 
16
28
  if (signal) {
17
29
  process.exit(signal);
@@ -37,6 +37,8 @@ export const silentOption = new Option(
37
37
  'Only log result of the operation'
38
38
  ).default(false);
39
39
 
40
+ export const originalCwdOption = (new Option('--original-cwd <string>')).hideHelp();
41
+
40
42
  export const bumpVersionOptionDeprecated = new Option(
41
43
  flags,
42
44
  chalk.bgYellow`DEPRECATED` +
@@ -2,7 +2,7 @@ import { APP_TYPES } from '../constants/cli.js';
2
2
  import Debug from 'debug';
3
3
 
4
4
  const debug = Debug('cca:resolve-app-runtime');
5
- import { spawn } from 'child_process';
5
+ import spawn from 'cross-spawn';
6
6
  import { promises as fs } from 'fs';
7
7
  import semver from 'semver';
8
8
  import os from 'os';
@@ -11,22 +11,22 @@ const checkCliVersion = async (command, version, stdErr = false) =>
11
11
  new Promise((resolve, reject) => {
12
12
  const child = spawn(command, ['--version']);
13
13
 
14
- let data;
14
+ let data = '';
15
15
 
16
- child.stderr.once('data', (buffer) => {
17
- data = buffer;
16
+ child.stderr.on('data', (buffer) => {
17
+ data += buffer;
18
18
  });
19
19
 
20
- child.stdout.once('data', (buffer) => {
21
- data = buffer;
20
+ child.stdout.on('data', (buffer) => {
21
+ data += buffer;
22
22
  });
23
23
 
24
24
  child.once('close', (code) => {
25
25
  if (code !== 0) {
26
26
  debug(`Command ${command} exited with code ${code}`);
27
- debug(data.toString());
27
+ debug('Output:', data.toString());
28
28
 
29
- return reject(false);
29
+ return resolve(false);
30
30
  }
31
31
 
32
32
  debug(`%s version output: %s`, command, data.toString());
@@ -50,6 +50,8 @@ const checkNodeVersion = (version) => async () => {
50
50
  }
51
51
  };
52
52
 
53
+ export const IS_WINDOWS = process.platform === 'win32';
54
+
53
55
  export const resolveAppRuntime = (opts) => {
54
56
  if (opts.appType === APP_TYPES.UI) {
55
57
  const version = '16';
@@ -78,7 +80,7 @@ export const resolveAppRuntime = (opts) => {
78
80
  return {
79
81
  language: 'python',
80
82
  isRuntimeAvailable: async () =>
81
- (await checkCliVersion('python3', version)) || (await checkCliVersion('python', version)),
83
+ IS_WINDOWS ? await checkCliVersion('python', version) || await checkCliVersion('python3', version) : checkCliVersion('python3', version),
82
84
  packageManager: 'pip',
83
85
  version,
84
86
  };
@@ -1,5 +1,8 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { logger } from './logger.js';
3
+ import Debug from 'debug';
4
+
5
+ const debug = Debug('cca:versioning');
3
6
 
4
7
  export function isInGitRepository(appPath) {
5
8
  try {
@@ -9,6 +12,7 @@ export function isInGitRepository(appPath) {
9
12
  });
10
13
  return true;
11
14
  } catch (e) {
15
+ debug(e);
12
16
  return false;
13
17
  }
14
18
  }
@@ -16,6 +20,8 @@ export function isInGitRepository(appPath) {
16
20
  export function tryGitInit(appPath) {
17
21
  try {
18
22
  if (isInGitRepository()) {
23
+ debug('is in git repository');
24
+
19
25
  return false;
20
26
  }
21
27
  execSync('git --version', { stdio: 'ignore', cwd: appPath });
@@ -24,7 +30,8 @@ export function tryGitInit(appPath) {
24
30
  logger.log('Initialized git repo in app');
25
31
  return true;
26
32
  } catch (e) {
27
- console.warn('Git repo not initialized', e);
33
+ debug(e);
34
+ console.warn('Git repo not initialized');
28
35
  return false;
29
36
  }
30
37
  }
@@ -44,12 +51,14 @@ export function tryGitCommit(appPath) {
44
51
  // In the future, we might supply our own committer
45
52
  // like Ember CLI does, but for now, let's just
46
53
  // remove the Git files to avoid a half-done state.
47
- console.warn('Git commit not created', e);
54
+ debug(e);
55
+ console.warn('Git commit not created');
48
56
  console.warn('Removing .git directory...');
49
57
  try {
50
58
  // unlinkSync() doesn't work on directories.
51
59
  fs.removeSync(path.join(appPath, '.git'));
52
60
  } catch (removeErr) {
61
+ debug(removeErr);
53
62
  // Ignore.
54
63
  }
55
64
  return false;
@@ -61,6 +70,7 @@ export function shouldUseYarn(appPath) {
61
70
  execSync('yarnpkg --version', { stdio: 'ignore', cwd: appPath });
62
71
  return true;
63
72
  } catch (e) {
73
+ debug(e);
64
74
  return false;
65
75
  }
66
76
  }
package/lib/main.js CHANGED
@@ -4,7 +4,7 @@ import { Command, CommanderError, Option } from 'commander';
4
4
  import fs from 'fs-extra';
5
5
  import inquirer from 'inquirer';
6
6
  import os from 'node:os';
7
- import path from 'node:path';
7
+ import path, { resolve } from 'node:path';
8
8
  import semver from 'semver';
9
9
 
10
10
  import { ensureLatestVersion, warnIfOutdated, ensureBumpVersion } from './scripts/utils/version.js';
@@ -31,9 +31,10 @@ import {
31
31
  envOption,
32
32
  silentOption,
33
33
  appVersion,
34
+ originalCwdOption,
34
35
  } from './bump-version.option.js';
35
36
  import { Manifest } from './flows/lib/manifest.js';
36
- import { resolveAppRuntime } from './helpers/resolve-app-runtime.js';
37
+ import { IS_WINDOWS, resolveAppRuntime } from './helpers/resolve-app-runtime.js';
37
38
  import { existsSync } from 'node:fs';
38
39
  import { fileURLToPath } from 'node:url';
39
40
  import { logger } from './helpers/logger.js';
@@ -57,6 +58,8 @@ const silencer =
57
58
  }
58
59
  };
59
60
 
61
+ const getRealWorkingDir = (relativePath, options) => resolve(options.originalCwd, relativePath)
62
+
60
63
  function startingMessage() {
61
64
  clear();
62
65
  console.log(chalk.green(' Welcome to apps generator for:'));
@@ -105,7 +108,7 @@ const printDeprecationNotice = (param) =>
105
108
  );
106
109
 
107
110
  export async function run() {
108
- const program = new Command()
111
+ const program = new Command('create-corva-app')
109
112
  .hook('preAction', async () => {
110
113
  checkNodeVersion();
111
114
 
@@ -117,7 +120,8 @@ export async function run() {
117
120
  const createCommand = program
118
121
  .command('create', { isDefault: true })
119
122
  .description('Create a new app')
120
- .argument('[project-directory]', 'project directory to work with', process.cwd())
123
+ .argument('[project-directory]', 'project directory to work with', process.argv[process.argv.length - 1])
124
+ .addOption(originalCwdOption)
121
125
  .usage(`${chalk.green('<project-directory>')} [options]`);
122
126
 
123
127
  manifestConstants.manifestOptions().forEach((value) => {
@@ -170,12 +174,15 @@ export async function run() {
170
174
  .argument('[patterns...]', 'Additional patterns to zip', [])
171
175
  .addOption(bumpVersionOption)
172
176
  .addOption(new Option('--ignored-files [ignoredFiles...]', 'Patterns to skip zip', []))
177
+ .addOption(originalCwdOption)
173
178
  .addOption(silentOption)
174
179
  .action(
175
180
  silencer(async (dirName, patterns, options) => {
176
181
  options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
177
182
 
178
- return runFlow(ZIP_FLOW, { dirName, patterns, options }).then(_.get('zipFileName'));
183
+ console.log(getRealWorkingDir(dirName, options), options)
184
+
185
+ return runFlow(ZIP_FLOW, { dirName: getRealWorkingDir(dirName, options), patterns, options }).then(_.get('zipFileName'));
179
186
  })
180
187
  );
181
188
 
@@ -189,6 +196,7 @@ export async function run() {
189
196
  .addOption(silentOption)
190
197
  .addOption(envOption)
191
198
  .addOption(apiKeyOption)
199
+ .addOption(originalCwdOption)
192
200
  .addOption(new Option('--notes [string]', 'Add custom notes to published app'))
193
201
  .addOption(
194
202
  new Option('--label [string]', 'Put a label on the release').choices(['BETA', 'PROD'])
@@ -209,7 +217,7 @@ export async function run() {
209
217
  .action(async (dirName, patterns, options) => {
210
218
  options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
211
219
 
212
- await runFlow(RELEASE_FLOW, { dirName, patterns, options });
220
+ await runFlow(RELEASE_FLOW, { dirName: getRealWorkingDir(dirName, options), patterns, options });
213
221
  });
214
222
 
215
223
  program
@@ -222,8 +230,9 @@ export async function run() {
222
230
  .addOption(appVersion)
223
231
  .addOption(new Option('--assets [assets...]', 'Assets ids list', []))
224
232
  .addOption(new Option('--interval [number]', 'Interval for scheduler apps (exp. 1200)'))
233
+ .addOption(originalCwdOption)
225
234
  .action(async (dirName, options) => {
226
- await runFlow(RERUN_FLOW, { dirName, options });
235
+ await runFlow(RERUN_FLOW, { dirName: getRealWorkingDir(dirName, options), options });
227
236
  });
228
237
 
229
238
  program
@@ -234,8 +243,9 @@ export async function run() {
234
243
  .addOption(envOption)
235
244
  .addOption(silentOption)
236
245
  .addOption(appVersion)
246
+ .addOption(originalCwdOption)
237
247
  .action(async (dirName, options) => {
238
- await runFlow(ATTACH_FLOW, { dirName, options });
248
+ await runFlow(ATTACH_FLOW, { dirName: getRealWorkingDir(dirName, options), options });
239
249
  });
240
250
 
241
251
  try {
@@ -302,19 +312,43 @@ const handleCommanderError = (e) => {
302
312
  }
303
313
  };
304
314
 
315
+ /**
316
+ *
317
+ * @param {import('./flows/lib/manifest').Manifest} manifest
318
+ */
319
+ const getEnvManagementLink = (manifest) => {
320
+ if (manifest.isJs()) {
321
+ if (IS_WINDOWS) {
322
+ return 'https://github.com/coreybutler/nvm-windows';
323
+ }
324
+
325
+ return 'https://github.com/nvm-sh/nvm';
326
+ }
327
+
328
+ if (IS_WINDOWS) {
329
+ return 'https://github.com/pyenv-win/pyenv-win';
330
+ }
331
+
332
+ return 'https://github.com/pyenv/pyenv';
333
+ };
334
+
305
335
  async function initPackage(projectName, opts) {
306
336
  const manifest = new Manifest(manifestHelpers.fillManifest(opts));
307
337
  const runtime = resolveAppRuntime(opts);
308
338
 
309
339
  if (!(await runtime.isRuntimeAvailable())) {
310
- throw new Error(`Runtime "${opts.runtime}" is not available locally`);
340
+ throw new Error(
341
+ `Runtime "${opts.runtime}" is not available locally. Please proceed to ${chalk.green(
342
+ getEnvManagementLink(manifest)
343
+ )} to install it locally.`
344
+ );
311
345
  }
312
346
 
313
347
  if (manifest.isUi()) {
314
348
  await ensureLatestVersion();
315
349
  }
316
350
 
317
- const root = path.resolve(projectName);
351
+ const root = getRealWorkingDir(projectName, opts);
318
352
 
319
353
  logger.log(`Creating a new Corva app in ${chalk.green(root)}.`);
320
354
 
@@ -500,38 +534,44 @@ function addPackageJSON(root, manifest, runtime) {
500
534
  */
501
535
  async function installApp(root, manifest, runtime) {
502
536
  const command = manifest.isJs() ? runtime.packageManager : 'make';
503
- const args = ['install'];
504
- const opts = { stdio: ['inherit', 'inherit', 'pipe'], cwd: root };
505
537
 
506
- if (process.env.CI && command === 'yarn') {
507
- args.push('--cache-folder=".yarn-cache"');
508
- }
538
+ if (!IS_WINDOWS || manifest.isJs()) {
539
+ const args = ['install'];
540
+ const opts = { stdio: ['inherit', 'inherit', 'pipe'], cwd: root };
509
541
 
510
- logger.log(chalk.yellow(`Installing template dependencies using ${runtime.packageManager}...`));
511
- const proc =
512
- manifest.isJs() && existsSync(`${os.homedir()}/.nvm/nvm.sh`)
513
- ? spawn.sync(`\\. ${os.homedir()}/.nvm/nvm.sh && nvm i && ${command} ${args.join(' ')}`, {
514
- shell: true,
515
- ...opts,
516
- })
517
- : spawn.sync(command, args, opts);
518
-
519
- if (proc.stderr) {
520
- const error = proc.stderr
521
- .toString('utf8')
522
- .split('\n')
523
- // NOTE: filter out warnings caused by @corva/ui peer dependencies
524
- .filter((line) => !line.includes('@corva/ui'))
525
- .join('\n');
526
- console.log(error);
527
- }
542
+ if (process.env.CI && command === 'yarn') {
543
+ args.push('--cache-folder=".yarn-cache"');
544
+ }
528
545
 
529
- if (proc.status !== 0) {
530
- console.error(`\`${command} ${args.join(' ')}\` failed`);
531
- return;
532
- }
546
+ logger.log(chalk.yellow(`Installing template dependencies using ${runtime.packageManager}...`));
547
+ const proc =
548
+ manifest.isJs() && existsSync(`${os.homedir()}/.nvm/nvm.sh`)
549
+ ? spawn.sync(`\\. ${os.homedir()}/.nvm/nvm.sh && nvm i && ${command} ${args.join(' ')}`, {
550
+ shell: true,
551
+ ...opts,
552
+ })
553
+ : spawn.sync(command, args, opts);
554
+
555
+ if (proc.stderr) {
556
+ const error = proc.stderr
557
+ .toString('utf8')
558
+ .split('\n')
559
+ // NOTE: filter out warnings caused by @corva/ui peer dependencies
560
+ .filter((line) => !line.includes('@corva/ui'))
561
+ .join('\n');
562
+ console.log(error);
563
+ }
564
+
565
+ if (proc.status !== 0) {
566
+ console.error(`\`${command} ${args.join(' ')}\` failed`);
567
+ return;
568
+ }
533
569
 
534
- logger.log(chalk.green('Successfull project install'));
570
+ logger.log(chalk.green('Successfull project install'));
571
+ } else {
572
+ logger.log();
573
+ logger.log(`⚠️ ${chalk.yellow('Please install project dependencies manually')}`);
574
+ }
535
575
 
536
576
  if (versioning.tryGitInit(root)) {
537
577
  logger.log();
@@ -544,7 +584,7 @@ async function installApp(root, manifest, runtime) {
544
584
  }
545
585
 
546
586
  logger.log();
547
- logger.log(`Success! Created ${manifest.name} at ${root}`);
587
+ logger.log(`Success! Created ${chalk.green(manifest.name)} at ${chalk.yellow(root)}`);
548
588
 
549
589
  helpCommands(manifest, runtime);
550
590
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corva/create-app",
3
- "version": "0.43.0-2",
3
+ "version": "0.43.0-4",
4
4
  "private": false,
5
5
  "description": "Create an app to use it in CORVA.AI",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "archiver": "^5.3.0",
38
38
  "chalk": "4.1.0",
39
39
  "commander": "^9.1.0",
40
- "cross-spawn": "7.0.3",
40
+ "cross-spawn": "^7.0.3",
41
41
  "debug": "^4.3.4",
42
42
  "dotenv": "^16.0.0",
43
43
  "figlet": "^1.5.0",
@@ -55,6 +55,7 @@
55
55
  "devDependencies": {
56
56
  "@corva/eslint-config-browser": "^0.0.4",
57
57
  "@corva/eslint-config-node": "^4.2.0",
58
+ "@types/cross-spawn": "^6.0.2",
58
59
  "conventional-changelog-cli": "^2.1.0",
59
60
  "prettier": "^2.4.1",
60
61
  "standard-version": "^9.0.0"