mirror of
https://github.com/lukaszraczylo/git-velocity.git
synced 2026-06-06 22:49:27 +00:00
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package diff
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// IsCommentLine checks if a line is a code comment (should not count as meaningful contribution)
|
|
func IsCommentLine(line string) bool {
|
|
trimmed := strings.TrimSpace(line)
|
|
if trimmed == "" {
|
|
return true // Empty lines don't count
|
|
}
|
|
|
|
// Common comment patterns across languages
|
|
commentPrefixes := []string{
|
|
"//", // C, C++, Java, Go, JS, TS, Swift, Kotlin, etc.
|
|
"#", // Python, Ruby, Shell, YAML, Perl, etc.
|
|
"/*", // C-style block comment start
|
|
"*/", // C-style block comment end
|
|
"*", // C-style block comment continuation
|
|
"<!--", // HTML/XML comment
|
|
"-->", // HTML/XML comment end
|
|
"--", // SQL, Lua, Haskell
|
|
";", // Assembly, Lisp, INI files
|
|
"'", // VB comment
|
|
"\"\"\"", // Python docstring
|
|
"'''", // Python docstring
|
|
}
|
|
|
|
for _, prefix := range commentPrefixes {
|
|
if strings.HasPrefix(trimmed, prefix) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// IsWhitespaceLine checks if a line contains only whitespace characters
|
|
func IsWhitespaceLine(line string) bool {
|
|
return strings.TrimSpace(line) == ""
|
|
}
|
|
|
|
// IsDocumentationFile checks if a file is documentation-only
|
|
func IsDocumentationFile(filename string) bool {
|
|
// Documentation file extensions and patterns
|
|
docPatterns := []string{
|
|
".md", ".markdown", ".rst", ".txt", ".adoc",
|
|
"README", "CHANGELOG", "LICENSE", "CONTRIBUTING",
|
|
"docs/", "documentation/", "/doc/",
|
|
}
|
|
|
|
lowerFilename := strings.ToLower(filename)
|
|
for _, pattern := range docPatterns {
|
|
if strings.Contains(lowerFilename, strings.ToLower(pattern)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// PatchStats holds the results of analyzing a diff patch
|
|
type PatchStats struct {
|
|
TotalAdditions int
|
|
TotalDeletions int
|
|
MeaningfulAdditions int
|
|
MeaningfulDeletions int
|
|
CommentAdditions int
|
|
CommentDeletions int
|
|
WhitespaceAdditions int
|
|
WhitespaceDeletions int
|
|
}
|
|
|
|
// AnalyzePatch analyzes a unified diff patch and returns both raw and meaningful line counts.
|
|
// It parses diff hunks and categorizes each changed line as meaningful, comment, or whitespace.
|
|
func AnalyzePatch(patch string) PatchStats {
|
|
stats := PatchStats{}
|
|
|
|
lines := strings.Split(patch, "\n")
|
|
for _, line := range lines {
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
|
|
// Check if this is an addition or deletion line
|
|
isAddition := strings.HasPrefix(line, "+") && !strings.HasPrefix(line, "+++")
|
|
isDeletion := strings.HasPrefix(line, "-") && !strings.HasPrefix(line, "---")
|
|
|
|
if !isAddition && !isDeletion {
|
|
continue // Context line or header
|
|
}
|
|
|
|
// Remove the diff prefix to get actual content
|
|
content := line[1:]
|
|
|
|
// Categorize the line
|
|
if IsWhitespaceLine(content) {
|
|
if isAddition {
|
|
stats.TotalAdditions++
|
|
stats.WhitespaceAdditions++
|
|
} else {
|
|
stats.TotalDeletions++
|
|
stats.WhitespaceDeletions++
|
|
}
|
|
} else if IsCommentLine(content) {
|
|
if isAddition {
|
|
stats.TotalAdditions++
|
|
stats.CommentAdditions++
|
|
} else {
|
|
stats.TotalDeletions++
|
|
stats.CommentDeletions++
|
|
}
|
|
} else {
|
|
// Meaningful code line
|
|
if isAddition {
|
|
stats.TotalAdditions++
|
|
stats.MeaningfulAdditions++
|
|
} else {
|
|
stats.TotalDeletions++
|
|
stats.MeaningfulDeletions++
|
|
}
|
|
}
|
|
}
|
|
|
|
return stats
|
|
}
|
|
|
|
// AnalyzePatchSimple returns just the meaningful additions and deletions
|
|
func AnalyzePatchSimple(patch string) (meaningfulAdds, meaningfulDels int) {
|
|
stats := AnalyzePatch(patch)
|
|
return stats.MeaningfulAdditions, stats.MeaningfulDeletions
|
|
}
|
|
|
|
// IsMeaningfulLine checks if a line of code is meaningful (not a comment or whitespace)
|
|
func IsMeaningfulLine(line string) bool {
|
|
return !IsWhitespaceLine(line) && !IsCommentLine(line)
|
|
}
|