feat: 适配了新的CLI命令

This commit is contained in:
chriscco
2025-07-25 17:54:38 +08:00
parent e2ac6cb3b6
commit 3dab9bf7dd
5 changed files with 90 additions and 42 deletions

View File

@@ -1,12 +0,0 @@
package domain
type ParseResult struct {
FilePath string `json:"file_path"`
Definition string `json:"definition"`
Error string `json:"error,omitempty"`
Success bool `json:"success"`
}
type SaveAstReq struct {
UserID string `json:"user_id" validate:"required"`
ProjectID string `json:"project_id" validate:"required"`
Files []string `json:"files" validate:"required"`
}

View File

@@ -14,7 +14,7 @@ type WorkspaceFileUsecase interface {
Create(ctx context.Context, req *CreateWorkspaceFileReq) (*WorkspaceFile, error)
Update(ctx context.Context, req *UpdateWorkspaceFileReq) (*WorkspaceFile, error)
Delete(ctx context.Context, id string) error
GetAndSave(ctx context.Context, req *SaveAstReq) error
GetAndSave(ctx context.Context, req *GetAndSaveReq) error
GetByID(ctx context.Context, id string) (*WorkspaceFile, error)
GetByPath(ctx context.Context, userID, workspaceID, path string) (*WorkspaceFile, error)
List(ctx context.Context, req *ListWorkspaceFileReq) (*ListWorkspaceFileResp, error)
@@ -82,6 +82,12 @@ type SyncWorkspaceFileReq struct {
Files []*CreateWorkspaceFileReq `json:"files" validate:"required,dive"` // 要同步的文件列表
}
type GetAndSaveReq struct {
CodeFiles CodeFiles `json:"code_files" validate:"required"` // 代码文件信息
UserID string `json:"user_id" validate:"required"` // 用户ID
ProjectID string `json:"project_id" validate:"required"` // 项目ID
}
// 响应结构体
type ListWorkspaceFileResp struct {
@@ -111,6 +117,56 @@ type WorkspaceFile struct {
UpdatedAt int64 `json:"updated_at"` // 更新时间
}
type CodeLanguageType string
const (
CodeLanguageTypeGo CodeLanguageType = "go"
CodeLanguageTypePython CodeLanguageType = "python"
CodeLanguageTypeJava CodeLanguageType = "java"
CodeLanguageTypeJavaScript CodeLanguageType = "javascript"
CodeLanguageTypeTypeScript CodeLanguageType = "typescript"
CodeLanguageTypeJSX CodeLanguageType = "jsx"
CodeLanguageTypeTSX CodeLanguageType = "tsx"
CodeLanguageTypeHTML CodeLanguageType = "html"
CodeLanguageTypeCSS CodeLanguageType = "css"
CodeLanguageTypePHP CodeLanguageType = "php"
CodeLanguageTypeRust CodeLanguageType = "rust"
CodeLanguageTypeSwift CodeLanguageType = "swift"
CodeLanguageTypeKotlin CodeLanguageType = "kotlin"
CodeLanguageTypeC CodeLanguageType = "c"
CodeLanguageTypeCpp CodeLanguageType = "cpp"
)
type CodeFiles struct {
Files []FileMeta `json:"files"`
}
type FileMeta struct {
FilePath string `json:"filePath"`
FileExtension string `json:"fileExtension"`
Language CodeLanguageType `json:"language"` // 语言类型(可选)
FileHash string `json:"fileHash"` // 文件哈希(可选)
Content string `json:"content"` // 文件内容(可选)
}
type IndexResult struct {
Name string `json:"name"`
Type string `json:"type"`
FilePath string `json:"filePath"`
StartLine int `json:"startLine"`
EndLine int `json:"endLine"`
RangeText string `json:"rangeText"`
DefinitionText string `json:"definitionText"`
Scope []struct{} `json:"scope"`
FileHash string `json:"fileHash"`
Definition struct {
Name string `json:"name"`
Type string `json:"type"`
ReturnType string `json:"returnType"`
} `json:"definition"`
Signature string `json:"signature"`
Language string `json:"language"`
ImplementText string `json:"implementText"`
}
func (w *WorkspaceFile) From(e *db.WorkspaceFile) *WorkspaceFile {
if e == nil {
return w

View File

@@ -95,13 +95,13 @@ func (h *WorkspaceFileHandler) GetByID(c *web.Context, req struct {
// GetAndSave
// @Tags WorkspaceFile
// @Summary 获取并保存工作区文件
// @param ctx
// @param ctx
// @param req
// @return error
func (h *WorkspaceFileHandler) GetAndSave(ctx *web.Context, req *domain.SaveAstReq) error {
func (h *WorkspaceFileHandler) GetAndSave(ctx *web.Context, req *domain.GetAndSaveReq) error {
err := h.usecase.GetAndSave(ctx.Request().Context(), req)
if err != nil {
h.logger.Error("failed to get and save workspace files", "error", err, "count", len(req.Files))
h.logger.Error("failed to get and save workspace files", "error", err, "count", len(req.CodeFiles.Files))
return err
}
return ctx.Success(nil)

View File

@@ -123,8 +123,8 @@ func (u *WorkspaceFileUsecase) GetByID(ctx context.Context, id string) (*domain.
return cvt.From(file, &domain.WorkspaceFile{}), nil
}
func (u *WorkspaceFileUsecase) GetAndSave(ctx context.Context, req *domain.SaveAstReq) (error) {
results, err := cli.RunParseCLI("parse", "", req.Files...)
func (u *WorkspaceFileUsecase) GetAndSave(ctx context.Context, req *domain.GetAndSaveReq) (error) {
results, err := cli.RunCli("index", "", req.CodeFiles)
if err != nil {
return err
}
@@ -134,12 +134,12 @@ func (u *WorkspaceFileUsecase) GetAndSave(ctx context.Context, req *domain.SaveA
return err
}
astData, err := json.Marshal(res.Definition)
if err != nil {
return err
}
resString, err := json.Marshal(res)
if err!= nil {
return err
}
_, err = u.repo.Update(ctx, file.ID.String(), func(up *db.WorkspaceFileUpdateOne) error {
return up.SetContent(string(astData)).Exec(ctx)
return up.SetContent(string(resString)).Exec(ctx)
})
if err != nil {
return err

View File

@@ -2,32 +2,36 @@ package cli
import (
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"github.com/chaitin/MonkeyCode/backend/domain"
)
// RunParseCLI
// @Description ctcode-cli 支持通过 CLI 的方式获取文件的 AST 信息
// @param command ["parse"] - 解析文件为 AST 树
// @param flag ["-s", "--successOnly"] - 是否只返回成功的结果
// @param paths 要解析的文件路径
// @return []ParseResult 解析结果数组
// @return error 错误信息
func RunParseCLI(command string, flag string, paths ...string) ([]domain.ParseResult, error) {
cmd := exec.Command("ctcode-cli", command, flag, strings.Join(paths, " "))
cmd.Env = os.Environ()
output, err := cmd.CombinedOutput()
fmt.Printf(`err: %s, output: %s\n`, fmt.Sprint(err), string(output))
// RunCli
// @Tags WorkspaceFile
// @Description: 运行ctcode-cli命令
// @param command 命令
// @param flag [ -m | --maxlines <int> ] 解析时允许的最大 CodeSnippet 行数
// @param codeFiles 代码文件信息
// @return string 输出结果
// @return error
func RunCli(command string, flag string, codeFiles domain.CodeFiles) ([]domain.IndexResult, error) {
inputJson, err := json.Marshal(codeFiles)
if err != nil {
return []domain.ParseResult{}, err
return []domain.IndexResult{}, err
}
var results []domain.ParseResult
if err := json.Unmarshal(output, &results); err != nil {
panic(err)
cmd := exec.Command("ctcode-cli", command, flag, string(inputJson))
cmd.Env = os.Environ()
output, err := cmd.CombinedOutput()
if err != nil {
return []domain.IndexResult{}, err
}
return results, nil
var res []domain.IndexResult
err = json.Unmarshal(output, &res)
if err!= nil {
return []domain.IndexResult{}, err
}
return res, nil
}