diff --git a/backend/domain/ast.go b/backend/domain/ast.go deleted file mode 100644 index 1050de2..0000000 --- a/backend/domain/ast.go +++ /dev/null @@ -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"` -} \ No newline at end of file diff --git a/backend/domain/workspace.go b/backend/domain/workspace.go index a96f19d..ec0279d 100644 --- a/backend/domain/workspace.go +++ b/backend/domain/workspace.go @@ -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 diff --git a/backend/internal/workspace/handler/http/v1/workspace.go b/backend/internal/workspace/handler/http/v1/workspace.go index 4b14088..e3e9841 100644 --- a/backend/internal/workspace/handler/http/v1/workspace.go +++ b/backend/internal/workspace/handler/http/v1/workspace.go @@ -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) diff --git a/backend/internal/workspace/usecase/workspace.go b/backend/internal/workspace/usecase/workspace.go index 3988fb7..a5d58d2 100644 --- a/backend/internal/workspace/usecase/workspace.go +++ b/backend/internal/workspace/usecase/workspace.go @@ -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 diff --git a/backend/pkg/cli/cli.go b/backend/pkg/cli/cli.go index f44a6d1..2d1e532 100644 --- a/backend/pkg/cli/cli.go +++ b/backend/pkg/cli/cli.go @@ -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 ] 解析时允许的最大 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 }