@travetto/cli 8.0.0-alpha.9 → 8.0.0

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,14 +1,14 @@
1
- import { type Class, type ClassInstance, Env, Runtime, RuntimeIndex, castTo, describeFunction, getClass } from '@travetto/runtime';
1
+ import { type Class, type ClassInstance, castTo, describeFunction, Env, getClass, Runtime, RuntimeIndex } from '@travetto/runtime';
2
2
  import { SchemaRegistryIndex, type ValidationError } from '@travetto/schema';
3
3
 
4
- import type { CliCommandShape } from '../types.ts';
5
- import { CliCommandRegistryIndex } from './registry-index.ts';
6
4
  import { CliModuleUtil } from '../module.ts';
7
5
  import { CliParseUtil } from '../parse.ts';
6
+ import type { CliCommandShape } from '../types.ts';
8
7
  import { CliUtil } from '../util.ts';
8
+ import { CliCommandRegistryIndex } from './registry-index.ts';
9
9
 
10
10
  type CliCommandConfigOptions = { runTarget?: boolean };
11
- type CliFlagOptions = { full?: string, short?: string, envVars?: string[] };
11
+ type CliFlagOptions = { full?: string; short?: string; envVars?: string[] };
12
12
 
13
13
  /**
14
14
  * Decorator to register a CLI command
@@ -32,8 +32,7 @@ export function CliCommand(config: CliCommandConfigOptions = {}) {
32
32
  */
33
33
  export function CliFlag(config: CliFlagOptions) {
34
34
  return function (instance: ClassInstance, property: string): void {
35
- SchemaRegistryIndex.getForRegister(getClass(instance))
36
- .registerField(property, CliParseUtil.buildAliases(config));
35
+ SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, CliParseUtil.buildAliases(config));
37
36
  };
38
37
  }
39
38
 
@@ -65,9 +64,9 @@ export function CliProfilesFlag(config: CliFlagOptions = {}) {
65
64
  description: 'Application profiles'
66
65
  });
67
66
 
68
- CliCommandRegistryIndex.registerPreMain<typeof instance>(cls, 1, cmd => Env.TRV_PROFILES.add(...cmd[property] ?? []));
67
+ CliCommandRegistryIndex.registerPreMain<typeof instance>(cls, 1, cmd => Env.TRV_PROFILES.add(...(cmd[property] ?? [])));
69
68
  };
70
- };
69
+ }
71
70
 
