You've already forked agentic-coding-workflow
feat(workspace): domain types + pathing/validation
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package workspace
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// 输入校验正则。改动需要同步更新 spec §3.6 与 dto.go 的错误消息。
|
||||
var (
|
||||
slugRe = regexp.MustCompile(`^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$`)
|
||||
branchRe = regexp.MustCompile(`^[A-Za-z0-9._/-]{1,200}$`)
|
||||
)
|
||||
|
||||
// ValidateSlug 报告 slug 是否合法。
|
||||
func ValidateSlug(slug string) error {
|
||||
if !slugRe.MatchString(slug) {
|
||||
return errors.New("slug must be lowercase alnum + '-' (1..32 chars), no leading/trailing dash")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateBranch 报告 branch 名是否合法(防止被 git 当成 flag)。
|
||||
func ValidateBranch(b string) error {
|
||||
if !branchRe.MatchString(b) {
|
||||
return errors.New("branch must match [A-Za-z0-9._/-]{1,200}")
|
||||
}
|
||||
if strings.HasPrefix(b, "-") || strings.HasPrefix(b, "+") || strings.HasPrefix(b, "/") {
|
||||
return errors.New("branch must not start with '-', '+', or '/'")
|
||||
}
|
||||
if strings.Contains(b, "..") {
|
||||
return errors.New("branch must not contain '..'")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateRemoteURL 检查 scheme 白名单。
|
||||
func ValidateRemoteURL(u string) error {
|
||||
switch {
|
||||
case strings.HasPrefix(u, "https://"),
|
||||
strings.HasPrefix(u, "http://"),
|
||||
strings.HasPrefix(u, "ssh://"),
|
||||
strings.HasPrefix(u, "git@"):
|
||||
return nil
|
||||
}
|
||||
return errors.New("git_remote_url must be https/http/ssh/git@ scheme")
|
||||
}
|
||||
|
||||
// MainPath 计算 workspace.main_path 绝对路径。dataDir 是配置中的 ${DATA_DIR}。
|
||||
func MainPath(dataDir string, wsID uuid.UUID) string {
|
||||
return filepath.Join(dataDir, "workspaces", wsID.String(), "main")
|
||||
}
|
||||
|
||||
// WorktreePath 计算支线 worktree 绝对路径。branch slug 化后嵌入路径。
|
||||
func WorktreePath(dataDir string, wsID uuid.UUID, branch string) string {
|
||||
return filepath.Join(dataDir, "workspaces", wsID.String(), ".worktrees", branchSlug(branch))
|
||||
}
|
||||
|
||||
// TmpDir 是 git CLI 凭据/known_hosts 临时文件根目录。启动期需清空。
|
||||
func TmpDir(dataDir string) string {
|
||||
return filepath.Join(dataDir, "tmp")
|
||||
}
|
||||
|
||||
// branchSlug 把 branch 名转成可作为目录名的字符串。
|
||||
//
|
||||
// 规则:把 '/' 替换为 '_';其他非法字符保留(branchRe 已限制)。
|
||||
func branchSlug(b string) string {
|
||||
return strings.ReplaceAll(b, "/", "_")
|
||||
}
|
||||
Reference in New Issue
Block a user