forked from Gitlink/gitlink-cli
fix(interactive): 命令面板选中带可选参数的命令也弹出表单
CI / test (push) Failing after 2m4s
Details
CI / test (push) Failing after 2m4s
Details
根因:updatePalette 只在有缺失的 Required flag 时才弹参数表单。但很多 命令的参数是'至少一个'关系(如 branch +batch-protect 的 --names/--from 二选一),无法单独标记 Required,导致 missingRequiredFlags 返回空, 表单被跳过,命令直接执行后报 'no branch names provided'。 修复:把表单触发条件从'有缺失必填参数'改为'命令有任何 flag'。这样 选中任何带参数的命令都弹表单,用户能填可选参数(留空即跳过)。 无 flag 的命令(如 wiki +list、repo +recommend)仍直接执行。 回归测试 TestPaletteSelectionOpensFormForOptionalFlags 验证模拟的 batch-protect(全可选参数)选中后进入 stateForm 而非直接执行。
This commit is contained in:
parent
c7a2ca3685
commit
d12ce0fb57
|
|
@ -0,0 +1,57 @@
|
|||
package interactive
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
||||
)
|
||||
|
||||
// TestPaletteSelectionOpensFormForOptionalFlags 验证:选中一个"只有可选参数、
|
||||
// 无必填参数"的命令(如 branch +batch-protect 的 names/from 二选一)时,
|
||||
// 仍然弹出参数表单,而非直接执行导致 "no ... provided" 错误。
|
||||
//
|
||||
// 回归:之前 updatePalette 只在有缺失的 Required flag 时才弹表单,
|
||||
// 导致 names/from 这类"至少一个"型参数(无法单独标 Required)的命令
|
||||
// 被直接执行,用户没机会输入参数。
|
||||
func TestPaletteSelectionOpensFormForOptionalFlags(t *testing.T) {
|
||||
// 构造一个模拟 branch +batch-protect 的 shortcut:所有 flag 都非必填。
|
||||
shortcuts := map[string][]*common.Shortcut{
|
||||
"branch": {
|
||||
{
|
||||
Name: "batch-protect",
|
||||
Description: "批量保护分支",
|
||||
Flags: []common.Flag{
|
||||
{Name: "names", Usage: "分支名(逗号分隔)"}, // 无 Required
|
||||
{Name: "from", Usage: "文件路径"}, // 无 Required
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error { return nil },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
m := newReplModel("owner", "repo")
|
||||
// 注入测试 registry
|
||||
m.shortcuts = shortcuts
|
||||
|
||||
// 1) 输入 / 触发命令面板
|
||||
m2, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'/'}})
|
||||
repl := m2.(replModel)
|
||||
if repl.state != statePalette {
|
||||
t.Fatalf("输入 / 后应在 statePalette,实际 %v", repl.state)
|
||||
}
|
||||
|
||||
// 2) 模拟用户选中 branch 组
|
||||
repl.palette.result = &PaletteResult{
|
||||
Group: "branch",
|
||||
Shortcut: shortcuts["branch"][0],
|
||||
}
|
||||
|
||||
// 3) 派发一条任意消息触发 updatePalette 的结果检查
|
||||
m3, _ := repl.Update(tea.KeyMsg{Type: tea.KeyEnter})
|
||||
final := m3.(replModel)
|
||||
|
||||
if final.state != stateForm {
|
||||
t.Fatalf("选中带可选参数的命令应进入 stateForm,实际 %v(命令被直接执行了,用户没机会填参数)", final.state)
|
||||
}
|
||||
}
|
||||
|
|
@ -250,17 +250,19 @@ func (m replModel) updatePalette(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
result := m.palette.result
|
||||
s := result.Shortcut
|
||||
|
||||
// Only open the form when required flags are missing.
|
||||
// Commands with only optional flags execute directly — users can pass
|
||||
// flags via the direct-command syntax if needed.
|
||||
missing := missingRequiredFlags(s, map[string]string{})
|
||||
if len(missing) > 0 {
|
||||
// Open the form whenever the command has ANY flags — not just required
|
||||
// ones. Many commands have "at-least-one-of" parameters (e.g. branch
|
||||
// +batch-protect needs --names OR --from) that can't be marked Required
|
||||
// individually, so skipping the form for "optional-only" commands left
|
||||
// users unable to supply them and the command failed at runtime.
|
||||
// Commands with no flags at all execute directly.
|
||||
if len(s.Flags) > 0 {
|
||||
m.form = newFormModel(result.Group, s, m.width, m.height, nil)
|
||||
m.state = stateForm
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// No required flags missing → execute directly
|
||||
// No flags → execute directly
|
||||
m.state = stateExecuting
|
||||
return m, tea.Batch(m.executeCommand(result.Group, s, map[string]string{}), m.spinner.Tick)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue