Skip to content

Commit 6993b44

Browse files
authored
Merge pull request #770 from elan-llm/custom_help
ACNA-4221: Addding custome help class to fix alias rt to display help… + adobe/aio-cli-plugin-runtime#389
2 parents 007af24 + 829deb8 commit 6993b44

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"topicSeparator": " ",
7979
"commands": "./src/commands",
8080
"bin": "aio",
81+
"helpClass": "./src/custom-help",
8182
"plugins": [
8283
"@oclif/plugin-help",
8384
"@oclif/plugin-plugins",

src/custom-help.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2025 Adobe Inc. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
const { Help } = require('@oclif/core')
14+
15+
/**
16+
* Custom Help class to handle alias resolution for command help display.
17+
*
18+
* Issue: When users run "aio rt --help", oclif's help system doesn't recognize
19+
* that "rt" is an alias for "runtime" and should display all subcommands.
20+
* The help system looks for "rt:*" subcommands which don't exist in the manifest
21+
* (they're registered as "runtime:*").
22+
*
23+
* Solution: Override showHelp to resolve aliases to their canonical command names
24+
* before displaying help, ensuring proper subcommand listing.
25+
*
26+
* @see https://github.com/adobe/aio-cli-plugin-runtime
27+
*/
28+
class CustomHelp extends Help {
29+
/**
30+
* Show help for a command, resolving aliases to canonical names.
31+
*
32+
* @param {string[]} args - Command ID and arguments to show help for
33+
* @returns {Promise<void>}
34+
*/
35+
async showHelp (args) {
36+
// Skip alias resolution if args is invalid or empty
37+
if (!Array.isArray(args) || args.length === 0) {
38+
return super.showHelp(args)
39+
}
40+
41+
// Map of known aliases to canonical command names
42+
// Add more mappings here as needed for other top-level aliases
43+
const aliasMap = {
44+
rt: 'runtime'
45+
}
46+
47+
// Resolve alias to canonical name if it exists
48+
const commandId = args[0]
49+
if (aliasMap[commandId]) {
50+
const resolvedArgs = [aliasMap[commandId], ...args.slice(1)]
51+
return super.showHelp(resolvedArgs)
52+
}
53+
54+
// No alias resolution needed, show help as-is
55+
return super.showHelp(args)
56+
}
57+
}
58+
59+
module.exports = CustomHelp

test/custom-help.test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2025 Adobe Inc. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
const { Help } = require('@oclif/core')
14+
const CustomHelp = require('../src/custom-help')
15+
16+
describe('CustomHelp', () => {
17+
let customHelp
18+
let showHelpSpy
19+
20+
beforeEach(() => {
21+
const mockConfig = { commands: new Map(), topics: [] }
22+
customHelp = new CustomHelp(mockConfig)
23+
showHelpSpy = jest.spyOn(Help.prototype, 'showHelp').mockResolvedValue()
24+
})
25+
26+
afterEach(() => {
27+
showHelpSpy.mockRestore()
28+
})
29+
30+
test('resolves "rt" alias to "runtime"', async () => {
31+
await customHelp.showHelp(['rt'])
32+
expect(showHelpSpy).toHaveBeenCalledWith(['runtime'])
33+
})
34+
35+
test('resolves "rt" with subcommands', async () => {
36+
await customHelp.showHelp(['rt', 'action'])
37+
expect(showHelpSpy).toHaveBeenCalledWith(['runtime', 'action'])
38+
})
39+
40+
test('passes through non-aliased commands unchanged', async () => {
41+
await customHelp.showHelp(['config'])
42+
expect(showHelpSpy).toHaveBeenCalledWith(['config'])
43+
})
44+
45+
test('handles empty array', async () => {
46+
await customHelp.showHelp([])
47+
expect(showHelpSpy).toHaveBeenCalledWith([])
48+
})
49+
50+
test('handles non-array arguments', async () => {
51+
await customHelp.showHelp('runtime')
52+
expect(showHelpSpy).toHaveBeenCalledWith('runtime')
53+
})
54+
})

0 commit comments

Comments
 (0)