72
71
  /**
73
72
  * Registers a flag to support targeting a specific module
@@ -84,28 +83,35 @@ export function CliModuleFlag(config: CliFlagOptions & { scope?: 'current' | 'co
84
83
  ...CliParseUtil.buildAliases(config, Env.TRV_MODULE.key),
85
84
  description: 'Module to run for',
86
85
  specifiers: ['module'],
87
- required: { active: Runtime.monoRoot },
86
+ required: { active: Runtime.monoRoot && config.scope !== 'command' }
88
87
  });
89
88
 
90
89
  SchemaRegistryIndex.getForRegister(cls).register({
91
- validators: [async (cmd: CliCommandShape): Promise<ValidationError | undefined> => {
92
- const typed: (typeof cmd) & { [property]?: string } = castTo(cmd);
93
- const providedModule = typed[property];
94
- const runModule = (config.scope === 'command' ? commandModule : providedModule) || Runtime.main.name;
95
-
96
- // If we need to run as a specific module
97
- if (runModule !== Runtime.main.name && RuntimeIndex.getModule(runModule) === undefined) {
98
- return { source: 'flag', message: `${runModule} is an unknown module`, kind: 'custom', path: property };
90
+ validators: [
91
+ async (cmd: CliCommandShape): Promise<ValidationError | undefined> => {
92
+ const typed: typeof cmd & { [property]?: string } = castTo(cmd);
93
+ const providedModule = typed[property];
94
+ const runModule = (config.scope === 'command' ? commandModule : providedModule) || Runtime.main.name;
95
+
96
+ // If we need to run as a specific module
97
+ if (runModule !== Runtime.main.name && RuntimeIndex.getModule(runModule) === undefined) {
98
+ return { source: 'flag', message: `${runModule} is an unknown module`, kind: 'custom', path: property };
99
+ }
100
+
101
+ if (!(await CliModuleUtil.moduleHasDependency(runModule, commandModule))) {
102
+ return {
103
+ source: 'flag',
104
+ message: `${runModule} does not have ${commandModule} as a dependency`,
105
+ kind: 'custom',
106
+ path: property
107
+ };
108
+ }
99
109
  }
100
-
101
- if (!(await CliModuleUtil.moduleHasDependency(runModule, commandModule))) {
102
- return { source: 'flag', message: `${runModule} does not have ${commandModule} as a dependency`, kind: 'custom', path: property };
103
- }
104
- }],
110
+ ]
105
111
  });
106
112
 
107
113
  CliCommandRegistryIndex.registerPreMain<typeof instance>(cls, 5, cmd => {
108
- const typed: (typeof cmd) & { [property]?: string } = castTo(cmd);
114
+ const typed: typeof cmd & { [property]?: string } = castTo(cmd);
109
115
  const providedModule = typed[property];
110
116
  const runModule = (config.scope === 'command' ? commandModule : providedModule) || Runtime.main.name;
111
117
  if (runModule !== Runtime.main.name) {
@@ -123,7 +129,9 @@ export function CliModuleFlag(config: CliFlagOptions & { scope?: 'current' | 'co
123
129
  export function CliRestartOnChangeFlag(config: CliFlagOptions = {}) {
124
130
  return function <K extends string, T extends Partial<Record<K, boolean>>>(instance: T, property: K): void {
125
131
  const cls = getClass(instance);
126
- if (Runtime.production) { return; }
132
+ if (Runtime.production) {
133
+ return;
134
+ }
127
135
 
128
136
  SchemaRegistryIndex.getForRegister(cls).registerField(property, {
129
137
  ...CliParseUtil.buildAliases(config),
@@ -142,12 +150,14 @@ export function CliRestartOnChangeFlag(config: CliFlagOptions = {}) {
142
150
  */
143
151
  export function CliDebugIpcFlag(config: CliFlagOptions = {}) {
144
152
  return function <K extends string, T extends Partial<Record<K, boolean>>>(instance: T, property: K): void {
145
- if (Runtime.production) { return; }
153
+ if (Runtime.production) {
154
+ return;
155
+ }
146
156
 
147
157
  const cls = getClass(instance);
148
158
  SchemaRegistryIndex.getForRegister(cls).registerField(property, {
149
159
  ...CliParseUtil.buildAliases(config, Env.TRV_DEBUG_IPC.key),
150
- description: 'Should the invocation automatically restart on source changes'
160
+ description: 'Should the invocation support debugging via IPC (e.g. from VSCode)'
151
161
  });
152
162
 
153
163
  CliCommandRegistryIndex.getForRegister(cls).register({ runTarget: true });
@@ -156,4 +166,4 @@ export function CliDebugIpcFlag(config: CliFlagOptions = {}) {
156
166
  return cmd[property] && CliUtil.runWithDebugIpc(cliConfig.name);
157
167
  });
158
168
  };
159
- }
169
+ }
@@ -1,21 +1,22 @@
1
- import { type Class, classConstruct, describeFunction } from '@travetto/runtime';
2
1
  import type { RegistryAdapter } from '@travetto/registry';
2
+ import { type Class, classConstruct, describeFunction } from '@travetto/runtime';
3
3
  import { SchemaRegistryIndex } from '@travetto/schema';
4
4
 
5
- import type { CliCommandConfig, CliCommandShape } from '../types.ts';
6
5
  import { CliParseUtil, ENV_PREFIX } from '../parse.ts';
6
+ import type { CliCommandConfig, CliCommandShape } from '../types.ts';
7
7
 
