gitlink-cli/doc/dev-guide.md

165 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# gitlink-cli 开发指南
## 环境准备
### 前置条件
- Go 1.22+(构建 CLI
- Node.js 14+npm 安装包,可选)
- Git
### 克隆与构建
```bash
git clone https://gitlink.org.cn/Gitlink/gitlink-cli.git
cd gitlink-cli
make build # 构建二进制
make install # 安装到 $GOPATH/bin
make test # 运行测试
make lint # 代码检查
```
## 项目结构
```
cmd/ # Cobra 命令定义
root.go # 根命令 + 全局 flags
auth/auth.go # 认证命令
api/api.go # Raw API 命令
config/config.go # 配置命令
cmdutil/ # 全局工具
internal/ # 内部包
auth/ # 登录、Token 存储
client/ # HTTP 客户端 + 分页
config/ # 配置文件管理
context/ # git remote 解析
output/ # 输出格式化
shortcuts/ # Shortcut 实现
common/ # 框架types, runner, testutil
_template/ # 开发模板
register.go # 注册入口
issue/ # Issue shortcuts参考实现
skills/ # AI Agent Skills
```
## 新增 Shortcut 指南
### 1. 创建域目录
```bash
mkdir -p shortcuts/mydomain
```
### 2. 实现 Shortcuts
参考 `shortcuts/_template/template.go``shortcuts/issue/issue.go`
每个域需要实现 `Shortcuts()` 函数,返回 `[]*common.Shortcut` 列表:
```go
package mydomain
import "github.com/gitlink-org/gitlink-cli/shortcuts/common"
func Shortcuts() []*common.Shortcut {
return []*common.Shortcut{
{
Name: "list",
Description: "List resources",
Flags: []common.Flag{
{Name: "page", Short: "p", Usage: "Page number", Default: "1"},
},
Run: func(ctx *common.RuntimeContext) error {
if err := ctx.ResolveOwnerRepo(); err != nil {
return err
}
env, err := ctx.CallAPI("GET", ctx.RepoPath()+"/resources", nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
}
}
```
### 3. 注册域
`shortcuts/register.go` 中添加:
```go
import "github.com/gitlink-org/gitlink-cli/shortcuts/mydomain"
// 在 RegisterShortcuts 函数中:
common.MountShortcut(rootCmd, "mydomain", mydomain.Shortcuts())
```
### 4. 编写测试
参考 `shortcuts/issue/issue_test.go`,使用 `common.NewTestServer``common.NewTestContext`
```go
package mydomain
import (
"net/http"
"testing"
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
)
func TestMyDomainList(t *testing.T) {
server := common.NewTestServer(t, func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" && r.URL.Path == "/owner/repo/resources.json" {
common.WriteJSON(t, w, map[string]interface{}{
"resources": []interface{}{},
})
} else {
t.Fatalf("unexpected: %s %s", r.Method, r.URL.Path)
}
})
defer server.Close()
ctx := common.NewTestContext(t, server, "owner", "repo", map[string]string{})
err := common.RunShortcut(t, Shortcuts(), "list", ctx)
if err != nil {
t.Fatalf("list failed: %v", err)
}
}
```
## API 约定
### v1 API 路径
Issue 相关操作使用 v1 路径:`/v1/{owner}/{repo}/issues`
其他操作使用:`/{owner}/{repo}/...`
### HTTP 方法映射
| 操作 | 方法 |
|------|------|
| 列表 | GET |
| 查看 | GET |
| 创建 | POST |
| 更新 | PATCH/PUT |
| 删除 | DELETE |
### 通用参数
- `--owner` / `--repo`:自动从 git remote 解析
- `--format`输出格式json/table/yaml
- `--page` / `--limit`:分页
## 测试
```bash
make test # 运行所有测试
make test-cover # 运行测试并生成覆盖率报告
go test -v ./shortcuts/mydomain/ # 测试单个域
```
## 提交 PR 前检查清单
- [ ] `make test` 通过
- [ ] `make lint` 通过(或 `go vet ./...`
- [ ] 新 Shortcut 已注册到 `register.go`
- [ ] 包含单元测试
- [ ] 帮助文档Description、Flags Usage已更新