package script import ( "fmt" "os" "os/exec" "strings" "time" ) // ExecuteScriptRequest 定义了执行脚本所需的参数和配置 type ExecuteScriptRequest struct { ScriptPath string Args []string Assets []string // 资产目录列表 // 脚本工作目录(默认当前目录) workDir string // 脚本执行环境变量(默认空) envVars map[string]string // 脚本执行日志文件路径(默认空,表示不记录日志) logFile string // 脚本执行超时时间(默认 0,表示不超时) timeout time.Duration // 脚本执行的命令元数据(可选),用于日志记录和监控 metadata *CommandMetadata // 脚本执行结果文件路径(默认空,表示不保存结果) resultFile string // 需要收集内容的文件列表 collectFiles []string // 日志回调函数, 用于实时输出日志(默认 nil,表示不使用回调) logCallback func(string) // 进程组管理控制参数, 用于避免脚本执行过程中,产生的子进程无法被正确杀死的问题 // 是否创建新的进程组(默认 true,用于杀死子进程树) // 设为 false 时,子进程不会被放入新的进程组,不能被组杀 createProcessGroup bool // 是否自定义 Cancel 函数以杀死进程组(默认 true) // 设为 false 时,使用默认的进程杀死方式 useProcessGroupKill bool // 命令执行信息 cmd *exec.Cmd } // SetEnv 设置环境变量, key会被强制转换为大写 func (s *ExecuteScriptRequest) SetEnv(key, value string) { key = strings.ToUpper(strings.TrimSpace(key)) s.envVars[key] = value if s.metadata != nil { s.metadata.EnvVars[key] = value } } // buildEnv 构建环境变量, 将请求中的环境变量与系统环境变量合并,返回一个新的环境变量列表 func (s *ExecuteScriptRequest) buildEnv() []string { env := os.Environ() // 获取系统环境变量 // 补充自定义环境变量 for key, value := range s.envVars { env = append(env, fmt.Sprintf("%s=%s", key, value)) } return env } // isDebugScriptEnabled 检查是否启用调试脚本 // 通过环境变量 DEBUG_SCRIPT 控制 (值为 true 或 1 时启用) func (s *ExecuteScriptRequest) isDebugScriptEnabled() bool { if val, ok := s.envVars["DEBUG_SCRIPT"]; ok { return strings.EqualFold(val, "true") || val == "1" } return false } func (r *ExecuteScriptRequest) WithWorkspacePrefix(workDirPrefix string) *ExecuteScriptRequest { if strings.HasPrefix(r.workDir, workDirPrefix) { return r } r.workDir = workDirPrefix + "/" + r.workDir return r } // CommandMetadata 命令元数据 type CommandMetadata struct { ID string `json:"id"` // 命令唯一ID Name string `json:"name"` // 命令名称 Description string `json:"description,omitempty"` // 命令描述 Tags []string `json:"tags,omitempty"` // 标签 CreatedBy string `json:"created_by"` // 创建者 CreatedAt time.Time `json:"created_at"` // 创建时间 Timeout time.Duration `json:"timeout"` // 超时时间 EnvVars map[string]string `json:"env_vars"` // 环境变量 WorkDir string `json:"work_dir"` // 工作目录 RefTask string `json:"ref_task,omitempty"` // 关联的任务 } // ExecutionResult 命令执行结果 type ExecutionResult struct { // 命令 Command string `json:"command"` // 错误原因 Error string `json:"error,omitempty"` // 命令退出码 ExitCode int `json:"exit_code"` // 命令开始执行时间 StartTime time.Time `json:"start_time"` // 命令结束执行时间 EndTime *time.Time `json:"end_time"` // 命令执行时长 Duration time.Duration `json:"duration"` // 命令执行是否成功 Success bool `json:"success"` // 是否跳过执行(跳过视为成功,但标记为 Skip 以便管道状态同步) Skipped bool `json:"skipped,omitempty"` // 非错误的说明信息(比如跳过原因等) Message string `json:"message,omitempty"` // 元数据 Metadata *CommandMetadata `json:"metadata"` // 文件内容集合 FileContents map[string]string `json:"file_contents,omitempty"` // 脚本输出参数(供下一个任务使用) OutputParams map[string]string `json:"output_params,omitempty"` }