mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-20 18:58:31 +08:00
fix shell risk gate dry-run flow for destructive git clean
This commit is contained in:
@@ -28,11 +28,11 @@ var destructivePatterns = []*regexp.Regexp{
|
|||||||
regexp.MustCompile(`\bchown\b.+\s+/`),
|
regexp.MustCompile(`\bchown\b.+\s+/`),
|
||||||
regexp.MustCompile(`\bclawgo\s+uninstall\b`),
|
regexp.MustCompile(`\bclawgo\s+uninstall\b`),
|
||||||
regexp.MustCompile(`\bdbt\s+drop\b`),
|
regexp.MustCompile(`\bdbt\s+drop\b`),
|
||||||
|
regexp.MustCompile(`\bgit\s+clean\b`),
|
||||||
}
|
}
|
||||||
|
|
||||||
var moderatePatterns = []*regexp.Regexp{
|
var moderatePatterns = []*regexp.Regexp{
|
||||||
regexp.MustCompile(`\bgit\s+reset\s+--hard\b`),
|
regexp.MustCompile(`\bgit\s+reset\s+--hard\b`),
|
||||||
regexp.MustCompile(`\bgit\s+clean\b`),
|
|
||||||
regexp.MustCompile(`\bdocker\s+system\s+prune\b`),
|
regexp.MustCompile(`\bdocker\s+system\s+prune\b`),
|
||||||
regexp.MustCompile(`\bapt(-get)?\s+install\b`),
|
regexp.MustCompile(`\bapt(-get)?\s+install\b`),
|
||||||
regexp.MustCompile(`\byum\s+install\b`),
|
regexp.MustCompile(`\byum\s+install\b`),
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ func (t *ExecTool) applyRiskGate(command string, force bool) (string, string) {
|
|||||||
return "Error: destructive command is disabled by policy (tools.shell.risk.allow_destructive=false).", ""
|
return "Error: destructive command is disabled by policy (tools.shell.risk.allow_destructive=false).", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.riskCfg.RequireDryRun {
|
if t.riskCfg.RequireDryRun && !force {
|
||||||
if dryRunCmd, ok := buildDryRunCommand(command); ok {
|
if dryRunCmd, ok := buildDryRunCommand(command); ok {
|
||||||
return "Risk gate: dry-run required first. Review output, then execute intentionally with force=true.", dryRunCmd
|
return "Risk gate: dry-run required first. Review output, then execute intentionally with force=true.", dryRunCmd
|
||||||
}
|
}
|
||||||
|
|||||||
45
pkg/tools/shell_test.go
Normal file
45
pkg/tools/shell_test.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"clawgo/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestApplyRiskGate_DryRunCanBeBypassedWithForce(t *testing.T) {
|
||||||
|
tool := &ExecTool{riskCfg: config.RiskConfig{
|
||||||
|
Enabled: true,
|
||||||
|
AllowDestructive: true,
|
||||||
|
RequireDryRun: true,
|
||||||
|
RequireForceFlag: false,
|
||||||
|
}}
|
||||||
|
|
||||||
|
msg, dryRun := tool.applyRiskGate("git clean -fd", true)
|
||||||
|
if msg != "" || dryRun != "" {
|
||||||
|
t.Fatalf("expected force=true to allow execution after dry-run step, got msg=%q dryRun=%q", msg, dryRun)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApplyRiskGate_RequiresDryRunWithoutForce(t *testing.T) {
|
||||||
|
tool := &ExecTool{riskCfg: config.RiskConfig{
|
||||||
|
Enabled: true,
|
||||||
|
AllowDestructive: true,
|
||||||
|
RequireDryRun: true,
|
||||||
|
RequireForceFlag: false,
|
||||||
|
}}
|
||||||
|
|
||||||
|
msg, dryRun := tool.applyRiskGate("git clean -fd", false)
|
||||||
|
if msg == "" {
|
||||||
|
t.Fatal("expected dry-run block message")
|
||||||
|
}
|
||||||
|
if dryRun == "" {
|
||||||
|
t.Fatal("expected dry-run command")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssessCommandRisk_GitCleanIsDestructive(t *testing.T) {
|
||||||
|
assessment := assessCommandRisk("git clean -fd")
|
||||||
|
if assessment.Level != RiskDestructive {
|
||||||
|
t.Fatalf("expected git clean to be destructive, got %s", assessment.Level)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user