Compare commits

...

5 Commits

Author SHA1 Message Date
Florian Forster b8840edbcd
Merge 399779240e into 02326d52c0 2024-11-14 14:39:51 +08:00
Vui Lam 02326d52c0
Fix broken links in active_help.md (#2202)
Small change to fix a couple of broken links in active_help.md

Signed-off-by: Vui Lam <vui.lam@broadcom.com>
2024-11-05 06:19:24 -05:00
Leonhard Stemplinger 5a138f143f
Make Powershell completion script work in constrained mode (#2196)
Creating CompletionResult objects is not allowed in Powershell constrained mode, so return results as strings if constrained mode is enabled

Store results as PsCustomObjects instead of hashtables. This prevents Sort-Object from trying to convert the hashtable to a object, which is blocked in constrained mode.
PsCustomObjects are created using New-Object to work around https://github.com/PowerShell/PowerShell/issues/20767
2024-11-03 19:45:01 -05:00
Florian Forster 399779240e doc: Improve the `WithUsage` example. 2024-01-12 09:13:41 +01:00
Florian Forster 4cba342aae feat: Add the `WithUsage` function. 2024-01-12 08:49:07 +01:00
4 changed files with 85 additions and 8 deletions

13
args.go
View File

@ -129,3 +129,16 @@ func MatchAll(pargs ...PositionalArgs) PositionalArgs {
func ExactValidArgs(n int) PositionalArgs {
return MatchAll(ExactArgs(n), OnlyValidArgs)
}
// WithUsage wraps another PositionalArgs function. If the function fails
// (returns a non-nil error), the error is supplemented with the command's
// usage message, providing the user with the information required to run the
// command correctly.
func WithUsage(wrapped PositionalArgs) PositionalArgs {
return func(cmd *Command, args []string) error {
if err := wrapped(cmd, args); err != nil {
return fmt.Errorf("%w\n\n%s", err, cmd.UsageString())
}
return nil
}
}

View File

@ -539,3 +539,42 @@ func TestLegacyArgsSubcmdAcceptsArgs(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
}
// WithUsage
func TestWithUsage(t *testing.T) {
c := getCommand(WithUsage(ExactArgs(1)), false)
_, err := executeCommand(c /* no args */)
if err == nil {
t.Fatalf("Expected error, got nil")
}
got, want := err.Error(), c.UsageString()
if !strings.Contains(got, want) {
t.Errorf("Expected error containing %q, got %q", want, got)
}
}
func ExampleWithUsage() {
cmd := &Command{
Use: "example <arg>",
Args: WithUsage(ExactArgs(1)),
Run: func(*Command, []string) {
panic("not reached")
},
}
cmd.SetArgs([]string{"1", "2"})
err := cmd.Execute()
fmt.Print(err)
// Output:
// accepts 1 arg(s), received 2
//
// Usage:
// example <arg> [flags]
//
// Flags:
// -h, --help help for example
}

View File

@ -162,7 +162,10 @@ filter __%[1]s_escapeStringWithSpecialChars {
if (-Not $Description) {
$Description = " "
}
@{Name="$Name";Description="$Description"}
New-Object -TypeName PSCustomObject -Property @{
Name = "$Name"
Description = "$Description"
}
}
@ -240,7 +243,12 @@ filter __%[1]s_escapeStringWithSpecialChars {
__%[1]s_debug "Only one completion left"
# insert space after value
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
$CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space
if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
[System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
} else {
$CompletionText
}
} else {
# Add the proper number of spaces to align the descriptions
@ -255,7 +263,12 @@ filter __%[1]s_escapeStringWithSpecialChars {
$Description = " ($($comp.Description))"
}
[System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
$CompletionText = "$($comp.Name)$Description"
if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
[System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
} else {
$CompletionText
}
}
}
@ -264,7 +277,13 @@ filter __%[1]s_escapeStringWithSpecialChars {
# insert space after value
# MenuComplete will automatically show the ToolTip of
# the highlighted value at the bottom of the suggestions.
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
$CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space
if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
[System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
} else {
$CompletionText
}
}
# TabCompleteNext and in case we get something unknown
@ -272,7 +291,13 @@ filter __%[1]s_escapeStringWithSpecialChars {
# Like MenuComplete but we don't want to add a space here because
# the user need to press space anyway to get the completion.
# Description will not be shown because that's not possible with TabCompleteNext
[System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
$CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars)
if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
[System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
} else {
$CompletionText
}
}
}

View File

@ -20,12 +20,12 @@ bin/ internal/ scripts/ pkg/ testdata/
## Supported shells
Active Help is currently only supported for the following shells:
- Bash (using [bash completion V2](shell_completions.md#bash-completion-v2) only). Note that bash 4.4 or higher is required for the prompt to appear when an Active Help message is printed.
- Bash (using [bash completion V2](completions/_index.md#bash-completion-v2) only). Note that bash 4.4 or higher is required for the prompt to appear when an Active Help message is printed.
- Zsh
## Adding Active Help messages
As Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions. If you are not familiar with dynamic completions, please refer to [Shell Completions](shell_completions.md).
As Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions. If you are not familiar with dynamic completions, please refer to [Shell Completions](completions/_index.md).
Adding Active Help is done through the use of the `cobra.AppendActiveHelp(...)` function, where the program repeatedly adds Active Help messages to the list of completions. Keep reading for details.
@ -148,7 +148,7 @@ details for your users.
## Debugging Active Help
Debugging your Active Help code is done in the same way as debugging your dynamic completion code, which is with Cobra's hidden `__complete` command. Please refer to [debugging shell completion](shell_completions.md#debugging) for details.
Debugging your Active Help code is done in the same way as debugging your dynamic completion code, which is with Cobra's hidden `__complete` command. Please refer to [debugging shell completion](completions/_index.md#debugging) for details.
When debugging with the `__complete` command, if you want to specify different Active Help configurations, you should use the active help environment variable. That variable is named `<PROGRAM>_ACTIVE_HELP` where any non-ASCII-alphanumeric characters are replaced by an `_`. For example, we can test deactivating some Active Help as shown below: