Fixes calculations (#2)

Git Level (per commit):
    - Track unique file paths in FilesModified slice
    - FilesChanged = count of unique files in THIS commit

  Aggregator Level (per contributor):
    - Collect all file paths from all commits into a SET
    - FilesChanged = size of the unique file set

  Result:
    - Contributor.FilesChanged = count of UNIQUE files they touched
    - Repository contributor = unique files in THAT repo only
This commit is contained in:
2025-12-19 10:44:00 +00:00
committed by GitHub
parent aedcf87338
commit 3bd9807e50
8 changed files with 420 additions and 57 deletions
+108 -2
View File
@@ -5,19 +5,22 @@ import (
)
// IsCommentLine checks if a line is a code comment (should not count as meaningful contribution)
// Note: Empty/whitespace lines are NOT comments - use IsWhitespaceLine for those.
func IsCommentLine(line string) bool {
trimmed := strings.TrimSpace(line)
if trimmed == "" {
return true // Empty lines don't count
return false // Empty lines are whitespace, not comments
}
// Common comment patterns across languages
// Order matters for overlapping prefixes (e.g., "///" before "//")
commentPrefixes := []string{
"///", // Rust/Swift/C# doc comments
"//", // C, C++, Java, Go, JS, TS, Swift, Kotlin, etc.
"#", // Python, Ruby, Shell, YAML, Perl, etc.
"/**", // JSDoc/JavaDoc block start
"/*", // 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
@@ -33,6 +36,19 @@ func IsCommentLine(line string) bool {
}
}
// C-style block comment continuation: line starts with * followed by space or end of line
// This avoids false positives like "*ptr = value" (pointer dereference)
if strings.HasPrefix(trimmed, "*") {
if len(trimmed) == 1 {
return true // Just "*" alone
}
// Must be followed by whitespace or common comment characters, not alphanumeric
nextChar := trimmed[1]
if nextChar == ' ' || nextChar == '\t' || nextChar == '/' {
return true
}
}
return false
}
@@ -64,6 +80,96 @@ func IsMeaningfulLine(line string) bool {
return !IsWhitespaceLine(line) && !IsCommentLine(line)
}
// IsDocCommentLine checks if a line is a documentation comment (JSDoc, JavaDoc, Rust doc, etc.)
// These are comments specifically meant to document code, as opposed to regular comments.
func IsDocCommentLine(line string) bool {
trimmed := strings.TrimSpace(line)
if trimmed == "" {
return false
}
// Documentation comment patterns
docPrefixes := []string{
"///", // Rust, Swift, C# doc comments
"//!", // Rust inner doc comments
"/**", // JSDoc, JavaDoc block start
"\"\"\"", // Python docstring
"'''", // Python docstring
}
for _, prefix := range docPrefixes {
if strings.HasPrefix(trimmed, prefix) {
return true
}
}
// JSDoc/JavaDoc continuation lines with annotations (@param, @return, etc.)
if strings.HasPrefix(trimmed, "* @") || strings.HasPrefix(trimmed, "* @") {
return true
}
// Check for common doc annotations at the start of a comment
if strings.HasPrefix(trimmed, "// @") || strings.HasPrefix(trimmed, "# @") {
return true
}
return false
}
// IsCommentedOutCode attempts to detect if a comment line contains commented-out code
// rather than an actual comment. This is a heuristic and may have false positives/negatives.
func IsCommentedOutCode(line string) bool {
trimmed := strings.TrimSpace(line)
if trimmed == "" {
return false
}
// Remove comment prefix to get the content
var content string
commentPrefixes := []string{"///", "//", "#", "/*", "--", ";"}
for _, prefix := range commentPrefixes {
if strings.HasPrefix(trimmed, prefix) {
content = strings.TrimSpace(trimmed[len(prefix):])
break
}
}
if content == "" {
return false
}
// Heuristics for detecting commented-out code:
// 1. Ends with common code patterns
codeEndings := []string{";", "{", "}", ")", ",", ":", "=>", "->"}
for _, ending := range codeEndings {
if strings.HasSuffix(content, ending) {
return true
}
}
// 2. Starts with common code keywords
codeKeywords := []string{
"if ", "else ", "for ", "while ", "switch ", "case ", "return ", "break", "continue",
"const ", "let ", "var ", "func ", "function ", "def ", "class ", "struct ", "type ",
"import ", "from ", "package ", "public ", "private ", "protected ", "static ",
"async ", "await ", "try ", "catch ", "throw ", "raise ",
}
contentLower := strings.ToLower(content)
for _, keyword := range codeKeywords {
if strings.HasPrefix(contentLower, keyword) {
return true
}
}
// 3. Contains assignment operators
if strings.Contains(content, " = ") || strings.Contains(content, " := ") ||
strings.Contains(content, " == ") || strings.Contains(content, " != ") {
return true
}
return false
}
// IsRenameOrMove checks if a file change represents a rename or move operation
// rather than actual content modification. A rename/move is detected when both
// the source (fromName) and destination (toName) paths exist and differ.