mirror of
https://github.com/cexll/myclaude.git
synced 2026-02-05 02:30:26 +08:00
- Move all source files to internal/{app,backend,config,executor,logger,parser,utils}
- Integrate third-party libraries: zerolog, goccy/go-json, gopsutil, cobra/viper
- Add comprehensive unit tests for utils package (94.3% coverage)
- Add performance benchmarks for string operations
- Fix error display: cleanup warnings no longer pollute Recent Errors
- Add GitHub Actions CI workflow
- Add Makefile for build automation
- Add README documentation
Generated with SWE-Agent.ai
Co-Authored-By: SWE-Agent.ai <noreply@swe-agent.ai>
105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package executor
|
|
|
|
import "strings"
|
|
|
|
// extractCoverageGap extracts what's missing from coverage reports.
|
|
func extractCoverageGap(message string) string {
|
|
if message == "" {
|
|
return ""
|
|
}
|
|
|
|
lower := strings.ToLower(message)
|
|
lines := strings.Split(message, "\n")
|
|
|
|
for _, line := range lines {
|
|
lineLower := strings.ToLower(line)
|
|
line = strings.TrimSpace(line)
|
|
|
|
if strings.Contains(lineLower, "uncovered") ||
|
|
strings.Contains(lineLower, "not covered") ||
|
|
strings.Contains(lineLower, "missing coverage") ||
|
|
strings.Contains(lineLower, "lines not covered") {
|
|
if len(line) > 100 {
|
|
return line[:97] + "..."
|
|
}
|
|
return line
|
|
}
|
|
|
|
if strings.Contains(lineLower, "branch") && strings.Contains(lineLower, "not taken") {
|
|
if len(line) > 100 {
|
|
return line[:97] + "..."
|
|
}
|
|
return line
|
|
}
|
|
}
|
|
|
|
if strings.Contains(lower, "function") && strings.Contains(lower, "0%") {
|
|
for _, line := range lines {
|
|
if strings.Contains(strings.ToLower(line), "0%") && strings.Contains(line, "function") {
|
|
line = strings.TrimSpace(line)
|
|
if len(line) > 100 {
|
|
return line[:97] + "..."
|
|
}
|
|
return line
|
|
}
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// extractErrorDetail extracts meaningful error context from task output.
|
|
func extractErrorDetail(message string, maxLen int) string {
|
|
if message == "" || maxLen <= 0 {
|
|
return ""
|
|
}
|
|
|
|
lines := strings.Split(message, "\n")
|
|
var errorLines []string
|
|
|
|
for _, line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
|
|
lower := strings.ToLower(line)
|
|
|
|
if strings.HasPrefix(line, "at ") && strings.Contains(line, "(") {
|
|
if len(errorLines) > 0 && strings.HasPrefix(strings.ToLower(errorLines[len(errorLines)-1]), "at ") {
|
|
continue
|
|
}
|
|
}
|
|
|
|
if strings.Contains(lower, "error") ||
|
|
strings.Contains(lower, "fail") ||
|
|
strings.Contains(lower, "exception") ||
|
|
strings.Contains(lower, "assert") ||
|
|
strings.Contains(lower, "expected") ||
|
|
strings.Contains(lower, "timeout") ||
|
|
strings.Contains(lower, "not found") ||
|
|
strings.Contains(lower, "cannot") ||
|
|
strings.Contains(lower, "undefined") ||
|
|
strings.HasPrefix(line, "FAIL") ||
|
|
strings.HasPrefix(line, "●") {
|
|
errorLines = append(errorLines, line)
|
|
}
|
|
}
|
|
|
|
if len(errorLines) == 0 {
|
|
start := len(lines) - 5
|
|
if start < 0 {
|
|
start = 0
|
|
}
|
|
for _, line := range lines[start:] {
|
|
line = strings.TrimSpace(line)
|
|
if line != "" {
|
|
errorLines = append(errorLines, line)
|
|
}
|
|
}
|
|
}
|
|
|
|
result := strings.Join(errorLines, " | ")
|
|
return safeTruncate(result, maxLen)
|
|
}
|