8
8
  const CLI_FILE_REGEX = /\/cli[.](?<name>.{0,100}?)([.]tsx?)?$/;
9
9
 
10
10
  const getName = (name: string): string => (name.match(CLI_FILE_REGEX)?.groups?.name ?? name).replaceAll('_', ':');
11
11
  const stripDashes = (flag?: string): string | undefined => flag?.replace(/^-+/, '');
12
- const toFlagName = (field: string): string => field.replace(/([a-z])([A-Z])/g, (_, left: string, right: string) => `${left}-${right.toLowerCase()}`);
12
+ const toFlagName = (field: string): string =>
13
+ field.replace(/([a-z])([A-Z])/g, (_, left: string, right: string) => `${left}-${right.toLowerCase()}`);
13
14
 
14
15
  function combineClasses(base: CliCommandConfig, ...configs: Partial<CliCommandConfig>[]): CliCommandConfig {
15
16
  for (const config of configs) {
16
17
  base.runTarget = config.runTarget ?? base.runTarget;
17
18
  if (config.preMain) {
18
- base.preMain = [...base.preMain ?? [], ...config.preMain ?? []];
19
+ base.preMain = [...(base.preMain ?? []), ...(config.preMain ?? [])];
19
20
  }
20
21
  }
21
22
  return base;
@@ -29,26 +30,15 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
29
30
  this.#cls = cls;
30
31
  }
31
32
 
