Allow passing full extension name (#5464)
This commit is contained in:
parent
bec49152cf
commit
00e97121ec
2 changed files with 90 additions and 31 deletions
|
|
@ -31,7 +31,8 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
executable of the same name. All arguments passed to the %[1]sgh <extname>%[1]s invocation
|
||||
will be forwarded to the %[1]sgh-<extname>%[1]s executable of the extension.
|
||||
|
||||
An extension cannot override any of the core gh commands.
|
||||
An extension cannot override any of the core gh commands. If an extension name conflicts
|
||||
with a core gh command you can use %[1]sgh extension exec <extname>%[1]s.
|
||||
|
||||
See the list of available extensions at <https://github.com/topics/gh-extension>.
|
||||
`, "`"),
|
||||
|
|
@ -79,21 +80,21 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
Use: "install <repository>",
|
||||
Short: "Install a gh extension from a repository",
|
||||
Long: heredoc.Doc(`
|
||||
Install a GitHub repository locally as a GitHub CLI extension.
|
||||
Install a GitHub repository locally as a GitHub CLI extension.
|
||||
|
||||
The repository argument can be specified in "owner/repo" format as well as a full URL.
|
||||
The URL format is useful when the repository is not hosted on github.com.
|
||||
The repository argument can be specified in "owner/repo" format as well as a full URL.
|
||||
The URL format is useful when the repository is not hosted on github.com.
|
||||
|
||||
To install an extension in development from the current directory, use "." as the
|
||||
value of the repository argument.
|
||||
To install an extension in development from the current directory, use "." as the
|
||||
value of the repository argument.
|
||||
|
||||
See the list of available extensions at <https://github.com/topics/gh-extension>.
|
||||
`),
|
||||
See the list of available extensions at <https://github.com/topics/gh-extension>.
|
||||
`),
|
||||
Example: heredoc.Doc(`
|
||||
$ gh extension install owner/gh-extension
|
||||
$ gh extension install https://git.example.com/owner/gh-extension
|
||||
$ gh extension install .
|
||||
`),
|
||||
$ gh extension install owner/gh-extension
|
||||
$ gh extension install https://git.example.com/owner/gh-extension
|
||||
$ gh extension install .
|
||||
`),
|
||||
Args: cmdutil.MinimumArgs(1, "must specify a repository to install from"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if args[0] == "." {
|
||||
|
|
@ -216,6 +217,31 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
return nil
|
||||
},
|
||||
},
|
||||
&cobra.Command{
|
||||
Use: "exec <name> [args]",
|
||||
Short: "Execute an installed extension",
|
||||
Long: heredoc.Doc(`
|
||||
Execute an extension using the short name. For example, if the extension repository is
|
||||
"owner/gh-extension", you should pass "extension". You can use this command when
|
||||
the short name conflicts with a core gh command.
|
||||
|
||||
All arguments after the extension name will be forwarded to the executable
|
||||
of the extension.
|
||||
`),
|
||||
Example: heredoc.Doc(`
|
||||
# execute a label extension instead of the core gh label command
|
||||
$ gh extension exec label
|
||||
`),
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if found, err := m.Dispatch(args, io.In, io.Out, io.ErrOut); !found {
|
||||
return fmt.Errorf("extension %q not found", args[0])
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
},
|
||||
},
|
||||
func() *cobra.Command {
|
||||
promptCreate := func() (string, extensions.ExtTemplateType, error) {
|
||||
var extName string
|
||||
|
|
@ -241,17 +267,17 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
Use: "create [<name>]",
|
||||
Short: "Create a new extension",
|
||||
Example: heredoc.Doc(`
|
||||
# Use interactively
|
||||
gh extension create
|
||||
# Use interactively
|
||||
gh extension create
|
||||
|
||||
# Create a script-based extension
|
||||
gh extension create foobar
|
||||
# Create a script-based extension
|
||||
gh extension create foobar
|
||||
|
||||
# Create a Go extension
|
||||
gh extension create --precompiled=go foobar
|
||||
# Create a Go extension
|
||||
gh extension create --precompiled=go foobar
|
||||
|
||||
# Create a non-Go precompiled extension
|
||||
gh extension create --precompiled=other foobar
|
||||
# Create a non-Go precompiled extension
|
||||
gh extension create --precompiled=other foobar
|
||||
`),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
@ -317,19 +343,19 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
}
|
||||
link := "https://docs.github.com/github-cli/github-cli/creating-github-cli-extensions"
|
||||
out := heredoc.Docf(`
|
||||
%[1]s Created directory %[2]s
|
||||
%[1]s Initialized git repository
|
||||
%[1]s Set up extension scaffolding
|
||||
%[6]s
|
||||
%[2]s is ready for development!
|
||||
%[1]s Created directory %[2]s
|
||||
%[1]s Initialized git repository
|
||||
%[1]s Set up extension scaffolding
|
||||
%[6]s
|
||||
%[2]s is ready for development!
|
||||
|
||||
%[4]s
|
||||
%[5]s
|
||||
- commit and use 'gh repo create' to share your extension with others
|
||||
%[4]s
|
||||
%[5]s
|
||||
- commit and use 'gh repo create' to share your extension with others
|
||||
|
||||
For more information on writing extensions:
|
||||
%[3]s
|
||||
`, cs.SuccessIcon(), fullName, link, cs.Bold("Next Steps"), steps, goBinChecks)
|
||||
For more information on writing extensions:
|
||||
%[3]s
|
||||
`, cs.SuccessIcon(), fullName, link, cs.Bold("Next Steps"), steps, goBinChecks)
|
||||
fmt.Fprint(io.Out, out)
|
||||
return nil
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package extension
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -515,6 +516,38 @@ func TestNewCmdExtension(t *testing.T) {
|
|||
isTTY: false,
|
||||
wantStdout: "",
|
||||
},
|
||||
{
|
||||
name: "exec extension missing",
|
||||
args: []string{"exec", "invalid"},
|
||||
managerStubs: func(em *extensions.ExtensionManagerMock) func(*testing.T) {
|
||||
em.DispatchFunc = func(args []string, stdin io.Reader, stdout, stderr io.Writer) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
return func(t *testing.T) {
|
||||
calls := em.DispatchCalls()
|
||||
assert.Equal(t, 1, len(calls))
|
||||
assert.EqualValues(t, []string{"invalid"}, calls[0].Args)
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: `extension "invalid" not found`,
|
||||
},
|
||||
{
|
||||
name: "exec extension with arguments",
|
||||
args: []string{"exec", "test", "arg1", "arg2", "--flag1"},
|
||||
managerStubs: func(em *extensions.ExtensionManagerMock) func(*testing.T) {
|
||||
em.DispatchFunc = func(args []string, stdin io.Reader, stdout, stderr io.Writer) (bool, error) {
|
||||
fmt.Fprintf(stdout, "test output")
|
||||
return true, nil
|
||||
}
|
||||
return func(t *testing.T) {
|
||||
calls := em.DispatchCalls()
|
||||
assert.Equal(t, 1, len(calls))
|
||||
assert.EqualValues(t, []string{"test", "arg1", "arg2", "--flag1"}, calls[0].Args)
|
||||
}
|
||||
},
|
||||
wantStdout: "test output",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue