Skip to content

Commit

Permalink
feat(cli): Enhance CLI command help (#1418)
Browse files Browse the repository at this point in the history
  • Loading branch information
saeta-eth authored Sep 27, 2024
1 parent f413dc9 commit ee72af7
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/cli/src/util/commands-config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Command } from 'commander';
import { formatCommandHelp } from './format-command-help';
import { parsePackageArguments, parsePackagesArguments } from './params';
import type { Command as CommandConfig } from '../commands/config/types';

Expand Down Expand Up @@ -50,5 +51,9 @@ export const applyCommandsConfig = (command: Command, config: CommandConfig) =>
});
}

// override the help output to add a header for anvil and forge options
const originalHelpInformation = command.helpInformation.bind(command);
command.helpInformation = () => formatCommandHelp(originalHelpInformation());

return command;
};
53 changes: 53 additions & 0 deletions packages/cli/src/util/format-command-help.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { formatCommandHelp } from './format-command-help';

describe('formatCommandHelp', () => {
it('should group Anvil options', () => {
const input = `
--option1 Description1
--anvil.option1 AnvilDescription1
--anvil.option2 AnvilDescription2
--option2 Description2
`;
const result = formatCommandHelp(input);
expect(result).toContain('Anvil Options:');
expect(result.indexOf('--anvil.option1')).toBeGreaterThan(result.indexOf('Anvil Options:'));
expect(result.indexOf('--anvil.option2')).toBeGreaterThan(result.indexOf('Anvil Options:'));
});

it('should group Forge options', () => {
const input = `
--option1 Description1
--forge.option1 ForgeDescription1
--forge.option2 ForgeDescription2
--option2 Description2
`;
const result = formatCommandHelp(input);
expect(result).toContain('Forge Options:');
expect(result.indexOf('--forge.option1')).toBeGreaterThan(result.indexOf('Forge Options:'));
expect(result.indexOf('--forge.option2')).toBeGreaterThan(result.indexOf('Forge Options:'));
});

it('should place help option after the last main option', () => {
const input = `
--option1 Description1
--option2 Description2
--anvil.option1 AnvilDescription1
-h, --help Show help
`;
const result = formatCommandHelp(input);
const helpIndex = result.indexOf('-h, --help');
const option2Index = result.indexOf('--option2');
const anvilOptionIndex = result.indexOf('--anvil.option1');
expect(helpIndex).toBeGreaterThan(option2Index);
expect(helpIndex).toBeLessThan(anvilOptionIndex);
});

it('should handle input with no special options', () => {
const input = `
--option1 Description1
--option2 Description2
`;
const result = formatCommandHelp(input);
expect(result).toBe(input);
});
});
37 changes: 37 additions & 0 deletions packages/cli/src/util/format-command-help.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export function formatCommandHelp(inputText: string): string {
const lines = inputText.split('\n');
const optionGroups = [
{ prefix: '--anvil.', header: 'Anvil Options:' },
{ prefix: '--forge.', header: 'Forge Options:' },
];

const result: string[] = [];
let helpLine: string | null = null;
let lastMainOptionIndex = -1;

lines.forEach((line) => {
const trimmedLine = line.trim();

if (trimmedLine.startsWith('-h, --help')) {
helpLine = line;
return;
}

const group = optionGroups.find((g) => trimmedLine.startsWith(g.prefix));
if (group) {
if (!result.includes(group.header)) {
result.push('', group.header);
}
} else if (trimmedLine.startsWith('-')) {
lastMainOptionIndex = result.length;
}

result.push(line);
});

if (helpLine) {
result.splice(lastMainOptionIndex + 1, 0, helpLine);
}

return result.join('\n');
}

0 comments on commit ee72af7

Please sign in to comment.