@travetto/cli 8.0.0-alpha.27 → 8.0.0-alpha.29
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 +20 -26
- package/__index__.ts +10 -9
- package/bin/trv.js +2 -1
- package/package.json +3 -3
- package/src/color.ts +1 -1
- package/src/execute.ts +2 -3
- package/src/help.ts +25 -27
- package/src/module.ts +9 -10
- package/src/parse.ts +54 -38
- package/src/registry/decorator.ts +36 -26
- package/src/registry/registry-adapter.ts +13 -11
- package/src/registry/registry-index.ts +24 -24
- package/src/schema-export.ts +24 -15
- package/src/schema.ts +15 -10
- package/src/scm.ts +19 -10
- package/src/service.ts +34 -33
- package/src/types.ts +5 -5
- package/src/util.ts +16 -18
- package/support/cli.cli_schema.ts +4 -6
- package/support/cli.main.ts +8 -7
- package/support/cli.service.ts +18 -15
- package/support/entry.trv.ts +2 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @travetto/cli
|
|
|
13
13
|
yarn add @travetto/cli
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The cli module represents the primary entry point for execution within the framework. One of the main goals for this module is extensibility, as adding new entry points is meant to be trivial. The framework leverages this module for exposing all executable tools and entry points.
|
|
16
|
+
The cli module represents the primary entry point for execution within the framework. One of the main goals for this module is extensibility, as adding new entry points is meant to be trivial. The framework leverages this module for exposing all executable tools and entry points. To see a high level listing of all supported commands, invoke `trv --help`
|
|
17
17
|
|
|
18
18
|
**Terminal: General Usage**
|
|
19
19
|
```bash
|
|
@@ -28,10 +28,11 @@ Commands:
|
|
|
28
28
|
email:compile Compile all email templates into generated runtime artifacts.
|
|
29
29
|
email:editor Start the email template editor service for interactive preview and testing.
|
|
30
30
|
email:test Render and send a template file to a target recipient for quick validation.
|
|
31
|
-
eslint Run ESLint for the workspace or changed files.
|
|
32
|
-
eslint:register Generate the workspace ESLint configuration entry file.
|
|
33
31
|
firestore:indexes Generate the Firestore composite indexes JSON for all registered models.
|
|
32
|
+
lint Run Biome linter/formatter for the workspace or changed files.
|
|
33
|
+
lint:register Generate the workspace Biome configuration entry file.
|
|
34
34
|
llm:support:execute Execute llm-support operations with dry-run by default.
|
|
35
|
+
llm:support:inline Inline and compile reference snippets for llm-support packaging.
|
|
35
36
|
llm:support:mcp Minimal MCP stdio server for llm-support tools.
|
|
36
37
|
llm:support:plan Build plan-first execution details for llm-support operations.
|
|
37
38
|
llm:support:recommend Recommend llm-support bundles, workflows, and operations.
|
|
@@ -59,7 +60,7 @@ Commands:
|
|
|
59
60
|
|
|
60
61
|
This listing is from the [Travetto](https://travetto.dev) monorepo, and represents the majority of tools that can be invoked from the command line.
|
|
61
62
|
|
|
62
|
-
This module also has a tight integration with the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin), allowing the editing experience to benefit from the commands defined. The most commonly used commands will be the ones packaged with the framework, but its also very easy to create new commands.
|
|
63
|
+
This module also has a tight integration with the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin), allowing the editing experience to benefit from the commands defined. The most commonly used commands will be the ones packaged with the framework, but its also very easy to create new commands. With the correct configuration, these commands will also be exposed within VSCode.
|
|
63
64
|
|
|
64
65
|
At it's heart, a cli command is the contract defined by what flags, and what arguments the command supports. Within the framework this requires three criteria to be met:
|
|
65
66
|
* The file must be located in the `support/` folder, and have a name that matches `cli.*.ts`
|
|
@@ -89,7 +90,7 @@ Options:
|
|
|
89
90
|
```
|
|
90
91
|
|
|
91
92
|
## Command Naming
|
|
92
|
-
The file name `support/cli.<name>.ts` has a direct mapping to the cli command name.
|
|
93
|
+
The file name `support/cli.<name>.ts` has a direct mapping to the cli command name. This hard mapping allows for the framework to be able to know which file to invoke without needing to load all command-related files.
|
|
93
94
|
|
|
94
95
|
Examples of mappings:
|
|
95
96
|
* `cli.test.ts` maps to `test`
|
|
@@ -107,7 +108,6 @@ import { CliCommand } from '@travetto/cli';
|
|
|
107
108
|
|
|
108
109
|
@CliCommand()
|
|
109
110
|
export class BasicCommand {
|
|
110
|
-
|
|
111
111
|
loud?: boolean;
|
|
112
112
|
|
|
113
113
|
main() {
|
|
@@ -127,7 +127,7 @@ Options:
|
|
|
127
127
|
--help display help for command
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
As you can see the command now has the support of a basic boolean flag to determine if the response should be loud or not.
|
|
130
|
+
As you can see the command now has the support of a basic boolean flag to determine if the response should be loud or not. The default value here is undefined/false, and so is an opt-in experience.
|
|
131
131
|
|
|
132
132
|
**Terminal: Basic Command with Loud Flag**
|
|
133
133
|
```bash
|
|
@@ -138,14 +138,14 @@ HELLO
|
|
|
138
138
|
|
|
139
139
|
The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) supports the following data types for flags:
|
|
140
140
|
* Boolean values
|
|
141
|
-
* Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#
|
|
142
|
-
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#
|
|
143
|
-
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#
|
|
141
|
+
* Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L202), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L211), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L193), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130) decorators help provide additional validation.
|
|
142
|
+
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L108) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L78) provide additional constraints
|
|
143
|
+
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130) decorators help provide additional validation.
|
|
144
144
|
* String lists. Same as String, but allowing multiple values.
|
|
145
145
|
* Numeric lists. Same as Number, but allowing multiple values.
|
|
146
146
|
|
|
147
147
|
## Binding Arguments
|
|
148
|
-
The `main()` method is the entrypoint for the command, represents a series of parameters. Some will be required, some may be optional.
|
|
148
|
+
The `main()` method is the entrypoint for the command, represents a series of parameters. Some will be required, some may be optional. The arguments support all types supported by the flags, and decorators can be provided using the decorators inline on parameters. Optional arguments in the method, will be optional at run time, and filled with the provided default values.
|
|
149
149
|
|
|
150
150
|
**Code: Basic Command with Arg**
|
|
151
151
|
```typescript
|
|
@@ -154,7 +154,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
154
154
|
|
|
155
155
|
@CliCommand()
|
|
156
156
|
export class BasicCommand {
|
|
157
|
-
|
|
158
157
|
main(@Min(1) @Max(10) volume: number = 1) {
|
|
159
158
|
console.log(volume > 7 ? 'HELLO' : 'Hello');
|
|
160
159
|
}
|
|
@@ -207,7 +206,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
207
206
|
|
|
208
207
|
@CliCommand()
|
|
209
208
|
export class BasicCommand {
|
|
210
|
-
|
|
211
209
|
reverse?: boolean;
|
|
212
210
|
|
|
213
211
|
main(@Min(1) @Max(10) volumes: number[]) {
|
|
@@ -256,7 +254,7 @@ $ trv basic:arg-list -r 10 5 3 9 8 1
|
|
|
256
254
|
```
|
|
257
255
|
|
|
258
256
|
## Customization
|
|
259
|
-
By default, all fields are treated as flags and all parameters of `main()` are treated as arguments within the validation process.
|
|
257
|
+
By default, all fields are treated as flags and all parameters of `main()` are treated as arguments within the validation process. Like the standard [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L19) behavior, we can leverage the metadata of the fields/parameters to help provide additional customization/context for the users of the commands.
|
|
260
258
|
|
|
261
259
|
**Code: Custom Command with Metadata**
|
|
262
260
|
```typescript
|
|
@@ -268,7 +266,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
268
266
|
*/
|
|
269
267
|
@CliCommand()
|
|
270
268
|
export class CustomCommand {
|
|
271
|
-
|
|
272
269
|
/**
|
|
273
270
|
* The message to send back to the user
|
|
274
271
|
* @alias -m
|
|
@@ -323,7 +320,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
323
320
|
*/
|
|
324
321
|
@CliCommand()
|
|
325
322
|
export class CustomCommand {
|
|
326
|
-
|
|
327
323
|
/**
|
|
328
324
|
* The message to send back to the user
|
|
329
325
|
* @alias env.MESSAGE
|
|
@@ -372,7 +368,7 @@ CuStOm
|
|
|
372
368
|
```
|
|
373
369
|
|
|
374
370
|
## Flag File Support
|
|
375
|
-
Sometimes its also convenient, especially with commands that support a variety of flags, to provide easy access to pre-defined sets of flags.
|
|
371
|
+
Sometimes its also convenient, especially with commands that support a variety of flags, to provide easy access to pre-defined sets of flags. Flag files represent a snapshot of command line arguments and flags, as defined in a file. When referenced, these inputs are essentially injected into the command line as if the user had typed them manually.
|
|
376
372
|
|
|
377
373
|
**Code: Example Flag File**
|
|
378
374
|
```bash
|
|
@@ -401,7 +397,7 @@ npx trv call:db --host localhost --port 3306 --username app --password <custom>
|
|
|
401
397
|
```
|
|
402
398
|
|
|
403
399
|
## VSCode Integration
|
|
404
|
-
By default, cli commands do not expose themselves to the VSCode extension, as the majority of them are not intended for that sort of operation.
|
|
400
|
+
By default, cli commands do not expose themselves to the VSCode extension, as the majority of them are not intended for that sort of operation. [Web API](https://github.com/travetto/travetto/tree/main/module/web#readme "Declarative support for creating Web Applications") does expose a cli target `web:http` that will show up, to help run/debug a web application. Any command can mark itself as being a run target, and will be eligible for running from within the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin). This is achieved by setting the `runTarget` field on the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) decorator. This means the target will be visible within the editor tooling.
|
|
405
401
|
|
|
406
402
|
**Code: Simple Run Target**
|
|
407
403
|
```typescript
|
|
@@ -412,7 +408,6 @@ import { CliCommand } from '@travetto/cli';
|
|
|
412
408
|
*/
|
|
413
409
|
@CliCommand({ runTarget: true })
|
|
414
410
|
export class RunCommand {
|
|
415
|
-
|
|
416
411
|
main(name: string) {
|
|
417
412
|
console.log(name);
|
|
418
413
|
}
|
|
@@ -444,11 +439,11 @@ If the goal is to run a more complex application, which may include depending on
|
|
|
444
439
|
|
|
445
440
|
**Code: Simple Run Target**
|
|
446
441
|
```typescript
|
|
447
|
-
import {
|
|
442
|
+
import { CliCommand, type CliCommandShape, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag } from '@travetto/cli';
|
|
448
443
|
import { DependencyRegistryIndex } from '@travetto/di';
|
|
449
|
-
import { CliCommand, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag, type CliCommandShape } from '@travetto/cli';
|
|
450
|
-
import { NetUtil } from '@travetto/web';
|
|
451
444
|
import { Registry } from '@travetto/registry';
|
|
445
|
+
import { Runtime, toConcrete } from '@travetto/runtime';
|
|
446
|
+
import { NetUtil } from '@travetto/web';
|
|
452
447
|
|
|
453
448
|
import type { WebHttpServer } from '../src/types.ts';
|
|
454
449
|
|
|
@@ -464,7 +459,6 @@ import type { WebHttpServer } from '../src/types.ts';
|
|
|
464
459
|
*/
|
|
465
460
|
@CliCommand()
|
|
466
461
|
export class WebHttpCommand implements CliCommandShape {
|
|
467
|
-
|
|
468
462
|
/** Port to run on */
|
|
469
463
|
port?: number;
|
|
470
464
|
|
|
@@ -511,7 +505,7 @@ export class WebHttpCommand implements CliCommandShape {
|
|
|
511
505
|
|
|
512
506
|
As noted in the example above, `fields` is specified in this execution, with support for `module`, and `env`. These env flag is directly tied to the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime/src/context.ts#L13) `name` defined in the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Runtime for travetto applications.") module.
|
|
513
507
|
|
|
514
|
-
The `module` field is slightly more complex, but is geared towards supporting commands within a monorepo context.
|
|
508
|
+
The `module` field is slightly more complex, but is geared towards supporting commands within a monorepo context. This flag ensures that a module is specified if running from the root of the monorepo, and that the module provided is real, and can run the desired command. When running from an explicit module folder in the monorepo, the module flag is ignored.
|
|
515
509
|
|
|
516
510
|
### Custom Validation
|
|
517
511
|
In addition to dependency injection, the command contract also allows for a custom validation function, which will have access to bound command (flags, and args) as well as the unknown arguments. When a command implements this method, any [ValidationError](https://github.com/travetto/travetto/tree/main/module/schema/src/validate/types.ts#L10) errors that are returned will be shared with the user, and fail to invoke the `main` method.
|
|
@@ -558,7 +552,7 @@ A simple example of the validation can be found in the `doc` command:
|
|
|
558
552
|
|
|
559
553
|
**Code: Simple Validation Example**
|
|
560
554
|
```typescript
|
|
561
|
-
@Validator(async
|
|
555
|
+
@Validator(async cmd => {
|
|
562
556
|
const docFile = path.resolve(cmd.input);
|
|
563
557
|
if (!(await fs.stat(docFile, { throwIfNoEntry: false }))) {
|
|
564
558
|
return { message: `input: ${cmd.input} does not exist`, path: 'input', source: 'flag', kind: 'invalid' };
|
|
@@ -567,7 +561,7 @@ A simple example of the validation can be found in the `doc` command:
|
|
|
567
561
|
```
|
|
568
562
|
|
|
569
563
|
## CLI - service
|
|
570
|
-
The module provides the ability to start/stop/restart services as [docker](https://www.docker.com/community-edition) containers.
|
|
564
|
+
The module provides the ability to start/stop/restart services as [docker](https://www.docker.com/community-edition) containers. This is meant to be used for development purposes, to minimize the effort of getting an application up and running. Services can be targeted individually or handled as a group.
|
|
571
565
|
|
|
572
566
|
**Terminal: Help for service**
|
|
573
567
|
```bash
|
package/__index__.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {} from './src/trv.d.ts';
|
|
2
|
+
|
|
3
|
+
export * from './src/color.ts';
|
|
3
4
|
export * from './src/execute.ts';
|
|
4
|
-
export * from './src/schema.ts';
|
|
5
|
-
export * from './src/schema-export.ts';
|
|
6
|
-
export * from './src/registry/decorator.ts';
|
|
7
|
-
export * from './src/registry/registry-index.ts';
|
|
8
|
-
export * from './src/registry/registry-adapter.ts';
|
|
9
5
|
export * from './src/help.ts';
|
|
10
|
-
export * from './src/color.ts';
|
|
11
6
|
export * from './src/module.ts';
|
|
12
|
-
export * from './src/scm.ts';
|
|
13
7
|
export * from './src/parse.ts';
|
|
8
|
+
export * from './src/registry/decorator.ts';
|
|
9
|
+
export * from './src/registry/registry-adapter.ts';
|
|
10
|
+
export * from './src/registry/registry-index.ts';
|
|
11
|
+
export * from './src/schema.ts';
|
|
12
|
+
export * from './src/schema-export.ts';
|
|
13
|
+
export * from './src/scm.ts';
|
|
14
14
|
export * from './src/service.ts';
|
|
15
|
+
export * from './src/types.ts';
|
|
15
16
|
export * from './src/util.ts';
|
package/bin/trv.js
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
// @ts-check
|
|
3
3
|
import '@travetto/runtime/support/patch.js';
|
|
4
4
|
import '@travetto/compiler/bin/hook.js';
|
|
5
|
+
|
|
5
6
|
const { invoke } = await import('@travetto/compiler/support/invoke.ts');
|
|
6
|
-
await invoke('exec', '@travetto/cli/support/entry.trv.ts', ...process.argv.slice(2));
|
|
7
|
+
await invoke('exec', '@travetto/cli/support/entry.trv.ts', ...process.argv.slice(2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/cli",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI infrastructure for Travetto framework",
|
|
6
6
|
"keywords": [
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"directory": "module/cli"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
33
|
-
"@travetto/terminal": "^8.0.0-alpha.
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.23",
|
|
33
|
+
"@travetto/terminal": "^8.0.0-alpha.21"
|
|
34
34
|
},
|
|
35
35
|
"travetto": {
|
|
36
36
|
"displayName": "Command Line Interface",
|
package/src/color.ts
CHANGED
package/src/execute.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { ConsoleManager, getClass, Runtime, ShutdownManager, Util } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
import { HelpUtil } from './help.ts';
|
|
4
|
+
import { CliParseUtil } from './parse.ts';
|
|
4
5
|
import { CliCommandRegistryIndex } from './registry/registry-index.ts';
|
|
5
6
|
import { CliCommandSchemaUtil } from './schema.ts';
|
|
6
|
-
import { CliParseUtil } from './parse.ts';
|
|
7
7
|
import type { CliCommandShape } from './types.ts';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Execution manager
|
|
11
11
|
*/
|
|
12
12
|
export class ExecutionManager {
|
|
13
|
-
|
|
14
13
|
/** Command Execution */
|
|
15
14
|
static async execute(instance: CliCommandShape, args: unknown[]): Promise<void> {
|
|
16
15
|
const config = CliCommandRegistryIndex.get(getClass(instance));
|
|
@@ -74,4 +73,4 @@ export class ExecutionManager {
|
|
|
74
73
|
await ShutdownManager.shutdown();
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
}
|
|
76
|
+
}
|
package/src/help.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CodecUtil, castKey, getClass, JSONUtil, Runtime } from '@travetto/runtime';
|
|
4
4
|
import { SchemaRegistryIndex, ValidationResultError } from '@travetto/schema';
|
|
5
5
|
|
|
6
6
|
import { cliTpl } from './color.ts';
|
|
7
|
-
import { HELP_FLAG, type CliCommandShape } from './types.ts';
|
|
8
7
|
import { CliCommandRegistryIndex, UNKNOWN_COMMAND } from './registry/registry-index.ts';
|
|
9
8
|
import { CliSchemaExportUtil } from './schema-export.ts';
|
|
9
|
+
import { type CliCommandShape, HELP_FLAG } from './types.ts';
|
|
10
10
|
|
|
11
11
|
const validationSourceMap: Record<string, string> = { arg: 'Argument', flag: 'Flag' };
|
|
12
12
|
|
|
13
13
|
const ifDefined = <T>(value: T | null | '' | undefined): T | undefined =>
|
|
14
|
-
|
|
14
|
+
value === null || value === '' || value === undefined ? undefined : value;
|
|
15
15
|
|
|
16
16
|
const MODULE_TO_COMMAND = {
|
|
17
17
|
'@travetto/doc': ['doc'],
|
|
18
18
|
'@travetto/email-compiler': ['email:compile', 'email:test', 'email:editor'],
|
|
19
|
-
'@travetto/
|
|
19
|
+
'@travetto/lint': ['lint', 'lint:register'],
|
|
20
20
|
'@travetto/model': ['model:install', 'model:export'],
|
|
21
21
|
'@travetto/openapi': ['openapi:spec', 'openapi:client'],
|
|
22
22
|
'@travetto/pack': ['pack', 'pack:zip', 'pack:docker'],
|
|
23
23
|
'@travetto/repo': ['repo:publish', 'repo:version', 'repo:exec', 'repo:list'],
|
|
24
24
|
'@travetto/test': ['test', 'test:watch', 'test:direct'],
|
|
25
25
|
'@travetto/web-http': ['web:http'],
|
|
26
|
-
'@travetto/web-rpc': ['web:rpc-client']
|
|
26
|
+
'@travetto/web-rpc': ['web:rpc-client']
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const COMMAND_TO_MODULE = Object.fromEntries(Object.entries(MODULE_TO_COMMAND).flatMap(([k, v]) => v.map(sv => [sv, k])));
|
|
@@ -32,7 +32,6 @@ const COMMAND_TO_MODULE = Object.fromEntries(Object.entries(MODULE_TO_COMMAND).f
|
|
|
32
32
|
* Utilities for showing help
|
|
33
33
|
*/
|
|
34
34
|
export class HelpUtil {
|
|
35
|
-
|
|
36
35
|
/** Get usage help for a command */
|
|
37
36
|
static getUsageMessage(command: CliCommandShape): string[] {
|
|
38
37
|
const schema = SchemaRegistryIndex.getConfig(getClass(command));
|
|
@@ -40,13 +39,14 @@ export class HelpUtil {
|
|
|
40
39
|
|
|
41
40
|
const usage: string[] = [];
|
|
42
41
|
|
|
43
|
-
usage.push(
|
|
44
|
-
cliTpl`${{ title: 'Usage:' }} ${{ param: commandName }} ${{ input: '[options]' }}`
|
|
45
|
-
);
|
|
42
|
+
usage.push(cliTpl`${{ title: 'Usage:' }} ${{ param: commandName }} ${{ input: '[options]' }}`);
|
|
46
43
|
|
|
47
44
|
// Ensure finalized
|
|
48
45
|
for (const field of schema.methods.main?.parameters ?? []) {
|
|
49
|
-
const type =
|
|
46
|
+
const type =
|
|
47
|
+
field.type === String && field.enum && field.enum?.values.length <= 7
|
|
48
|
+
? field.enum?.values?.join('|')
|
|
49
|
+
: field.type.name.toLowerCase();
|
|
50
50
|
const arg = `${field.name}${field.array ? '...' : ''}:${type}`;
|
|
51
51
|
usage.push(cliTpl`${{ input: field.required?.active !== false ? `<${arg}>` : `[${arg}]` }}`);
|
|
52
52
|
}
|
|
@@ -76,9 +76,7 @@ export class HelpUtil {
|
|
|
76
76
|
const defaultValue = ifDefined(command[key]) ?? ifDefined(field.default);
|
|
77
77
|
const aliases = (field.aliases ?? [])
|
|
78
78
|
.filter(flag => flag.startsWith('-'))
|
|
79
|
-
.filter(flag =>
|
|
80
|
-
(field.type !== Boolean) || (defaultValue !== true ? !flag.startsWith('--no-') : flag.startsWith('--'))
|
|
81
|
-
);
|
|
79
|
+
.filter(flag => field.type !== Boolean || (defaultValue !== true ? !flag.startsWith('--no-') : flag.startsWith('--')));
|
|
82
80
|
let type: string | undefined;
|
|
83
81
|
|
|
84
82
|
if (field.type === String && field.enum && field.enum.values.length <= 3) {
|
|
@@ -87,10 +85,7 @@ export class HelpUtil {
|
|
|
87
85
|
({ type } = CliSchemaExportUtil.baseInputType(field));
|
|
88
86
|
}
|
|
89
87
|
|
|
90
|
-
const parameter = [
|
|
91
|
-
cliTpl`${{ param: aliases.join(', ') }}`,
|
|
92
|
-
...(type ? [cliTpl`${{ type: `<${type}>` }}`] : []),
|
|
93
|
-
];
|
|
88
|
+
const parameter = [cliTpl`${{ param: aliases.join(', ') }}`, ...(type ? [cliTpl`${{ type: `<${type}>` }}`] : [])];
|
|
94
89
|
|
|
95
90
|
params.push(parameter.join(' '));
|
|
96
91
|
const parts = [cliTpl`${{ title: field.description }}`];
|
|
@@ -104,7 +99,6 @@ export class HelpUtil {
|
|
|
104
99
|
params.push(cliTpl`${{ param: HELP_FLAG }}`);
|
|
105
100
|
descriptions.push('display help for command');
|
|
106
101
|
|
|
107
|
-
|
|
108
102
|
const paramWidths = params.map(item => util.stripVTControlCharacters(item).length);
|
|
109
103
|
const descWidths = descriptions.map(item => util.stripVTControlCharacters(item).length);
|
|
110
104
|
|
|
@@ -113,8 +107,9 @@ export class HelpUtil {
|
|
|
113
107
|
|
|
114
108
|
const options: string[] = [
|
|
115
109
|
cliTpl`${{ title: 'Options:' }}`,
|
|
116
|
-
...params.map(
|
|
117
|
-
|
|
110
|
+
...params.map(
|
|
111
|
+
(_, i) =>
|
|
112
|
+
` ${params[i]}${' '.repeat(paramWidth - paramWidths[i])} ${descriptions[i].padEnd(descWidth)}${' '.repeat(descWidth - descWidths[i])}`
|
|
118
113
|
),
|
|
119
114
|
''
|
|
120
115
|
];
|
|
@@ -139,9 +134,10 @@ export class HelpUtil {
|
|
|
139
134
|
for (const example of schema.examples) {
|
|
140
135
|
for (const line of example.split('\n')) {
|
|
141
136
|
examples.push(
|
|
142
|
-
line.trim().startsWith('>')
|
|
143
|
-
cliTpl` ${{ input: line.substring(line.indexOf('> ') + 2).trim() }}`
|
|
144
|
-
cliTpl` ${{ subtitle: line.trim() }}`
|
|
137
|
+
line.trim().startsWith('>')
|
|
138
|
+
? cliTpl` ${{ input: line.substring(line.indexOf('> ') + 2).trim() }}`
|
|
139
|
+
: cliTpl` ${{ subtitle: line.trim() }}`
|
|
140
|
+
);
|
|
145
141
|
}
|
|
146
142
|
}
|
|
147
143
|
examples.push('');
|
|
@@ -171,9 +167,11 @@ ${{ identifier: Runtime.getInstallCommand(module) }}
|
|
|
171
167
|
...this.getUsageMessage(command),
|
|
172
168
|
...this.getDescriptionMessage(command),
|
|
173
169
|
...this.getOptionsMessage(command),
|
|
174
|
-
...await this.getExtendedHelpMessage(command),
|
|
170
|
+
...(await this.getExtendedHelpMessage(command)),
|
|
175
171
|
...this.getExamplesMessage(command)
|
|
176
|
-
]
|
|
172
|
+
]
|
|
173
|
+
.map(line => line.trimEnd())
|
|
174
|
+
.join('\n');
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
/**
|
|
@@ -221,7 +219,7 @@ ${{ identifier: Runtime.getInstallCommand(module) }}
|
|
|
221
219
|
}
|
|
222
220
|
return cliTpl` * ${{ failure: error.message }}`;
|
|
223
221
|
}),
|
|
224
|
-
''
|
|
222
|
+
''
|
|
225
223
|
].join('\n');
|
|
226
224
|
}
|
|
227
225
|
|
|
@@ -240,4 +238,4 @@ ${{ identifier: Runtime.getInstallCommand(module) }}
|
|
|
240
238
|
}
|
|
241
239
|
console.error!();
|
|
242
240
|
}
|
|
243
|
-
}
|
|
241
|
+
}
|
package/src/module.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
2
1
|
import type { IndexedModule } from '@travetto/manifest';
|
|
2
|
+
import { Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
3
3
|
|
|
4
4
|
import { CliScmUtil } from './scm.ts';
|
|
5
5
|
|
|
6
|
-
type ModuleGraphEntry = { children: Set<string
|
|
6
|
+
type ModuleGraphEntry = { children: Set<string>; name: string; active: Set<string>; parents?: string[] };
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Simple utilities for understanding modules for CLI use cases
|
|
10
10
|
*/
|
|
11
11
|
export class CliModuleUtil {
|
|
12
|
-
|
|
13
12
|
/**
|
|
14
13
|
* Find modules that changed, and the dependent modules
|
|
15
14
|
* @param fromHash
|
|
@@ -34,8 +33,7 @@ export class CliModuleUtil {
|
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
return [...out.values()]
|
|
38
|
-
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
36
|
+
return [...out.values()].toSorted((a, b) => a.name.localeCompare(b.name));
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
/**
|
|
@@ -45,9 +43,10 @@ export class CliModuleUtil {
|
|
|
45
43
|
* @returns
|
|
46
44
|
*/
|
|
47
45
|
static async findModules(mode: 'all' | 'changed' | 'workspace', fromHash?: string, toHash?: string): Promise<IndexedModule[]> {
|
|
48
|
-
return (
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
return (
|
|
47
|
+
mode === 'changed'
|
|
48
|
+
? await this.findChangedModulesRecursive(fromHash, toHash, true)
|
|
49
|
+
: [...RuntimeIndex.getModuleList(mode)].map(name => RuntimeIndex.getModule(name)!)
|
|
51
50
|
).filter(module => module.sourcePath !== Runtime.workspace.path);
|
|
52
51
|
}
|
|
53
52
|
|
|
@@ -103,7 +102,7 @@ export class CliModuleUtil {
|
|
|
103
102
|
/**
|
|
104
103
|
* Find changed paths, either files between two git commits, or all folders for changed modules
|
|
105
104
|
*/
|
|
106
|
-
static async findChangedPaths(config: { since?: string
|
|
105
|
+
static async findChangedPaths(config: { since?: string; changed?: boolean; logError?: boolean } = {}): Promise<string[]> {
|
|
107
106
|
if (config.since) {
|
|
108
107
|
try {
|
|
109
108
|
const files = await CliScmUtil.findChangedFiles(config.since, 'HEAD');
|
|
@@ -119,4 +118,4 @@ export class CliModuleUtil {
|
|
|
119
118
|
return modules.map(module => module.sourcePath);
|
|
120
119
|
}
|
|
121
120
|
}
|
|
122
|
-
}
|
|
121
|
+
}
|