33
+ // TODO: handle when aliases overlap/conflict
32
34
  finalize(parent?: CliCommandConfig): void {
33
35
  // Add help command
34
36
  const schema = SchemaRegistryIndex.getConfig(this.#cls);
35
-
36
- // Add help to every command
37
- (schema.fields ??= {}).help = {
38
- type: Boolean,
39
- name: 'help',
40
- class: this.#cls,
41
- description: 'display help for command',
42
- required: { active: false },
43
- default: false,
44
- access: 'readonly',
45
- aliases: ['-h', '--help']
46
- };
47
-
48
- const used = new Set(Object.values(schema.fields)
49
- .flatMap(field => field.aliases ?? [])
50
- .filter(alias => !alias.startsWith(ENV_PREFIX))
51
- .map(stripDashes)
37
+ const used = new Set(
38
+ Object.values(schema.fields)
39
+ .flatMap(field => field.aliases ?? [])
40
+ .filter(alias => !alias.startsWith(ENV_PREFIX))
41
+ .map(stripDashes)
52
42
  );
53
43
 
54
44
  for (const field of Object.values(schema.fields)) {
@@ -57,7 +47,7 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
57
47
 
58
48
  let short = stripDashes(shortAliases?.[0]) ?? rawAliases.find(alias => alias.length <= 2);
59
49
  const long = stripDashes(longAliases?.[0]) ?? rawAliases.find(alias => alias.length >= 3) ?? toFlagName(fieldName);
60
- const aliases: string[] = field.aliases = [...envAliases];
50
+ const aliases: string[] = (field.aliases = [...envAliases]);
61
51
 
62
52
  if (short === undefined) {
63
53
  short = fieldName.charAt(0);
@@ -77,7 +67,7 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
77
67
  }
78
68
 
79
69
  if (parent) {
80
- this.#config.preMain = [...this.#config.preMain, ...parent?.preMain ?? []];
70
+ this.#config.preMain = [...this.#config.preMain, ...(parent?.preMain ?? [])];
81
71
  }
82
72
 
83
73
  // Sort
@@ -93,7 +83,7 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
93
83
  */
94
84
  register(...configs: Partial<CliCommandConfig>[]): CliCommandConfig {
95
85
  const metadata = describeFunction(this.#cls);
96
- this.#config ??= { cls: this.#cls, name: getName(metadata.import), preMain: [], runTarget: true };
86
+ this.#config ??= { cls: this.#cls, name: getName(metadata.import), preMain: [], runTarget: false };
97
87
  return combineClasses(this.#config, ...configs);
98
88
  }
99
89
 
@@ -103,4 +93,4 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
103
93
  getInstance(): CliCommandShape {
104
94
  return classConstruct(this.#cls);
105
95
  }
106
- }
96
+ }
@@ -1,5 +1,5 @@
1
+ import { Registry, type RegistryAdapter, type RegistryIndex, RegistryIndexStore } from '@travetto/registry';
1
2
  import { type Any, type Class, getClass, getParentClass, isClass, Runtime, RuntimeIndex } from '@travetto/runtime';
2
- import { type RegistryAdapter, type RegistryIndex, RegistryIndexStore, Registry } from '@travetto/registry';
3
3
  import { type SchemaClassConfig, SchemaRegistryIndex } from '@travetto/schema';
4
4
 
5
5
  import type { CliCommandConfig, CliCommandShape, PreMainHandler } from '../types.ts';
@@ -8,12 +8,11 @@ import { CliCommandRegistryAdapter } from './registry-adapter.ts';
8
8
  const CLI_FILE_REGEX = /\/cli[.](?<name>.{0,100}?)([.]tsx?)?$/;
9
9
  const getName = (field: string): string => (field.match(CLI_FILE_REGEX)?.groups?.name ?? field).replaceAll('_', ':');
10
10
 
11
- type CliCommandLoadResult = { command: string, config: CliCommandConfig, instance: CliCommandShape, schema: SchemaClassConfig };
11
+ type CliCommandLoadResult = { command: string; config: CliCommandConfig; instance: CliCommandShape; schema: SchemaClassConfig };
12
12
 
13
13
  export const UNKNOWN_COMMAND = Symbol();
14
14
 
15
15
  export class CliCommandRegistryIndex implements RegistryIndex {
16
-
17
16
  static #instance = Registry.registerIndex(this);
18
17
 
19
18
  static getForRegister(cls: Class): RegistryAdapter<CliCommandConfig> {
@@ -37,7 +36,9 @@ export class CliCommandRegistryIndex implements RegistryIndex {
37
36
 
38
37
  store = new RegistryIndexStore(CliCommandRegistryAdapter);
39
38
 
40
- /** @private */ constructor(source: unknown) { Registry.validateConstructor(source); }
39
+ /** @private */ constructor(source: unknown) {
40
+ Registry.validateConstructor(source);
41
+ }
41
42
 
42
43
  /**
43
44
  * Get list of all commands available
@@ -71,19 +72,16 @@ export class CliCommandRegistryIndex implements RegistryIndex {
71
72
 
72
73
  const found = this.#commandMapping.get(name)!;
73
74
  const values = Object.values(await Runtime.importFrom<Record<string, Class>>(found));
74
- const filtered = values
75
- .filter(isClass)
76
- .reduce<Class[]>((classes, cls) => {
77
- const parent = getParentClass(cls);
78
- if (parent && !classes.includes(parent)) {
79
- classes.push(parent);
80
- }
81
- classes.push(cls);
82
- return classes;
83
- }, []);
84
-
85
- const uninitialized = filtered
86
- .filter(cls => !this.store.finalized(cls));
75
+ const filtered = values.filter(isClass).reduce<Class[]>((classes, cls) => {
76
+ const parent = getParentClass(cls);
77
+ if (parent && !classes.includes(parent)) {
78
+ classes.push(parent);
79
+ }
80
+ classes.push(cls);
81
+ return classes;
82
+ }, []);
83
+
84
+ const uninitialized = filtered.filter(cls => !this.store.finalized(cls));
87
85
 
88
86
  // Initialize any uninitialized commands
89
87
  if (uninitialized.length) {
@@ -110,13 +108,15 @@ export class CliCommandRegistryIndex implements RegistryIndex {
110
108
  async load(names?: string[]): Promise<CliCommandLoadResult[]> {
111
109
  const keys = names ?? [...this.#commandMapping.keys()];
112
110
 
113
- const list = await Promise.all(keys.map(async key => {
114
- const instance = await this.#getInstance(key);
115
- const config = this.store.get(getClass(instance)).get();
116
- const schema = SchemaRegistryIndex.getConfig(getClass(instance));
117
- return { command: key, instance, config, schema };
118
- }));
111
+ const list = await Promise.all(
112
+ keys.map(async key => {
113
+ const instance = await this.#getInstance(key);
114
+ const config = this.store.get(getClass(instance)).get();
115
+ const schema = SchemaRegistryIndex.getConfig(getClass(instance));
116
+ return { command: key, instance, config, schema };
117
+ })
118
+ );
119
119
 
120
120
  return list.sort((a, b) => a.command.localeCompare(b.command));
121
121
  }
122
- }
122
+ }
@@ -1,7 +1,7 @@
1
- import { castTo, type Class, describeFunction } from '@travetto/runtime';
1
+ import { type Class, castTo, describeFunction } from '@travetto/runtime';
2
2
  import { type SchemaInputConfig, SchemaRegistryIndex } from '@travetto/schema';
3
3
 
4
- import { CliCommandRegistryIndex } from '../src/registry/registry-index.ts';
4
+ import { CliCommandRegistryIndex } from './registry/registry-index.ts';
5
5
 
6
6
  /**
7
7
  * CLI Command argument/flag shape
@@ -32,24 +32,30 @@ export interface CliCommandSchema<K extends string = string> {
32
32
  }
33
33
 
34
34
  export class CliSchemaExportUtil {
35
-
36
35
  /**
37
36
  * Get the base type for a CLI command input
38
37
  */
39
38
  static baseInputType(config: SchemaInputConfig): Pick<CliCommandInput, 'type' | 'fileExtensions'> {
40
39
  switch (castTo<Function>(config.type)) {
41
- case Date: return { type: 'date' };
42
- case Boolean: return { type: 'boolean' };
43
- case Number: return { type: 'number' };
44
- case RegExp: return { type: 'regex' };
45
- case BigInt: return { type: 'bigint' };
40
+ case Date:
41
+ return { type: 'date' };
42
+ case Boolean:
43
+ return { type: 'boolean' };
44
+ case Number:
45
+ return { type: 'number' };
46
+ case RegExp:
47
+ return { type: 'regex' };
48
+ case BigInt:
49
+ return { type: 'bigint' };
46
50
  case String: {
47
51
  switch (true) {
48
- case config.specifiers?.includes('module'): return { type: 'module' };
49
- case config.specifiers?.includes('file'): return {
50
- type: 'file',
51
- fileExtensions: config.specifiers?.map(specifier => specifier.split('ext:')[1]).filter(specifier => !!specifier)
52
- };
52
+ case config.specifiers?.includes('module'):
53
+ return { type: 'module' };
54
+ case config.specifiers?.includes('file'):
55
+ return {
56
+ type: 'file',
57
+ fileExtensions: config.specifiers?.map(specifier => specifier.split('ext:')[1]).filter(specifier => !!specifier)
58
+ };
53
59
  }
54
60
  }
55
61
  }
@@ -62,14 +68,17 @@ export class CliSchemaExportUtil {
62
68
  static processInput(config: SchemaInputConfig): CliCommandInput {
63
69
  return {
64
70
  ...this.baseInputType(config),
65
- ...(('name' in config && typeof config.name === 'string') ? { name: config.name } : { name: '' }),
71
+ ...('name' in config && typeof config.name === 'string' ? { name: config.name } : { name: '' }),
66
72
  description: config.description,
67
73
  array: config.array,
68
74
  required: config.required?.active !== false,
69
75
  choices: config.enum?.values,
70
76
  default: Array.isArray(config.default) ? config.default.slice(0) : config.default,
71
77
  flagNames: (config.aliases ?? []).slice(0).filter(value => !value.startsWith('env.')),
72
- envVars: (config.aliases ?? []).slice(0).filter(value => value.startsWith('env.')).map(value => value.replace('env.', ''))
78
+ envVars: (config.aliases ?? [])
79
+ .slice(0)
80
+ .filter(value => value.startsWith('env.'))
81
+ .map(value => value.replace('env.', ''))
73
82
  };
74
83
  }
75
84
 
@@ -87,4 +96,4 @@ export class CliSchemaExportUtil {
87
96
  runTarget: config.runTarget ?? false
88
97
  };
89
98
  }
90
- }
99
+ }
package/src/schema.ts CHANGED
@@ -1,15 +1,18 @@
1
1
  import { castKey, castTo, getClass } from '@travetto/runtime';
2
- import { BindUtil, SchemaRegistryIndex, SchemaValidator, ValidationResultError, type ValidationError } from '@travetto/schema';
2
+ import { BindUtil, SchemaRegistryIndex, SchemaValidator, type ValidationError, ValidationResultError } from '@travetto/schema';
3
3
 
4
- import type { ParsedState, CliCommandShape } from './types.ts';
4
+ import type { CliCommandShape, ParsedState } from './types.ts';
5
5
 
6
6
  const getSource = (source: string | undefined, defaultSource: ValidationError['source']): ValidationError['source'] => {
7
7
  switch (source) {
8
8
  case 'custom':
9
9
  case 'arg':
10
- case 'flag': return source;
11
- case undefined: return defaultSource;
12
- default: return 'custom';
10
+ case 'flag':
11
+ return source;
12
+ case undefined:
13
+ return defaultSource;
14
+ default:
15
+ return 'custom';
13
16
  }
14
17
  };
15
18
 
@@ -41,7 +44,7 @@ export class CliCommandSchemaUtil {
41
44
  const key = castKey<T>(item.fieldName);
42
45
  const value = item.value!;
43
46
  if (item.array) {
44
- castTo<unknown[]>(template[key] ??= castTo([])).push(value);
47
+ castTo<unknown[]>((template[key] ??= castTo([]))).push(value);
45
48
  } else {
46
49
  template[key] = castTo(value);
47
50
  }
@@ -49,7 +52,7 @@ export class CliCommandSchemaUtil {
49
52
  }
50
53
  case 'arg': {
51
54
  if (item.array) {
52
- castTo<unknown[]>(bound[item.index] ??= []).push(item.input);
55
+ castTo<unknown[]>((bound[item.index] ??= [])).push(item.input);
53
56
  } else {
54
57
  bound[item.index] = item.input;
55
58
  }
@@ -67,11 +70,13 @@ export class CliCommandSchemaUtil {
67
70
  */
68
71
  static async validate(command: CliCommandShape, args: unknown[]): Promise<typeof command> {
69
72
  const cls = getClass(command);
70
- const paramNames = SchemaRegistryIndex.get(cls).getMethod('main').parameters.map(config => config.name!);
73
+ const paramNames = SchemaRegistryIndex.get(cls)
74
+ .getMethod('main')
75
+ .parameters.map(config => config.name!);
71
76
 
72
77
  const results = await Promise.all([
73
78
  SchemaValidator.validate(cls, command).then(() => [], transformFlagErrors),
74
- SchemaValidator.validateMethod(cls, 'main', args, paramNames).then(() => [], transformArgErrors),
79
+ SchemaValidator.validateMethod(cls, 'main', args, paramNames).then(() => [], transformArgErrors)
75
80
  ]);
76
81
 
77
82
  const errors = results.flat();
@@ -80,4 +85,4 @@ export class CliCommandSchemaUtil {
80
85
  }
81
86
  return command;
82
87
  }
83
- }
88
+ }
package/src/scm.ts CHANGED
@@ -2,8 +2,8 @@ import { spawn } from 'node:child_process';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
 
5
- import { RuntimeError, ExecUtil, Runtime, RuntimeIndex } from '@travetto/runtime';
6
5
  import type { IndexedModule } from '@travetto/manifest';
6
+ import { ExecUtil, Runtime, RuntimeError, RuntimeIndex } from '@travetto/runtime';
7
7
 
8
8
  export class CliScmUtil {
9
9
  /**
@@ -12,17 +12,20 @@ export class CliScmUtil {
12
12
  * @returns
13
13
  */
14
14
  static isRepoRoot(folder: string): Promise<boolean> {
15
- return fs.stat(path.resolve(folder, '.git')).then(() => true, () => false);
15
+ return fs.stat(path.resolve(folder, '.git')).then(
16
+ () => true,
17
+ () => false
18
+ );
16
19
  }
17
20
 
18
21
  /**
19
22
  * Get author information
20
23
  * @returns
21
24
  */
22
- static async getAuthor(): Promise<{ name?: string, email: string }> {
25
+ static async getAuthor(): Promise<{ name?: string; email: string }> {
23
26
  const [name, email] = await Promise.all([
24
27
  ExecUtil.getResult(spawn('git', ['config', 'user.name']), { catch: true }),
25
- ExecUtil.getResult(spawn('git', ['config', 'user.email'])),
28
+ ExecUtil.getResult(spawn('git', ['config', 'user.email']))
26
29
  ]);
27
30
  return {
28
31
  name: (name.valid ? name.stdout.trim() : '') || process.env.USER,
@@ -35,10 +38,12 @@ export class CliScmUtil {
35
38
  * @returns
36
39
  */
37
40
  static async findLastRelease(): Promise<string | undefined> {
41
+ // cspell:words oneline
38
42
  const result = await ExecUtil.getResult(spawn('git', ['log', '--pretty=oneline'], { cwd: Runtime.workspace.path }));
39
43
  return result.stdout
40
44
  .split(/\n/)
41
- .find(line => /Publish /.test(line))?.split(/\s+/)?.[0];
45
+ .find(line => /Publish /.test(line))
46
+ ?.split(/\s+/)?.[0];
42
47
  }
43
48
 
44
49
  /**
@@ -48,9 +53,15 @@ export class CliScmUtil {
48
53
  */
49
54
  static async findChangedFiles(fromHash: string, toHash: string = 'HEAD'): Promise<string[]> {
50
55
  const rootPath = Runtime.workspace.path;
51
- const result = await ExecUtil.getResult(spawn('git', ['diff', '--name-only', `${fromHash}..${toHash}`, ':!**/DOC.*', ':!**/README.*'], { cwd: rootPath }), { catch: true });
56
+ const result = await ExecUtil.getResult(
57
+ spawn('git', ['diff', '--name-only', `${fromHash}..${toHash}`, ':!**/DOC.*', ':!**/README.*'], { cwd: rootPath }),
58
+ { catch: true }
59
+ );
52
60
  if (!result.valid) {
53
- throw new RuntimeError('Unable to detect changes between', { category: 'data', details: { fromHash, toHash, output: (result.stderr || result.stdout) } });
61
+ throw new RuntimeError('Unable to detect changes between', {
62
+ category: 'data',
63
+ details: { fromHash, toHash, output: result.stderr || result.stdout }
64
+ });
54
65
  }
55
66
  const out = new Set<string>();
56
67
  for (const line of result.stdout.split(/\n/g)) {
@@ -76,8 +87,7 @@ export class CliScmUtil {
76
87
  .map(file => RuntimeIndex.getModule(file.module))
77
88
  .filter(module => !!module);
78
89
 
79
- return [...new Set(modules)]
80
- .toSorted((a, b) => a.name.localeCompare(b.name));
90
+ return [...new Set(modules)].toSorted((a, b) => a.name.localeCompare(b.name));
81
91
  }
82
92
 
83
93
  /**
@@ -103,4 +113,4 @@ export class CliScmUtil {
103
113
  const res2 = await ExecUtil.getResult(spawn('git', ['diff', '--quiet', '--exit-code', '--cached']), { catch: true });
104
114
  return !res1.valid || !res2.valid;
105
115
  }
106
- }
116
+ }