Module: Moult::Churn
- Defined in:
- lib/moult/churn.rb
Overview
Per-file change frequency from git history. "Change" means a commit that touched the file; the count is the number of such commits within the window.
Decisions (v0.1):
* Window: the last 12 months by default ({DEFAULT_SINCE}), configurable via
+since+ (anything `git log --since` accepts, e.g. "2025-01-01"). All of
history over-weights long-lived files, so we bound it.
* Renames are NOT followed. `git log --follow` only works for a single
pathspec, so whole-repo rename tracking is out of scope; a renamed file
starts a fresh count under its new path.
* Outside a git repository, churn is empty (every file scores 0).
Paths are reported relative to the repository root, as git emits them.
Constant Summary collapse
- DEFAULT_SINCE =
"12 months ago"
Class Method Summary collapse
-
.collect(root:, since: DEFAULT_SINCE) ⇒ Hash{String=>Integer}
Path => commit count (default 0).
- .empty_counts ⇒ Object
-
.parse(output) ⇒ Hash{String=>Integer}
Pure parser over
git log --name-only --pretty=format:output.
Class Method Details
.collect(root:, since: DEFAULT_SINCE) ⇒ Hash{String=>Integer}
Returns path => commit count (default 0).
27 28 29 30 31 32 |
# File 'lib/moult/churn.rb', line 27 def collect(root:, since: DEFAULT_SINCE) output = Git.log_name_only(root, since: since) return empty_counts unless output parse(output) end |
.empty_counts ⇒ Object
48 49 50 |
# File 'lib/moult/churn.rb', line 48 def empty_counts Hash.new(0) end |
.parse(output) ⇒ Hash{String=>Integer}
Pure parser over git log --name-only --pretty=format: output. Counts how
many lines (commits) mention each path.
38 39 40 41 42 43 44 45 46 |
# File 'lib/moult/churn.rb', line 38 def parse(output) counts = empty_counts output.each_line(chomp: true) do |line| next if line.empty? counts[line] += 1 end counts end |