git_fame 2.5.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/exe/git-fame +9 -0
- data/lib/git_fame/author.rb +5 -75
- data/lib/git_fame/base.rb +9 -523
- data/lib/git_fame/collector.rb +45 -0
- data/lib/git_fame/command.rb +159 -0
- data/lib/git_fame/contribution.rb +12 -0
- data/lib/git_fame/diff.rb +25 -0
- data/lib/git_fame/error.rb +5 -0
- data/lib/git_fame/extension.rb +16 -0
- data/lib/git_fame/filter.rb +43 -0
- data/lib/git_fame/render/extension.rb +26 -0
- data/lib/git_fame/render.rb +38 -0
- data/lib/git_fame/result.rb +29 -4
- data/lib/git_fame/types.rb +11 -0
- data/lib/git_fame/version.rb +3 -1
- data/lib/git_fame.rb +16 -3
- metadata +79 -114
- data/.gitignore +0 -20
- data/.gitmodules +0 -3
- data/.rspec +0 -7
- data/.travis.yml +0 -16
- data/Gemfile +0 -4
- data/LICENSE +0 -22
- data/README.md +0 -140
- data/Rakefile +0 -15
- data/bin/git-fame +0 -58
- data/git_fame.gemspec +0 -42
- data/lib/git_fame/blame_parser.rb +0 -83
- data/lib/git_fame/commit_range.rb +0 -27
- data/lib/git_fame/errors.rb +0 -6
- data/lib/git_fame/file.rb +0 -13
- data/lib/git_fame/helper.rb +0 -11
- data/lib/git_fame/silent_progressbar.rb +0 -20
- data/spec/bin_spec.rb +0 -116
- data/spec/git_fame_spec.rb +0 -488
- data/spec/spec_helper.rb +0 -65
- data/spec/support/startup.rb +0 -21
data/git_fame.gemspec
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('../lib/git_fame/version', __FILE__)
|
3
|
-
|
4
|
-
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Linus Oleander"]
|
6
|
-
gem.email = ["linus@oleander.nu"]
|
7
|
-
gem.description = "A command-line tool that helps you summarize and pretty-print collaborators in a git repository based on contributions"
|
8
|
-
gem.summary = %q{
|
9
|
-
git-fame is a command-line tool that helps you summarize and pretty-print collaborators in a git repository based on contributions. A Ruby wrapper for git-blame if you will.
|
10
|
-
|
11
|
-
Generates stats like:
|
12
|
-
- Number of files changed by a user
|
13
|
-
- Number of commits by user
|
14
|
-
- Lines of code by a user}
|
15
|
-
|
16
|
-
gem.homepage = "http://oleander.io/git-fame-rb"
|
17
|
-
|
18
|
-
gem.files = `git ls-files`.split($\)
|
19
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
20
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
-
gem.name = "git_fame"
|
22
|
-
gem.require_paths = ["lib"]
|
23
|
-
gem.version = GitFame::VERSION
|
24
|
-
|
25
|
-
gem.add_dependency("progressbar", "~> 0.21.0")
|
26
|
-
gem.add_dependency("trollop", "~> 2.1.2")
|
27
|
-
gem.add_dependency("hirb", "~> 0.7.3")
|
28
|
-
gem.add_dependency("scrub_rb", "~> 1.0.1")
|
29
|
-
gem.add_dependency("memoist", "~> 0.14.0")
|
30
|
-
gem.add_dependency("method_profiler", "~> 2.0.1")
|
31
|
-
|
32
|
-
gem.add_development_dependency("rspec", "~> 3.4.0")
|
33
|
-
gem.add_development_dependency("rspec-collection_matchers", "~> 1.1.2")
|
34
|
-
gem.add_development_dependency("rake", "~> 10.4.2")
|
35
|
-
gem.add_development_dependency("coveralls", "~> 0.8.1")
|
36
|
-
gem.add_development_dependency("json", "~> 1.8.3")
|
37
|
-
gem.add_development_dependency("tins", "~> 1.6.0")
|
38
|
-
gem.add_development_dependency("term-ansicolor", "~> 1.3.2")
|
39
|
-
gem.add_development_dependency("colorize")
|
40
|
-
|
41
|
-
gem.required_ruby_version = ">= 1.9.2"
|
42
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# Extracted from the dolt gem. Currently not maintained.
|
2
|
-
# Source: https://docs.omniref.com/ruby/gems/libdolt/0.33.14/symbols/Dolt::Git::Blame::PorcelainParser
|
3
|
-
module GitFame
|
4
|
-
class BlameParser
|
5
|
-
def initialize(output)
|
6
|
-
@output = output
|
7
|
-
@commits = {}
|
8
|
-
end
|
9
|
-
def parse
|
10
|
-
lines = @output.split("\n")
|
11
|
-
chunks = []
|
12
|
-
while lines.length > 0
|
13
|
-
chunk = extract_header(lines)
|
14
|
-
affected_lines = extract_lines(lines, chunk[:num_lines])
|
15
|
-
if chunks.last && chunk[:oid] == chunks.last[:oid]
|
16
|
-
chunks.last[:lines].concat(affected_lines)
|
17
|
-
else
|
18
|
-
chunk[:lines] = affected_lines
|
19
|
-
chunks << chunk
|
20
|
-
end
|
21
|
-
end
|
22
|
-
chunks
|
23
|
-
rescue Exception => error
|
24
|
-
raise Error, "Failed parsing Procelain: #{error.message}"
|
25
|
-
end
|
26
|
-
|
27
|
-
def is_header?(line)
|
28
|
-
line =~ /^[0-9a-f]{40} \d+ \d+ \d+$/
|
29
|
-
end
|
30
|
-
|
31
|
-
def extract_header(lines)
|
32
|
-
header = lines.shift
|
33
|
-
pieces = header.scan(/^([0-9a-f]{40}) (\d+) (\d+) (\d+)$/).first
|
34
|
-
header = { :oid => pieces.first, :num_lines => pieces[3].to_i }
|
35
|
-
if lines.first =~ /^author/
|
36
|
-
header[:author] = extract_hash(lines, :author)
|
37
|
-
header[:committer] = extract_hash(lines, :committer)
|
38
|
-
header[:summary] = extract(lines, "summary")
|
39
|
-
header[:boundary] = extract(lines, "boundary")
|
40
|
-
throwaway = lines.shift until throwaway =~ /^filename/
|
41
|
-
@commits[header[:oid]] = header
|
42
|
-
else
|
43
|
-
header[:author] = @commits[header[:oid]][:author]
|
44
|
-
header[:committer] = @commits[header[:oid]][:committer]
|
45
|
-
header[:summary] = @commits[header[:oid]][:summary]
|
46
|
-
end
|
47
|
-
header
|
48
|
-
end
|
49
|
-
|
50
|
-
def extract_lines(lines, num)
|
51
|
-
extracted = []
|
52
|
-
num.times do
|
53
|
-
if extracted.length > 0
|
54
|
-
line = lines.shift # Header for next line
|
55
|
-
end
|
56
|
-
content = lines.shift # Actual content
|
57
|
-
next unless content
|
58
|
-
extracted.push(content[1..content.length]) # 8 spaces padding
|
59
|
-
end
|
60
|
-
extracted
|
61
|
-
end
|
62
|
-
|
63
|
-
def extract_hash(lines, type)
|
64
|
-
{
|
65
|
-
:name => extract(lines, "#{type}"),
|
66
|
-
:mail => extract(lines, "#{type}-mail").gsub(/[<>]/, ""),
|
67
|
-
:time => (Time.at(extract(lines, "#{type}-time").to_i).utc +
|
68
|
-
Time.zone_offset(extract(lines, "#{type}-tz")))
|
69
|
-
}
|
70
|
-
end
|
71
|
-
def extract(lines, thing)
|
72
|
-
if thing == "boundary"
|
73
|
-
if (line = lines.shift) == thing
|
74
|
-
return true
|
75
|
-
else
|
76
|
-
return ! lines.unshift(line)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
lines.shift.split("#{thing} ")[1]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
class CommitRange < Struct.new(:data, :current_branch)
|
2
|
-
SHORT_LENGTH = 7
|
3
|
-
|
4
|
-
def to_s(short = false)
|
5
|
-
@_to_s ||= range.map do |commit|
|
6
|
-
short ? shorten(commit) : commit
|
7
|
-
end.join("..")
|
8
|
-
end
|
9
|
-
|
10
|
-
def is_range?
|
11
|
-
data.is_a?(Array)
|
12
|
-
end
|
13
|
-
|
14
|
-
def range
|
15
|
-
is_range? ? data : [data]
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def branch?(commit)
|
21
|
-
current_branch == commit
|
22
|
-
end
|
23
|
-
|
24
|
-
def shorten(commit)
|
25
|
-
branch?(commit) ? commit : commit[0..SHORT_LENGTH]
|
26
|
-
end
|
27
|
-
end
|
data/lib/git_fame/errors.rb
DELETED
data/lib/git_fame/file.rb
DELETED
data/lib/git_fame/helper.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
module GitFame
|
2
|
-
module Helper
|
3
|
-
#
|
4
|
-
# @value Fixnum Value to be formated
|
5
|
-
# @return String Formated according ActionView::Helpers::NumberHelper.number_with_delimiter
|
6
|
-
#
|
7
|
-
def number_with_delimiter(value)
|
8
|
-
value.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require "progressbar"
|
2
|
-
|
3
|
-
class SilentProgressbar
|
4
|
-
#
|
5
|
-
# @name String Name for progressbar
|
6
|
-
# @steps Fixnum Total number of steps
|
7
|
-
# @active Should progressbar be visible?
|
8
|
-
#
|
9
|
-
def initialize(name, steps, active = false)
|
10
|
-
@bp = ProgressBar.new(name, steps) if active
|
11
|
-
end
|
12
|
-
|
13
|
-
def finish
|
14
|
-
@bp && @bp.finish
|
15
|
-
end
|
16
|
-
|
17
|
-
def increment
|
18
|
-
@bp && @bp.inc
|
19
|
-
end
|
20
|
-
end
|
data/spec/bin_spec.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
describe "bin/git-fame" do
|
2
|
-
it "should include the authors name" do
|
3
|
-
run("--help").should include_output("Linus Oleander")
|
4
|
-
end
|
5
|
-
|
6
|
-
it "should include the the current version" do
|
7
|
-
run("--version").should include_output(GitFame::VERSION)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should fail on invalid option" do
|
11
|
-
run("--nope").should_not be_a_succees
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should not accept a non-existent repository" do
|
15
|
-
run("--repository=??").should_not be_a_succees
|
16
|
-
end
|
17
|
-
|
18
|
-
[
|
19
|
-
"--sort=name",
|
20
|
-
"--sort=commits",
|
21
|
-
"--sort=loc",
|
22
|
-
"--hide-progressbar",
|
23
|
-
"--whitespace",
|
24
|
-
"--by-type",
|
25
|
-
"--include=hello",
|
26
|
-
"--exclude=hello",
|
27
|
-
"--extension=rb,ln",
|
28
|
-
"--branch=master",
|
29
|
-
"--format=csv",
|
30
|
-
"--format=pretty",
|
31
|
-
"--before=2010-01-01",
|
32
|
-
"--after=1980-01-01",
|
33
|
-
"--version",
|
34
|
-
"--help",
|
35
|
-
"--verbose",
|
36
|
-
"--everything",
|
37
|
-
"--timeout=10",
|
38
|
-
"--timeout=-1"
|
39
|
-
].each do |option|
|
40
|
-
it "should support #{option}" do
|
41
|
-
run(option).should be_a_succees
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should sort by loc by default" do
|
46
|
-
run("--sort=loc", "--progressbar=0").first.should eq(run("--progressbar=0").first)
|
47
|
-
end
|
48
|
-
|
49
|
-
context "dates" do
|
50
|
-
it "should fail on invalid before date" do
|
51
|
-
res = run("--before='---'")
|
52
|
-
res.should_not be_a_succees
|
53
|
-
res.should include_output("'---' is not a valid date")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should fail on invalid after date" do
|
57
|
-
res = run("--after='---'")
|
58
|
-
res.should_not be_a_succees
|
59
|
-
res.should include_output("'---' is not a valid date")
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should not print stack trace on invalid dates (--after)" do
|
63
|
-
res = run("--after='---'")
|
64
|
-
res.should_not be_a_succees
|
65
|
-
res.should_not include_output("GitFame::Error")
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should fail on invalid timeout" do
|
69
|
-
run("--timeout=hello").should_not be_a_succees
|
70
|
-
run("--timeout=").should_not be_a_succees
|
71
|
-
run("--timeout=0").should_not be_a_succees
|
72
|
-
run("--timeout=-2").should_not be_a_succees
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should not print stack trace on invalid dates (--before)" do
|
76
|
-
res = run("--before='---'")
|
77
|
-
res.should_not be_a_succees
|
78
|
-
res.should_not include_output("GitFame::Error")
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should not print stack trace on out of span (--before)" do
|
82
|
-
res = run("--before='1910-01-01'")
|
83
|
-
res.should_not be_a_succees
|
84
|
-
res.should_not include_output("GitFame::Error")
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should not print stack trace on out of span (--after)" do
|
88
|
-
res = run("--after='2100-01-01'")
|
89
|
-
res.should_not be_a_succees
|
90
|
-
res.should_not include_output("GitFame::Error")
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
context "sort" do
|
95
|
-
it "should fail on non existing option" do
|
96
|
-
run("--sort=-----").should_not be_a_succees
|
97
|
-
end
|
98
|
-
|
99
|
-
results = []
|
100
|
-
GitFame::SORT.each do |option|
|
101
|
-
it "should be able to sort by #{option}" do
|
102
|
-
out = run("--sort=#{option}")
|
103
|
-
out.should be_a_succees
|
104
|
-
# TODO: Not a impl. problem
|
105
|
-
# Just not enough data
|
106
|
-
unless option == "name"
|
107
|
-
results.push(out.first)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
it "#{GitFame::SORT.join(", ")} should not output the same thing" do
|
113
|
-
results.uniq.sort.should eq(results.sort)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|