Files
clawgo/pkg/tools/risk.go
2026-02-14 13:56:45 +08:00

94 lines
2.4 KiB
Go

package tools
import (
"regexp"
"strings"
)
type RiskLevel string
const (
RiskSafe RiskLevel = "safe"
RiskModerate RiskLevel = "moderate"
RiskDestructive RiskLevel = "destructive"
)
type RiskAssessment struct {
Level RiskLevel
Reasons []string
}
var destructivePatterns = []*regexp.Regexp{
regexp.MustCompile(`\brm\s+-rf\b`),
regexp.MustCompile(`\bmkfs(\.| )`),
regexp.MustCompile(`\bdd\s+if=`),
regexp.MustCompile(`\bshutdown\b`),
regexp.MustCompile(`\breboot\b`),
regexp.MustCompile(`\buserdel\b`),
regexp.MustCompile(`\bchown\b.+\s+/`),
regexp.MustCompile(`\bclawgo\s+uninstall\b`),
regexp.MustCompile(`\bdbt\s+drop\b`),
regexp.MustCompile(`\bgit\s+clean\b`),
}
var moderatePatterns = []*regexp.Regexp{
regexp.MustCompile(`\bgit\s+reset\s+--hard\b`),
regexp.MustCompile(`\bdocker\s+system\s+prune\b`),
regexp.MustCompile(`\bapt(-get)?\s+install\b`),
regexp.MustCompile(`\byum\s+install\b`),
regexp.MustCompile(`\bpip\s+install\b`),
}
func assessCommandRisk(command string) RiskAssessment {
cmd := strings.ToLower(strings.TrimSpace(command))
out := RiskAssessment{Level: RiskSafe, Reasons: []string{}}
for _, re := range destructivePatterns {
if re.MatchString(cmd) {
out.Level = RiskDestructive
out.Reasons = append(out.Reasons, "destructive pattern: "+re.String())
}
}
if out.Level == RiskDestructive {
return out
}
for _, re := range moderatePatterns {
if re.MatchString(cmd) {
out.Level = RiskModerate
out.Reasons = append(out.Reasons, "moderate pattern: "+re.String())
}
}
return out
}
func buildDryRunCommand(command string) (string, bool) {
trimmed := strings.TrimSpace(command)
lower := strings.ToLower(trimmed)
switch {
case strings.HasPrefix(lower, "apt ") || strings.HasPrefix(lower, "apt-get "):
if strings.Contains(lower, "--dry-run") || strings.Contains(lower, "-s ") {
return trimmed, true
}
return trimmed + " --dry-run", true
case strings.HasPrefix(lower, "yum "):
if strings.Contains(lower, "--assumeno") {
return trimmed, true
}
return trimmed + " --assumeno", true
case strings.HasPrefix(lower, "dnf "):
if strings.Contains(lower, "--assumeno") {
return trimmed, true
}
return trimmed + " --assumeno", true
case strings.HasPrefix(lower, "git clean"):
if strings.Contains(lower, "-n") || strings.Contains(lower, "--dry-run") {
return trimmed, true
}
return trimmed + " -n", true
default:
return "", false
}
}