feat: 新增 shell 自动补全命令
This commit is contained in:
parent
9749a4c832
commit
5c16a4a70e
23
README.md
23
README.md
|
|
@ -172,6 +172,29 @@ export GITLINK_TOKEN="your-token" # Or set env var (for CI/CD, non-interactive e
|
|||
gitlink-cli repo +list
|
||||
```
|
||||
|
||||
#### Shell Completion
|
||||
|
||||
Generate completion scripts for your shell after installation:
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
mkdir -p ~/.local/share/bash-completion/completions
|
||||
gitlink-cli completion bash > ~/.local/share/bash-completion/completions/gitlink-cli
|
||||
|
||||
# Zsh
|
||||
gitlink-cli completion zsh > "${fpath[1]}/_gitlink-cli"
|
||||
|
||||
# Fish
|
||||
mkdir -p ~/.config/fish/completions
|
||||
gitlink-cli completion fish > ~/.config/fish/completions/gitlink-cli.fish
|
||||
|
||||
# PowerShell
|
||||
gitlink-cli completion powershell > gitlink-cli.ps1
|
||||
. ./gitlink-cli.ps1
|
||||
```
|
||||
|
||||
Use `--no-descriptions` if your shell setup prefers compact completion output.
|
||||
|
||||
### Quick Start (AI Agent)
|
||||
|
||||
> The following steps are for AI Agents. Some steps require the user to complete actions in a browser.
|
||||
|
|
|
|||
|
|
@ -180,6 +180,29 @@ export GITLINK_TOKEN="your-token" # 或设置环境变量(适用于 CI/CD、
|
|||
gitlink-cli repo +list
|
||||
```
|
||||
|
||||
#### Shell 自动补全
|
||||
|
||||
安装后可以为常用 shell 生成自动补全脚本:
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
mkdir -p ~/.local/share/bash-completion/completions
|
||||
gitlink-cli completion bash > ~/.local/share/bash-completion/completions/gitlink-cli
|
||||
|
||||
# Zsh
|
||||
gitlink-cli completion zsh > "${fpath[1]}/_gitlink-cli"
|
||||
|
||||
# Fish
|
||||
mkdir -p ~/.config/fish/completions
|
||||
gitlink-cli completion fish > ~/.config/fish/completions/gitlink-cli.fish
|
||||
|
||||
# PowerShell
|
||||
gitlink-cli completion powershell > gitlink-cli.ps1
|
||||
. ./gitlink-cli.ps1
|
||||
```
|
||||
|
||||
如果当前终端不需要补全说明文本,可以追加 `--no-descriptions` 生成更精简的脚本。
|
||||
|
||||
### 快速上手(AI Agent)
|
||||
|
||||
> 以下步骤面向 AI Agent。部分步骤需要用户在浏览器中完成操作。
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ func TestRootCmdHasSubcommands(t *testing.T) {
|
|||
}
|
||||
names := map[string]bool{}
|
||||
for _, sub := range root.Commands() {
|
||||
names[sub.Use] = true
|
||||
names[sub.Name()] = true
|
||||
}
|
||||
for _, want := range []string{"auth", "config", "doctor", "version"} {
|
||||
for _, want := range []string{"auth", "completion", "config", "doctor", "version"} {
|
||||
if !names[want] {
|
||||
t.Fatalf("missing subcommand: %s", want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompletionCmdGeneratesSupportedShells(t *testing.T) {
|
||||
cases := []struct {
|
||||
shell string
|
||||
want string
|
||||
}{
|
||||
{shell: "bash", want: "__gitlink-cli"},
|
||||
{shell: "zsh", want: "#compdef gitlink-cli"},
|
||||
{shell: "fish", want: "complete -c gitlink-cli"},
|
||||
{shell: "powershell", want: "Register-ArgumentCompleter"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
root, err := NewRootCmd(RootOptions{Version: "test", Args: []string{"completion", tc.shell}}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var out bytes.Buffer
|
||||
root.SetOut(&out)
|
||||
root.SetErr(&out)
|
||||
if err := root.Execute(); err != nil {
|
||||
t.Fatalf("%s completion error: %v", tc.shell, err)
|
||||
}
|
||||
if !strings.Contains(out.String(), tc.want) {
|
||||
t.Fatalf("%s completion missing %q, got:\n%s", tc.shell, tc.want, out.String()[:min(len(out.String()), 400)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompletionCmdNoDescriptions(t *testing.T) {
|
||||
root, err := NewRootCmd(RootOptions{
|
||||
Version: "test",
|
||||
Args: []string{"completion", "bash", "--no-descriptions"},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var out bytes.Buffer
|
||||
root.SetOut(&out)
|
||||
root.SetErr(&out)
|
||||
if err := root.Execute(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(out.String(), "GitLink CLI - command-line tool for GitLink") {
|
||||
t.Fatalf("expected descriptions to be omitted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompletionCmdRejectsUnsupportedShell(t *testing.T) {
|
||||
root, err := NewRootCmd(RootOptions{Version: "test", Args: []string{"completion", "xonsh"}}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var out bytes.Buffer
|
||||
root.SetOut(&out)
|
||||
root.SetErr(&out)
|
||||
err = root.Execute()
|
||||
if err == nil {
|
||||
t.Fatal("expected unsupported shell error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "invalid argument") {
|
||||
t.Fatalf("expected invalid argument error, got %q", err.Error())
|
||||
}
|
||||
}
|
||||
38
cmd/root.go
38
cmd/root.go
|
|
@ -58,6 +58,7 @@ func NewRootCmd(opts RootOptions, tr *i18n.Translator) (*cobra.Command, error) {
|
|||
rootCmd.AddCommand(apiCmd.NewAPICmd(tr))
|
||||
rootCmd.AddCommand(configCmd.NewConfigCmd(tr))
|
||||
rootCmd.AddCommand(doctorCmd.NewDoctorCmd(tr))
|
||||
rootCmd.AddCommand(newCompletionCmd(tr))
|
||||
rootCmd.AddCommand(newVersionCmd(version, tr))
|
||||
|
||||
shortcuts.RegisterAll(rootCmd, tr)
|
||||
|
|
@ -79,6 +80,43 @@ func newVersionCmd(version string, tr *i18n.Translator) *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
func newCompletionCmd(tr *i18n.Translator) *cobra.Command {
|
||||
var noDescriptions bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "completion [bash|zsh|fish|powershell]",
|
||||
Short: tr.T("cmd.completion.short"),
|
||||
Long: tr.T("cmd.completion.long"),
|
||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
root := cmd.Root()
|
||||
out := cmd.OutOrStdout()
|
||||
includeDescriptions := !noDescriptions
|
||||
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
return root.GenBashCompletionV2(out, includeDescriptions)
|
||||
case "zsh":
|
||||
if noDescriptions {
|
||||
return root.GenZshCompletionNoDesc(out)
|
||||
}
|
||||
return root.GenZshCompletion(out)
|
||||
case "fish":
|
||||
return root.GenFishCompletion(out, includeDescriptions)
|
||||
case "powershell":
|
||||
if noDescriptions {
|
||||
return root.GenPowerShellCompletion(out)
|
||||
}
|
||||
return root.GenPowerShellCompletionWithDesc(out)
|
||||
default:
|
||||
return fmt.Errorf("unsupported shell: %s", args[0])
|
||||
}
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&noDescriptions, "no-descriptions", false, tr.T("flag.completion.no_descriptions"))
|
||||
return cmd
|
||||
}
|
||||
|
||||
func Execute() error {
|
||||
args := os.Args[1:]
|
||||
rootCmd, err := NewRootCmd(RootOptions{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
# Shell 自动补全命令
|
||||
|
||||
新增 `gitlink-cli completion [bash|zsh|fish|powershell]`,用于为 Bash、Zsh、Fish 和 PowerShell 生成原生自动补全脚本。用户安装 CLI 后可以直接把脚本写入对应 shell 的补全目录,减少记忆 Shortcut 命令、全局参数和子命令名称的成本,也让跨平台安装体验更完整。
|
||||
|
||||
命令支持 `--no-descriptions`,在不需要补全文案的终端配置中可以输出更精简的脚本。实现复用 Cobra 官方补全生成能力,不引入远端 API 依赖,并通过单元测试覆盖四类 shell 输出、描述开关和非法 shell 参数校验。
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
"cmd.ci.restart.short": "Restart a build",
|
||||
"cmd.ci.short": "CI/CD operations",
|
||||
"cmd.ci.stop.short": "Stop a build",
|
||||
"cmd.completion.long": "Generate shell completion scripts for gitlink-cli.\n\nLoad the generated script in your shell profile to enable command and flag completion.\n\nExamples:\n gitlink-cli completion bash > ~/.local/share/bash-completion/completions/gitlink-cli\n gitlink-cli completion zsh > \"${fpath[1]}/_gitlink-cli\"\n gitlink-cli completion fish > ~/.config/fish/completions/gitlink-cli.fish\n gitlink-cli completion powershell > gitlink-cli.ps1",
|
||||
"cmd.completion.short": "Generate shell completion scripts",
|
||||
"cmd.config.get.short": "Get a configuration value",
|
||||
"cmd.config.init.short": "Initialize configuration file",
|
||||
"cmd.config.list.short": "List all configuration values",
|
||||
|
|
@ -130,6 +132,7 @@
|
|||
"flag.ci.stage": "Stage number",
|
||||
"flag.ci.step": "Step number",
|
||||
"flag.comment.body": "Comment body",
|
||||
"flag.completion.no_descriptions": "Disable completion descriptions",
|
||||
"flag.dataset.description": "Dataset description",
|
||||
"flag.dataset.dry_run": "Preview the request without writing the dataset",
|
||||
"flag.dataset.dry_run_delete": "Preview the request without deleting the attachment",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
"cmd.ci.restart.short": "重启构建",
|
||||
"cmd.ci.short": "CI/CD 操作",
|
||||
"cmd.ci.stop.short": "停止构建",
|
||||
"cmd.completion.long": "为 gitlink-cli 生成 shell 自动补全脚本。\n\n将生成的脚本加载到 shell 配置中,即可启用命令和参数补全。\n\n示例:\n gitlink-cli completion bash > ~/.local/share/bash-completion/completions/gitlink-cli\n gitlink-cli completion zsh > \"${fpath[1]}/_gitlink-cli\"\n gitlink-cli completion fish > ~/.config/fish/completions/gitlink-cli.fish\n gitlink-cli completion powershell > gitlink-cli.ps1",
|
||||
"cmd.completion.short": "生成 shell 自动补全脚本",
|
||||
"cmd.config.get.short": "获取配置项",
|
||||
"cmd.config.init.short": "初始化配置文件",
|
||||
"cmd.config.list.short": "列出所有配置项",
|
||||
|
|
@ -130,6 +132,7 @@
|
|||
"flag.ci.stage": "阶段编号",
|
||||
"flag.ci.step": "步骤编号",
|
||||
"flag.comment.body": "评论内容",
|
||||
"flag.completion.no_descriptions": "关闭补全描述",
|
||||
"flag.dataset.description": "数据集描述",
|
||||
"flag.dataset.dry_run": "预览请求,不写入数据集",
|
||||
"flag.dataset.dry_run_delete": "预览请求,不删除附件",
|
||||
|
|
|
|||
|
|
@ -63,6 +63,27 @@ gitlink-cli auth login
|
|||
- HTTPS: `https://www.gitlink.org.cn/owner/repo.git`
|
||||
- SSH: `git@www.gitlink.org.cn:owner/repo.git`
|
||||
|
||||
## Shell 自动补全
|
||||
|
||||
安装后可以按用户当前 shell 生成补全脚本,帮助用户发现 Shortcut 子命令和参数:
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
gitlink-cli completion bash > ~/.local/share/bash-completion/completions/gitlink-cli
|
||||
|
||||
# Zsh
|
||||
gitlink-cli completion zsh > "${fpath[1]}/_gitlink-cli"
|
||||
|
||||
# Fish
|
||||
gitlink-cli completion fish > ~/.config/fish/completions/gitlink-cli.fish
|
||||
|
||||
# PowerShell
|
||||
gitlink-cli completion powershell > gitlink-cli.ps1
|
||||
. ./gitlink-cli.ps1
|
||||
```
|
||||
|
||||
如果终端补全不需要描述文本,可以追加 `--no-descriptions`。
|
||||
|
||||
## 输出格式
|
||||
|
||||
所有命令输出遵循统一 Envelope 格式:
|
||||
|
|
|
|||
Loading…
Reference in New Issue