cron_types.go (1992B)
1 package jci 2 3 import ( 4 "crypto/sha1" 5 "encoding/hex" 6 "fmt" 7 "path/filepath" 8 "strings" 9 ) 10 11 type CronJobType string 12 13 const ( 14 CronJobGitJCI CronJobType = "git-jci" 15 CronJobBinary CronJobType = "binary" 16 CronJobShell CronJobType = "shell" 17 ) 18 19 type CronJob struct { 20 ID string 21 Schedule string 22 Command string 23 Type CronJobType 24 BinaryPath string 25 BinaryArgs string 26 Line int 27 CronLog string 28 } 29 30 func classifyCronCommand(command string, repoRoot string) (CronJobType, string, string) { 31 trimmed := strings.TrimSpace(command) 32 if trimmed == "" { 33 return CronJobShell, "", "" 34 } 35 36 if strings.HasPrefix(trimmed, "git jci") { 37 return CronJobGitJCI, "", "" 38 } 39 40 head, tail := splitCommandHeadTail(trimmed) 41 cleaned := strings.TrimPrefix(head, "./") 42 if strings.HasPrefix(cleaned, ".jci/") { 43 abs := filepath.Join(repoRoot, cleaned) 44 return CronJobBinary, abs, tail 45 } 46 47 if !strings.Contains(head, "/") { 48 candidate := filepath.Join(repoRoot, ".jci", head) 49 return CronJobBinary, candidate, tail 50 } 51 52 return CronJobShell, trimmed, tail 53 } 54 55 func cronJobID(schedule, command string) string { 56 sum := sha1.Sum([]byte(schedule + "\x00" + command)) 57 return hex.EncodeToString(sum[:]) 58 } 59 60 func (job CronJob) shellCommand(repoRoot string) string { 61 var command string 62 switch job.Type { 63 case CronJobBinary: 64 command = shellEscape(job.BinaryPath) 65 if job.BinaryArgs != "" { 66 command += " " + job.BinaryArgs 67 } 68 default: 69 command = job.Command 70 } 71 72 full := fmt.Sprintf("cd %s && %s", shellEscape(repoRoot), command) 73 if job.CronLog != "" { 74 full = fmt.Sprintf("%s >> %s 2>&1", full, shellEscape(job.CronLog)) 75 } 76 return full 77 } 78 79 func shellEscape(value string) string { 80 if value == "" { 81 return "''" 82 } 83 return "'" + strings.ReplaceAll(value, "'", "'\\''") + "'" 84 } 85 86 func splitCommandHeadTail(cmd string) (string, string) { 87 parts := strings.Fields(cmd) 88 if len(parts) == 0 { 89 return "", "" 90 } 91 head := parts[0] 92 tail := strings.Join(parts[1:], " ") 93 return head, tail 94 }