Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/ts-command-line",
"comment": "Remove `abstract` modifier from `CommandLineParser` class to allow direct instantiation. Remove redundant `_actions` array field.",
"type": "minor"
}
],
"packageName": "@rushstack/ts-command-line"
}
2 changes: 1 addition & 1 deletion common/reviews/api/ts-command-line.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export abstract class CommandLineParameterWithArgument extends CommandLineParame
}

// @public
export abstract class CommandLineParser extends CommandLineParameterProvider {
export class CommandLineParser extends CommandLineParameterProvider {
constructor(options: ICommandLineParserOptions);
get actions(): ReadonlyArray<CommandLineAction>;
addAction(action: CommandLineAction): void;
Expand Down
11 changes: 4 additions & 7 deletions libraries/ts-command-line/src/providers/CommandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ export interface ICommandLineParserOptions {
* The "argparse" library is a relatively advanced command-line parser with features such
* as word-wrapping and intelligible error messages (that are lacking in other similar
* libraries such as commander, yargs, and nomnom). Unfortunately, its ruby-inspired API
* is awkward to use. The abstract base classes CommandLineParser and CommandLineAction
* is awkward to use. The base classes CommandLineParser and CommandLineAction
* provide a wrapper for "argparse" that makes defining and consuming arguments quick
* and simple, and enforces that appropriate documentation is provided for each parameter.
*
* @public
*/
export abstract class CommandLineParser extends CommandLineParameterProvider {
export class CommandLineParser extends CommandLineParameterProvider {
/**
* Reports which CommandLineAction was specified on the command line.
* @remarks
Expand All @@ -65,7 +65,6 @@ export abstract class CommandLineParser extends CommandLineParameterProvider {
private readonly _argumentParser: argparse.ArgumentParser;
private _actionsSubParser: argparse.SubParser | undefined;
private readonly _options: ICommandLineParserOptions;
private readonly _actions: CommandLineAction[];
private readonly _actionsByName: Map<string, CommandLineAction>;
private _executed: boolean = false;
private _tabCompleteActionWasAdded: boolean = false;
Expand All @@ -74,7 +73,6 @@ export abstract class CommandLineParser extends CommandLineParameterProvider {
super();

this._options = options;
this._actions = [];
this._actionsByName = new Map<string, CommandLineAction>();

const { toolFilename, toolDescription, toolEpilog } = options;
Expand All @@ -95,7 +93,7 @@ export abstract class CommandLineParser extends CommandLineParameterProvider {
* Returns the list of actions that were defined for this CommandLineParser object.
*/
public get actions(): ReadonlyArray<CommandLineAction> {
return this._actions;
return Array.from(this._actionsByName.values());
}

/**
Expand All @@ -110,7 +108,6 @@ export abstract class CommandLineParser extends CommandLineParameterProvider {
}

action._buildParser(this._actionsSubParser);
this._actions.push(action);
this._actionsByName.set(action.actionName, action);
}

Expand Down Expand Up @@ -314,7 +311,7 @@ export abstract class CommandLineParser extends CommandLineParameterProvider {
...state,
parentParameterNames: updatedParentParameterNames
};
for (const action of this._actions) {
for (const action of this._actionsByName.values()) {
action._registerDefinedParameters(parentState);
}
}
Expand Down
18 changes: 18 additions & 0 deletions libraries/ts-command-line/src/test/CommandLineParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,22 @@ describe(CommandLineParser.name, () => {
const action: TestAction = commandLineParser.selectedAction as TestAction;
expect(action.done).toBe(true);
});

it('can be instantiated directly without subclassing', () => {
// This test verifies that CommandLineParser can be instantiated directly,
// which is useful for test scenarios
const commandLineParser = new CommandLineParser({
toolFilename: 'test-tool',
toolDescription: 'A test tool'
});

expect(commandLineParser).toBeDefined();
expect(commandLineParser.actions).toEqual([]);

// Verify that addAction can be called on the direct instance
const action = new TestAction();
commandLineParser.addAction(action);
expect(commandLineParser.actions).toHaveLength(1);
expect(commandLineParser.actions[0]).toBe(action);
});
});