-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(wrangler/cli): add @bomb.sh/tab completions
#11113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
e9c0d42
f5f65e1
3e0e733
4b2b606
b74ad8d
f0f739b
768ef7a
e38e836
be3b023
15d5e4c
b1e60dd
412fa27
f49e16b
20222b6
3437d21
8c87c89
77a6ef3
89757a4
85ca3e7
4f5476c
7752c58
2f05cd5
c8d2486
e8a27f9
d18b46e
25bee9d
ac25016
149ae0f
137fb10
6fd7f18
72e17bb
b4364b0
76fc750
5efb94b
a016b97
e9e79a1
b2fc39e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "wrangler": minor | ||
| --- | ||
|
|
||
| Add tab completion for commands | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| // shell completions for wrangler - this dynamically extracts commands from the actual command registry | ||
| import t from "@bomb.sh/tab"; | ||
NuroDev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| import { experimental_getWranglerCommands } from "./experimental-commands-api"; | ||
| import type { DefinitionTreeNode } from "./core/types"; | ||
|
|
||
| export function setupCompletions() { | ||
AmirSa12 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const { registry, globalFlags } = experimental_getWranglerCommands(); | ||
|
|
||
| // global flags that work on every command | ||
| for (const [flagName, flagDef] of Object.entries(globalFlags)) { | ||
| // skip hidden flags | ||
| if ("hidden" in flagDef && flagDef.hidden) continue; | ||
|
|
||
| const description = flagDef.describe || ""; | ||
| t.option(flagName, description); | ||
|
|
||
| if ("alias" in flagDef && flagDef.alias) { | ||
| const aliases = Array.isArray(flagDef.alias) | ||
| ? flagDef.alias | ||
| : [flagDef.alias]; | ||
| for (const alias of aliases) { | ||
| t.option(alias, `Alias for --${flagName}`); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // recursively add commands from the registry tree | ||
| function addCommandsFromTree( | ||
| node: DefinitionTreeNode, | ||
| parentPath: string[] = [] | ||
| ) { | ||
| for (const [name, childNode] of node.subtree.entries()) { | ||
| const commandPath = [...parentPath, name]; | ||
| const commandName = commandPath.join(" "); | ||
|
|
||
| if (childNode.definition) { | ||
| const def = childNode.definition; | ||
| let description = ""; | ||
|
|
||
| if (def.metadata?.description) { | ||
| description = def.metadata.description; | ||
| } | ||
|
|
||
| if ( | ||
| def.metadata?.status && | ||
| def.metadata.status !== "stable" && | ||
| !def.metadata.hidden | ||
| ) { | ||
| const statusLabels = { | ||
| experimental: "[experimental]", | ||
| alpha: "[alpha]", | ||
| "private-beta": "[private-beta]", | ||
| "open-beta": "[open-beta]", | ||
NuroDev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
| const statusLabel = | ||
| statusLabels[def.metadata.status as keyof typeof statusLabels]; | ||
| if (statusLabel) { | ||
| description = `${description} ${statusLabel}`; | ||
| } | ||
| } | ||
|
|
||
| if (!def.metadata?.hidden) { | ||
| const cmd = t.command(commandName, description); | ||
|
|
||
| if (def.type === "command" && "args" in def) { | ||
| const args = def.args || {}; | ||
| for (const [argName, argDef] of Object.entries(args)) { | ||
| if (argDef.hidden) continue; | ||
|
|
||
| const argDescription = argDef.describe || ""; | ||
|
|
||
| if (argDef.choices && Array.isArray(argDef.choices)) { | ||
| cmd.option(argName, argDescription, (complete) => { | ||
| for (const choice of argDef.choices as string[]) { | ||
| complete(choice, choice); | ||
| } | ||
| }); | ||
| } else { | ||
| cmd.option(argName, argDescription); | ||
| } | ||
|
|
||
| if (argDef.alias) { | ||
| const aliases = Array.isArray(argDef.alias) | ||
| ? argDef.alias | ||
| : [argDef.alias]; | ||
| for (const alias of aliases) { | ||
| cmd.option(alias, `Alias for --${argName}`); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (childNode.subtree.size > 0) { | ||
| addCommandsFromTree(childNode, commandPath); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| addCommandsFromTree(registry); | ||
|
|
||
| return t; | ||
| } | ||
| // Handle completion requests from the shell | ||
| export function handleCompletion(args: string[]) { | ||
| const shell = args[0]; | ||
|
|
||
| if (shell === "--") { | ||
| // Parse completion request from shell | ||
| setupCompletions(); | ||
| t.parse(args.slice(1)); | ||
| } else { | ||
| // Generate shell completion script | ||
| setupCompletions(); | ||
| t.setup("wrangler", "wrangler", shell); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ import { | |
| } from "./cert/cert"; | ||
| import { checkNamespace, checkStartupCommand } from "./check/commands"; | ||
| import { cloudchamber } from "./cloudchamber"; | ||
| import { handleCompletion } from "./complete"; | ||
| import { getDefaultEnvFiles, loadDotEnv } from "./config/dot-env"; | ||
| import { containers } from "./containers"; | ||
| import { demandSingleValue } from "./core"; | ||
|
|
@@ -1630,6 +1631,12 @@ export function createCLIParser(argv: string[]) { | |
| export async function main(argv: string[]): Promise<void> { | ||
| setupSentry(); | ||
|
|
||
| // Handle shell completion requests | ||
| if (argv[0] === "complete") { | ||
| handleCompletion(argv.slice(1)); | ||
| return; | ||
| } | ||
|
||
|
|
||
| checkMacOSVersion({ shouldThrow: false }); | ||
|
|
||
| const startTime = Date.now(); | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.