feat(processor): integrate config-based comment preservation in git mode
- Load .shush.toml configuration for pattern-based comment preservation - Add preserved comment tracking and display in dry-run output - Enhance preview with cyan 'P' indicators for preserved comments - Add preserved count to summary statistics and totals - Support both line and block comment preservation based on patterns
This commit is contained in:
@@ -6,19 +6,19 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/carlosarraes/shush/internal/config"
|
||||
"github.com/carlosarraes/shush/internal/git"
|
||||
"github.com/carlosarraes/shush/internal/types"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
|
||||
type GitTotals struct {
|
||||
FilesProcessed int
|
||||
TotalChanged int
|
||||
TotalKept int
|
||||
TotalPreserved int
|
||||
}
|
||||
|
||||
|
||||
func (p *Processor) processGitChanges() error {
|
||||
|
||||
gitStatus, err := git.DetectRepo()
|
||||
@@ -34,7 +34,6 @@ func (p *Processor) processGitChanges() error {
|
||||
fmt.Printf("Git repository detected: %s\n", gitStatus.RootDir)
|
||||
}
|
||||
|
||||
|
||||
var changes []git.FileChange
|
||||
switch {
|
||||
case p.cli.ChangesOnly:
|
||||
@@ -59,21 +58,28 @@ func (p *Processor) processGitChanges() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
supportedChanges := make([]git.FileChange, 0, len(changes))
|
||||
for _, change := range changes {
|
||||
if IsSupportedFile(change.Path) {
|
||||
supportedChanges = append(supportedChanges, change)
|
||||
} else if p.cli.Verbose {
|
||||
fmt.Printf("Skipping unsupported file: %s\n", change.Path)
|
||||
}
|
||||
}
|
||||
|
||||
if len(supportedChanges) == 0 {
|
||||
fmt.Println("No supported files found to process")
|
||||
return nil
|
||||
}
|
||||
|
||||
if p.cli.Verbose {
|
||||
fmt.Printf("Found %d files with changes to process\n", len(changes))
|
||||
fmt.Printf("Found %d supported files with changes to process\n", len(supportedChanges))
|
||||
}
|
||||
|
||||
totals := &GitTotals{}
|
||||
|
||||
|
||||
for _, change := range changes {
|
||||
|
||||
if !IsSupportedFile(change.Path) {
|
||||
if p.cli.Verbose {
|
||||
fmt.Printf("Skipping unsupported file: %s\n", change.Path)
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, change := range supportedChanges {
|
||||
|
||||
if p.cli.Verbose {
|
||||
fmt.Printf("Processing: %s\n", change.Path)
|
||||
@@ -93,7 +99,6 @@ func (p *Processor) processGitChanges() error {
|
||||
totals.FilesProcessed++
|
||||
}
|
||||
|
||||
|
||||
if p.cli.DryRun && totals.FilesProcessed > 0 {
|
||||
p.showGitTotals(totals)
|
||||
}
|
||||
@@ -101,13 +106,19 @@ func (p *Processor) processGitChanges() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (p *Processor) processFileWithLineRanges(filename string, lineRanges []git.LineRange) error {
|
||||
language, err := DetectLanguage(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
cfg, _, err := config.Load()
|
||||
if err != nil && p.cli.Verbose {
|
||||
fmt.Printf("Warning: failed to load config, using defaults: %v\n", err)
|
||||
cfg = config.Default()
|
||||
}
|
||||
|
||||
if p.cli.Verbose {
|
||||
fmt.Printf("Processing %s (language: %s)\n", filename, GetLanguageName(filename))
|
||||
if len(lineRanges) == 0 {
|
||||
@@ -117,9 +128,6 @@ func (p *Processor) processFileWithLineRanges(filename string, lineRanges []git.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -136,7 +144,6 @@ func (p *Processor) processFileWithLineRanges(filename string, lineRanges []git.
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if p.cli.Backup {
|
||||
if err := p.createBackup(filename); err != nil {
|
||||
return fmt.Errorf("failed to create backup: %v", err)
|
||||
@@ -146,8 +153,7 @@ func (p *Processor) processFileWithLineRanges(filename string, lineRanges []git.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
processEntireFile := len(lineRanges) == 0
|
||||
processEntireFile := len(lineRanges) == 0
|
||||
modified := false
|
||||
|
||||
for i, line := range lines {
|
||||
@@ -155,7 +161,7 @@ processEntireFile := len(lineRanges) == 0
|
||||
shouldProcess := processEntireFile || git.IsInLineRanges(lineNum, lineRanges)
|
||||
|
||||
if shouldProcess {
|
||||
newLine := p.removeCommentsFromLine(line, language)
|
||||
newLine := p.removeCommentsFromLine(line, language, cfg)
|
||||
if newLine != line {
|
||||
lines[i] = newLine
|
||||
modified = true
|
||||
@@ -163,7 +169,6 @@ processEntireFile := len(lineRanges) == 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if modified {
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
@@ -187,24 +192,28 @@ processEntireFile := len(lineRanges) == 0
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (p *Processor) removeCommentsFromLine(line string, language types.Language) string {
|
||||
func (p *Processor) removeCommentsFromLine(line string, language types.Language, cfg *config.Config) string {
|
||||
result := line
|
||||
hasChanges := false
|
||||
|
||||
|
||||
if !p.cli.Block && language.LineComment != "" {
|
||||
|
||||
if idx := strings.Index(result, language.LineComment); idx != -1 {
|
||||
|
||||
comment := strings.TrimSpace(result[idx:])
|
||||
|
||||
|
||||
if cfg.ShouldPreserveComment(comment) {
|
||||
return line
|
||||
}
|
||||
|
||||
result = result[:idx]
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !p.cli.Inline && language.BlockComment != nil {
|
||||
|
||||
|
||||
startComment := language.BlockComment.Start
|
||||
endComment := language.BlockComment.End
|
||||
|
||||
@@ -217,18 +226,28 @@ func (p *Processor) removeCommentsFromLine(line string, language types.Language)
|
||||
endIdx := strings.Index(result[startIdx:], endComment)
|
||||
if endIdx == -1 {
|
||||
|
||||
comment := strings.TrimSpace(result[startIdx:])
|
||||
if cfg.ShouldPreserveComment(comment) {
|
||||
return line
|
||||
}
|
||||
|
||||
result = result[:startIdx]
|
||||
hasChanges = true
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
blockComment := strings.TrimSpace(result[startIdx:startIdx+endIdx+len(endComment)])
|
||||
if cfg.ShouldPreserveComment(blockComment) {
|
||||
return line
|
||||
}
|
||||
|
||||
endIdx += startIdx + len(endComment)
|
||||
result = result[:startIdx] + result[endIdx:]
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if hasChanges {
|
||||
result = strings.TrimSpace(result)
|
||||
}
|
||||
@@ -236,13 +255,18 @@ func (p *Processor) removeCommentsFromLine(line string, language types.Language)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
func (p *Processor) showGitPreviewWithTotals(filename string, lineRanges []git.LineRange, totals *GitTotals) error {
|
||||
language, err := DetectLanguage(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
cfg, _, err := config.Load()
|
||||
if err != nil {
|
||||
cfg = config.Default()
|
||||
}
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -267,6 +291,7 @@ func (p *Processor) showGitPreviewWithTotals(filename string, lineRanges []git.L
|
||||
lineNum := 0
|
||||
keptCount := 0
|
||||
changedCount := 0
|
||||
preservedCount := 0
|
||||
|
||||
processEntireFile := len(lineRanges) == 0
|
||||
|
||||
@@ -278,7 +303,7 @@ func (p *Processor) showGitPreviewWithTotals(filename string, lineRanges []git.L
|
||||
lineNumStr := gray.Sprintf("%4d", lineNum)
|
||||
|
||||
if shouldProcess {
|
||||
newLine := p.removeCommentsFromLine(line, language)
|
||||
newLine := p.removeCommentsFromLine(line, language, cfg)
|
||||
if newLine != line {
|
||||
changedCount++
|
||||
fmt.Printf("%s %s %s\n", lineNumStr, red.Sprint("~"), red.Sprint(line))
|
||||
@@ -286,8 +311,16 @@ func (p *Processor) showGitPreviewWithTotals(filename string, lineRanges []git.L
|
||||
fmt.Printf("%s %s %s\n", lineNumStr, green.Sprint("+"), green.Sprint(newLine))
|
||||
}
|
||||
} else {
|
||||
keptCount++
|
||||
fmt.Printf("%s %s %s\n", lineNumStr, green.Sprint(" "), line)
|
||||
// Check if this line has comments that were preserved
|
||||
hasComment := p.lineHasComment(line, language)
|
||||
if hasComment {
|
||||
preservedCount++
|
||||
cyan := color.New(color.FgCyan)
|
||||
fmt.Printf("%s %s %s\n", lineNumStr, cyan.Sprint("P"), line)
|
||||
} else {
|
||||
keptCount++
|
||||
fmt.Printf("%s %s %s\n", lineNumStr, green.Sprint(" "), line)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
keptCount++
|
||||
@@ -301,20 +334,42 @@ func (p *Processor) showGitPreviewWithTotals(filename string, lineRanges []git.L
|
||||
|
||||
fmt.Printf("\n%s\n", strings.Repeat("-", 50))
|
||||
fmt.Printf("%s %d lines would be changed\n", yellow.Sprint("~"), changedCount)
|
||||
fmt.Printf("%s %d lines would be kept\n\n", green.Sprint("✓"), keptCount)
|
||||
|
||||
fmt.Printf("%s %d lines would be kept\n", green.Sprint("✓"), keptCount)
|
||||
if preservedCount > 0 {
|
||||
cyan := color.New(color.FgCyan)
|
||||
fmt.Printf("%s %d comments would be preserved\n", cyan.Sprint("P"), preservedCount)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
totals.TotalChanged += changedCount
|
||||
totals.TotalKept += keptCount
|
||||
totals.TotalPreserved += preservedCount
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// lineHasComment checks if a line contains comments
|
||||
func (p *Processor) lineHasComment(line string, language types.Language) bool {
|
||||
// Check for line comments
|
||||
if language.LineComment != "" && strings.Contains(line, language.LineComment) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check for block comments
|
||||
if language.BlockComment != nil {
|
||||
if strings.Contains(line, language.BlockComment.Start) || strings.Contains(line, language.BlockComment.End) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Processor) showGitTotals(totals *GitTotals) {
|
||||
yellow := color.New(color.FgYellow)
|
||||
green := color.New(color.FgGreen)
|
||||
blue := color.New(color.FgBlue)
|
||||
cyan := color.New(color.FgCyan)
|
||||
|
||||
fmt.Printf("\n%s\n", strings.Repeat("=", 60))
|
||||
fmt.Printf("%s\n", blue.Sprint("GIT PROCESSING TOTALS"))
|
||||
@@ -322,5 +377,8 @@ func (p *Processor) showGitTotals(totals *GitTotals) {
|
||||
fmt.Printf("%s %d files processed\n", blue.Sprint("📁"), totals.FilesProcessed)
|
||||
fmt.Printf("%s %d lines would be changed\n", yellow.Sprint("~"), totals.TotalChanged)
|
||||
fmt.Printf("%s %d lines would be kept\n", green.Sprint("✓"), totals.TotalKept)
|
||||
if totals.TotalPreserved > 0 {
|
||||
fmt.Printf("%s %d comments would be preserved\n", cyan.Sprint("P"), totals.TotalPreserved)
|
||||
}
|
||||
fmt.Printf("%s\n", strings.Repeat("=", 60))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user