feat: security hardening, tests, doctor command, CI update, CHANGELOG
All checks were successful
CI / build (push) Successful in 2m37s
All checks were successful
CI / build (push) Successful in 2m37s
- Add AES-256-GCM encryption for API keys (internal/secret) - Add dangerous command detection in terminal - Add muyue doctor command for system health checks - Add scanner TTL cache, orchestrator history mutex, shared HTTP client - Deduplicate MCP config generation, refactor skills YAML parser - Add XDG-compliant config dir with legacy migration - Add cleanup on all TUI quit paths - Add 8 test files (config, workflow, skills, orchestrator, version, platform, scanner, secret) - Update CI to actions/setup-go@v5 - Add CHANGELOG.md, update README and Makefile 🤖 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/muyue/muyue/internal/platform"
|
||||
)
|
||||
@@ -34,7 +36,40 @@ type ScanResult struct {
|
||||
GitConfigured bool `yaml:"git_configured"`
|
||||
}
|
||||
|
||||
var (
|
||||
cacheMu sync.RWMutex
|
||||
cacheResult *ScanResult
|
||||
cacheTime time.Time
|
||||
cacheTTL = 5 * time.Minute
|
||||
)
|
||||
|
||||
func ScanSystem() *ScanResult {
|
||||
cacheMu.RLock()
|
||||
if cacheResult != nil && time.Since(cacheTime) < cacheTTL {
|
||||
result := cacheResult
|
||||
cacheMu.RUnlock()
|
||||
return result
|
||||
}
|
||||
cacheMu.RUnlock()
|
||||
|
||||
result := doScan()
|
||||
|
||||
cacheMu.Lock()
|
||||
cacheResult = result
|
||||
cacheTime = time.Now()
|
||||
cacheMu.Unlock()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func InvalidateCache() {
|
||||
cacheMu.Lock()
|
||||
cacheResult = nil
|
||||
cacheTime = time.Time{}
|
||||
cacheMu.Unlock()
|
||||
}
|
||||
|
||||
func doScan() *ScanResult {
|
||||
info := platform.Detect()
|
||||
result := &ScanResult{
|
||||
System: info,
|
||||
|
||||
76
internal/scanner/scanner_test.go
Normal file
76
internal/scanner/scanner_test.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScanSystem(t *testing.T) {
|
||||
InvalidateCache()
|
||||
result := ScanSystem()
|
||||
if result == nil {
|
||||
t.Fatal("ScanSystem should not return nil")
|
||||
}
|
||||
if result.System.OS == "" {
|
||||
t.Error("System OS should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanTools(t *testing.T) {
|
||||
tools := scanTools()
|
||||
if len(tools) == 0 {
|
||||
t.Error("Should scan at least some tools")
|
||||
}
|
||||
for _, tool := range tools {
|
||||
if tool.Name == "" {
|
||||
t.Error("Tool name should not be empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanRuntimes(t *testing.T) {
|
||||
runtimes := scanRuntimes()
|
||||
if len(runtimes) == 0 {
|
||||
t.Error("Should scan at least some runtimes")
|
||||
}
|
||||
for _, r := range runtimes {
|
||||
if r.Name == "" {
|
||||
t.Error("Runtime name should not be empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckGitConfig(t *testing.T) {
|
||||
_ = checkGitConfig()
|
||||
}
|
||||
|
||||
func TestCheckShellSetup(t *testing.T) {
|
||||
_ = checkShellSetup()
|
||||
}
|
||||
|
||||
func TestSummary(t *testing.T) {
|
||||
InvalidateCache()
|
||||
result := ScanSystem()
|
||||
summary := result.Summary()
|
||||
if summary == "" {
|
||||
t.Error("Summary should not be empty")
|
||||
}
|
||||
if !strings.Contains(summary, "System:") {
|
||||
t.Error("Summary should contain System:")
|
||||
}
|
||||
if !strings.Contains(summary, "Tools:") {
|
||||
t.Error("Summary should contain Tools:")
|
||||
}
|
||||
if !strings.Contains(summary, "Runtimes:") {
|
||||
t.Error("Summary should contain Runtimes:")
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanCache(t *testing.T) {
|
||||
InvalidateCache()
|
||||
r1 := ScanSystem()
|
||||
r2 := ScanSystem()
|
||||
if r1 != r2 {
|
||||
t.Error("Cached result should be the same pointer")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user