@travetto/cli 3.0.0-rc.7 → 3.0.0-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,8 +27,6 @@ Options:
27
27
  Commands:
28
28
  echo [options] [args...]
29
29
  help [command] display help for command
30
-
31
- 
32
30
  ```
33
31
 
34
32
  This will show all the available options/choices that are exposed given the currently installed modules.
@@ -50,7 +48,7 @@ export class CliEchoCommand extends CliCommand {
50
48
  name = 'echo';
51
49
 
52
50
  getOptions() {
53
- return { uppercase: this.boolOption({ desc: 'Upper case', def: false }) };
51
+ return { uppercase: this.boolOption({ desc: 'Upper case' }) };
54
52
  }
55
53
 
56
54
  getArgs() {
@@ -75,10 +73,8 @@ $ trv echo --help
75
73
  Usage: echo [options] [args...]
76
74
 
77
75
  Options:
78
- -u, --uppercase Upper case (default: false)
76
+ -u, --uppercase Upper case
79
77
  -h, --help display help for command
80
-
81
- 
82
78
  ```
83
79
 
84
80
  And actually using it:
@@ -88,5 +84,4 @@ And actually using it:
88
84
  $ trv echo -u bOb rOb DRoP
89
85
 
90
86
  [ 'BOB', 'ROB', 'DROP' ]
91
- 
92
87
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/cli",
3
- "version": "3.0.0-rc.7",
3
+ "version": "3.0.0-rc.9",
4
4
  "description": "CLI infrastructure for travetto framework",
5
5
  "keywords": [
6
6
  "cli",
@@ -26,10 +26,10 @@
26
26
  "directory": "module/cli"
27
27
  },
28
28
  "dependencies": {
29
- "@travetto/base": "^3.0.0-rc.7",
30
- "@travetto/terminal": "^3.0.0-rc.4",
31
- "@travetto/worker": "^3.0.0-rc.7",
32
- "commander": "^9.5.0"
29
+ "@travetto/base": "^3.0.0-rc.8",
30
+ "@travetto/terminal": "^3.0.0-rc.6",
31
+ "@travetto/worker": "^3.0.0-rc.8",
32
+ "commander": "^10.0.0"
33
33
  },
34
34
  "travetto": {
35
35
  "displayName": "Command Line Interface"
@@ -24,8 +24,8 @@ export class CliCommandManager {
24
24
  */
25
25
  static getCommandMapping(): Map<string, string> {
26
26
  const all = new Map<string, string>();
27
- for (const { output } of RootIndex.findSupport({ filter: /\/cli[.]/, checkProfile: false })) {
28
- all.set(output.replace(/^.*\/cli[.](.*?)[.][^.]+$/, (_, f) => f), output);
27
+ for (const { outputFile: output, import: imp } of RootIndex.findSupport({ filter: /\/cli[.]/, checkProfile: false })) {
28
+ all.set(output.replace(/^.*\/cli[.](.*?)[.][^.]+$/, (_, f) => f), imp);
29
29
  }
30
30
  return all;
31
31
  }
package/src/command.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { appendFile, mkdir } from 'fs/promises';
2
- import type * as commander from 'commander';
2
+ import type commander from 'commander';
3
3
 
4
4
  import { path } from '@travetto/manifest';
5
5
  import { ConsoleManager, DataUtil, defineGlobalEnv, GlobalEnvConfig, ShutdownManager } from '@travetto/base';
@@ -74,7 +74,7 @@ export abstract class CliCommand<V extends OptionMap = OptionMap> {
74
74
  /**
75
75
  * Get args
76
76
  */
77
- getArgs?(): string;
77
+ getArgs?(): string | undefined;
78
78
  /**
79
79
  * Initialization code for adding options
80
80
  */
@@ -135,8 +135,8 @@ export abstract class CliCommand<V extends OptionMap = OptionMap> {
135
135
  boolOption(cfg: OptionConfig<boolean>): OptionConfig<boolean> {
136
136
  return {
137
137
  type: Boolean,
138
- // TODO: This needs to be resolved?
139
- combine: (val, curr): boolean => DataUtil.coerceType(val, Boolean, false) ?? true,
138
+ combine: (val, curr): boolean =>
139
+ (val !== undefined ? DataUtil.coerceType(val, Boolean, false) : undefined) ?? curr,
140
140
  completion: true,
141
141
  ...cfg
142
142
  };
@@ -217,18 +217,23 @@ export abstract class CliCommand<V extends OptionMap = OptionMap> {
217
217
  if (this.init) {
218
218
  cmd = await this.init?.(cmd);
219
219
  }
220
- if (this.getArgs) {
221
- cmd = cmd.arguments(this.getArgs?.());
220
+ const args = this.getArgs?.();
221
+ if (args) {
222
+ cmd = cmd.arguments(args);
222
223
  }
223
224
  for (const cfg of await this.finalizeOptions()) {
224
- let key = `${cfg.short ? `-${cfg.short}, ` : ''}--${cfg.name}`;
225
- if (cfg.type !== Boolean || cfg.def) {
226
- key = `${key} <${cfg.name}>`;
227
- }
228
- cmd = cfg.combine ?
225
+ const pre = cfg.short ? `-${cfg.short}, ` : '';
226
+ if (cfg.type === Boolean) {
227
+ if (cfg.def) {
228
+ cmd.option(`${pre}--no-${cfg.name}`, `Disables: ${cfg.desc}`);
229
+ } else {
230
+ cmd.option(`${pre}--${cfg.name}`, cfg.desc);
231
+ }
232
+ } else {
233
+ const key = `${pre}--${cfg.name} <${cfg.name}>`;
229
234
  // @ts-expect-error
230
- cmd.option(key, cfg.desc, cfg.combine, cfg.def) :
231
- cmd.option(key, cfg.desc, (cur, acc) => cur, cfg.def);
235
+ cmd = cmd.option(key, cfg.desc, cfg.combine ?? ((cur, acc): unknown => cur), cfg.def);
236
+ }
232
237
  }
233
238
 
234
239
  cmd = cmd.action(this.runAction.bind(this));
package/src/execute.ts CHANGED
@@ -1,8 +1,9 @@
1
+ import fs from 'fs/promises';
1
2
  import { program as commander } from 'commander';
2
3
 
3
- import { RootIndex, PackageUtil, path } from '@travetto/manifest';
4
+ import { PackageUtil, path, RootIndex } from '@travetto/manifest';
4
5
  import { GlobalTerminal } from '@travetto/terminal';
5
- import { runMain } from '@travetto/base/support/init.main';
6
+ import { ShutdownManager } from '@travetto/base';
6
7
 
7
8
  import { CliCommandManager } from './command-manager';
8
9
  import { HelpUtil } from './help';
@@ -15,9 +16,7 @@ export class ExecutionManager {
15
16
  /**
16
17
  * Run command
17
18
  */
18
- static async runCommand(args: string[]): Promise<void> {
19
- const cmd = args[2];
20
-
19
+ static async runCommand(cmd: string, args: string[]): Promise<void> {
21
20
  let command;
22
21
 
23
22
  try {
@@ -32,7 +31,7 @@ export class ExecutionManager {
32
31
  if (args.includes('-h') || args.includes('--help')) {
33
32
  return command.showHelp();
34
33
  } else {
35
- await commander.parseAsync(args);
34
+ await commander.parseAsync([process.argv[0], process.argv[1], cmd, ...args]);
36
35
  }
37
36
  } catch (err) {
38
37
  if (!(err instanceof Error)) {
@@ -44,27 +43,47 @@ export class ExecutionManager {
44
43
  }
45
44
  }
46
45
 
46
+ /**
47
+ * Run file expecting a main method
48
+ */
49
+ static async runMain(file: string, args: string[]): Promise<void> {
50
+ try {
51
+ // If referenced file exists
52
+ if (await (fs.stat(path.resolve(file)).then(() => true, () => false))) {
53
+ file = path.join(RootIndex.manifest.mainModule, file);
54
+ }
55
+
56
+ const imp = RootIndex.getFromImport(file)?.import;
57
+ if (!imp) {
58
+ throw new Error(`Unknown file: ${file}`);
59
+ }
60
+
61
+ const mod = await import(imp);
62
+ await ShutdownManager.exitWithResponse(await mod.main(...args));
63
+ } catch (err) {
64
+ await ShutdownManager.exitWithResponse(err, true);
65
+ }
66
+ }
67
+
47
68
  /**
48
69
  * Execute the command line
49
70
  * @param args
50
71
  */
51
- static async run(args: string[]): Promise<void> {
72
+ static async run(argv: string[]): Promise<void> {
73
+ const { init } = await import('@travetto/base/support/init.js');
74
+ await init();
75
+
52
76
  const width = GlobalTerminal.width;
53
77
  commander
54
78
  .version(PackageUtil.getFrameworkVersion())
55
79
  .configureOutput({ getOutHelpWidth: () => width, getErrHelpWidth: () => width });
56
80
 
57
- const cmd = args[2];
58
-
81
+ const [, , cmd, ...args] = argv;
59
82
  if (cmd === 'main') {
60
- let mainFile = RootIndex.resolveFileImport(process.argv[3])!;
61
- if (!mainFile.startsWith('/')) {
62
- mainFile = path.join(RootIndex.manifest.mainModule, mainFile);
63
- mainFile = RootIndex.resolveFileImport(mainFile);
64
- }
65
- await runMain((await import(mainFile)).main, process.argv.slice(4));
83
+ const [file, ...rest] = args;
84
+ await this.runMain(file, rest);
66
85
  } else if (cmd && !cmd.startsWith('-')) {
67
- await this.runCommand(args);
86
+ await this.runCommand(cmd, args);
68
87
  } else {
69
88
  // Load all commands
70
89
  await CliCommandManager.loadAllCommands(x => x.setup(commander));
package/src/help.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type * as commander from 'commander';
1
+ import type commander from 'commander';
2
2
 
3
3
  import { cliTpl } from './color';
4
4
 
5
5
  const TYPE_PATTERN = /(\[[^\]]+\])/g;
6
+ const REQ_TYPE_PATTERN = /(<[^>]+>)/g;
6
7
  const TITLE_PATTERN = /^(\S[^:]+:)/gim;
7
8
 
8
9
  const OPTIONS_PATTERN = new RegExp([
@@ -32,7 +33,7 @@ const COMMANDS_PATTERN = new RegExp([
32
33
  '(?<space>[ ]+)',
33
34
  '(?<name>\\S+)',
34
35
  '(?<optionsSpace>[ ]+)?',
35
- '(?<options>\\[.*\\])?',
36
+ '(?<options>(?:\\[|<).*(?:\\]|>))?',
36
37
  '((?<descriptionSpace>[ ]+)(?<description>[a-z][^\\n\\[]+))?',
37
38
  '(?:[ ]+)?',
38
39
  '$',
@@ -50,7 +51,7 @@ const USAGE_PATTERN = new RegExp([
50
51
  '(?<space>[ ]+)?',
51
52
  '(?<name>[^\\[ ]+)?',
52
53
  '(?<nameSpace>[ ]+)?',
53
- '(?<options>\\[.*\\])?',
54
+ '(?<options>(?:\\[|<).*(?:\\]|>))?',
54
55
  '(?:[ ]+)?',
55
56
  '$',
56
57
  ].join(''), 'gim');
@@ -135,7 +136,7 @@ export class HelpUtil {
135
136
  space,
136
137
  cliTpl`${{ param: name }}`,
137
138
  optionsSpace,
138
- options?.replace(TYPE_PATTERN, input => cliTpl`${{ input }}`),
139
+ options?.replace(TYPE_PATTERN, input => cliTpl`${{ input }}`).replace(REQ_TYPE_PATTERN, type => cliTpl`${{ type }}`),
139
140
  descriptionSpace,
140
141
  cliTpl`${{ description }}`
141
142
  ]
package/src/module.ts CHANGED
@@ -38,13 +38,13 @@ export class CliModuleUtil {
38
38
  stdoutTerm: Terminal,
39
39
  stderrTerm: Terminal
40
40
  ): ExecutionOptions {
41
- const folder = mod.workspaceRelative;
41
+ const folder = mod.sourceFolder;
42
42
  const opts: ExecutionOptions = {
43
43
  stdio: ['ignore', 'pipe', 'pipe', 'ignore'],
44
44
  outputMode: 'text',
45
45
  catchAsResult: true,
46
46
  cwd: folder,
47
- env: { TRV_MANIFEST: '' },
47
+ env: { TRV_MANIFEST: '', TRV_MODULE: mod.name },
48
48
  };
49
49
 
50
50
  if (config.showStdout) {
@@ -62,7 +62,7 @@ export class CliModuleUtil {
62
62
  * @returns
63
63
  */
64
64
  static #buildPrefixes(mods: IndexedModule[]): Record<string, string> {
65
- const folders = mods.map(x => x.workspaceRelative);
65
+ const folders = mods.map(x => x.sourceFolder);
66
66
  const maxWidth = Math.max(...folders.map(x => x.length));
67
67
  return Object.fromEntries(folders.map((x, i) => [x, colorize(x.padStart(maxWidth, ' ').padEnd(maxWidth + 1), i)]));
68
68
  }
@@ -102,14 +102,14 @@ export class CliModuleUtil {
102
102
  return (mode === 'changed' ?
103
103
  await this.findChangedModulesRecursive() :
104
104
  [...RootIndex.getModuleList('all')].map(x => RootIndex.getModule(x)!)
105
- ).filter(x => x.source !== RootIndex.manifest.workspacePath);
105
+ ).filter(x => x.sourcePath !== RootIndex.manifest.workspacePath);
106
106
  }
107
107
 
108
108
  /**
109
109
  * Synchronize all workspace modules to have the correct versions from the current packages
110
110
  */
111
111
  static async synchronizeModuleVersions(): Promise<void> {
112
- await PackageUtil.syncVersions((await this.findModules('all')).map(x => x.source));
112
+ await PackageUtil.syncVersions((await this.findModules('all')).map(x => x.sourcePath));
113
113
  }
114
114
 
115
115
  /**
@@ -30,7 +30,7 @@ export class RepoExecCommand extends CliCommand<Options> {
30
30
  }
31
31
 
32
32
  getArgs(): string {
33
- return '[command] [...args]';
33
+ return '<command> [...args]';
34
34
  }
35
35
 
36
36
  envInit(): GlobalEnvConfig {
@@ -43,7 +43,7 @@ export class RepoExecCommand extends CliCommand<Options> {
43
43
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
44
44
  (mod, opts) => ExecUtil.spawn(this.args[0], this.args.slice(1), opts),
45
45
  {
46
- progressMessage: mod => `Running '${this.args.join(' ')}' [%idx/%total] ${mod?.workspaceRelative ?? ''}`,
46
+ progressMessage: mod => `Running '${this.args.join(' ')}' [%idx/%total] ${mod?.sourceFolder ?? ''}`,
47
47
  showStdout: this.cmd.showStdout,
48
48
  prefixOutput: this.cmd.prefixOutput,
49
49
  workerCount: this.cmd.workers,
@@ -29,7 +29,7 @@ export class RepoListCommand extends CliCommand<Options> {
29
29
  async action(...args: unknown[]): Promise<void> {
30
30
  const mods = await CliModuleUtil.findModules(this.cmd.changed ? 'changed' : 'all');
31
31
  if (!this.cmd.graph) {
32
- for (const mod of mods.map(x => x.workspaceRelative).sort()) {
32
+ for (const mod of mods.map(x => x.sourceFolder).sort()) {
33
33
  console.log!(mod);
34
34
  }
35
35
  } else {
package/support/cli.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { ExecutionManager } from '@travetto/cli';
2
+
3
+ ExecutionManager.run(process.argv);
@@ -1,8 +0,0 @@
1
- import { ExecutionManager } from '@travetto/cli';
2
-
3
- /**
4
- * Entry point
5
- */
6
- export async function main(): Promise<void> {
7
- return ExecutionManager.run(process.argv); // Run cli
8
- }