git_evolution 0.0.1 → 0.1.2
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 +4 -4
- data/Gemfile +11 -0
- data/Gemfile.lock +92 -0
- data/README.md +4 -0
- data/Rakefile +4 -1
- data/bin/git-evolution +1 -1
- data/bin/git_evolution +1 -1
- data/git_evolution.gemspec +9 -5
- data/lib/git_evolution.rb +10 -38
- data/lib/git_evolution/commit.rb +42 -0
- data/lib/git_evolution/initialize.rb +6 -0
- data/lib/git_evolution/option_handler.rb +62 -0
- data/lib/git_evolution/report_presenter.rb +64 -0
- data/lib/git_evolution/repository.rb +27 -0
- data/lib/git_evolution/version.rb +2 -2
- data/pkg/git_evolution-0.1.1.gem +0 -0
- data/pkg/git_evolution-0.1.2.gem +0 -0
- data/spec/fixtures/raw_commit.txt +18 -0
- data/spec/fixtures/raw_commit_with_no_body.txt +19 -0
- data/spec/fixtures/raw_commit_with_no_diff.txt +8 -0
- data/spec/git_evolution/commit_spec.rb +47 -0
- data/spec/git_evolution/option_handler_spec.rb +135 -0
- data/spec/git_evolution/repository_spec.rb +88 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/coverage.rb +16 -0
- data/spec/support/repository_helper.rb +39 -0
- metadata +64 -12
- data/.gitignore +0 -34
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf16cc71418f589e13752aa32e110fe41dda318a
|
|
4
|
+
data.tar.gz: f527d0c64625e859bbda0759eaec9453d4651809
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75f452c8f3cd00f2e99ed0eb7afedb2391205e693a310ef4e4d6cd0cd7aa4d099c32ed4b414aef33271881dca134677a17616174170d8dd9832b4526af4c36c3
|
|
7
|
+
data.tar.gz: cdfdee0e7dc34c330da4b40f0ba190911dc87291d9186ed288e2660bf0acf15253db26033a45394a89768743de100f7b564e33be2c7f186d46c03e8d59b0a0a9
|
data/Gemfile
CHANGED
|
@@ -2,3 +2,14 @@ source 'https://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
# Specify your gem's dependencies in git_evolution.gemspec
|
|
4
4
|
gemspec
|
|
5
|
+
|
|
6
|
+
group :test do
|
|
7
|
+
gem 'simplecov'
|
|
8
|
+
gem 'coveralls', require: false
|
|
9
|
+
gem 'rspec'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
group :development do
|
|
13
|
+
gem 'pry-byebug'
|
|
14
|
+
gem 'rubocop'
|
|
15
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
git_evolution (0.1.2)
|
|
5
|
+
bundler (~> 1.0)
|
|
6
|
+
chronic (~> 0.10.0)
|
|
7
|
+
rake (~> 10.0)
|
|
8
|
+
rugged (~> 0.21.0)
|
|
9
|
+
|
|
10
|
+
GEM
|
|
11
|
+
remote: https://rubygems.org/
|
|
12
|
+
specs:
|
|
13
|
+
ast (2.0.0)
|
|
14
|
+
astrolabe (1.3.0)
|
|
15
|
+
parser (>= 2.2.0.pre.3, < 3.0)
|
|
16
|
+
byebug (3.5.1)
|
|
17
|
+
columnize (~> 0.8)
|
|
18
|
+
debugger-linecache (~> 1.2)
|
|
19
|
+
slop (~> 3.6)
|
|
20
|
+
chronic (0.10.2)
|
|
21
|
+
coderay (1.1.0)
|
|
22
|
+
columnize (0.9.0)
|
|
23
|
+
coveralls (0.7.10)
|
|
24
|
+
multi_json (~> 1.10)
|
|
25
|
+
rest-client (>= 1.6.8, < 2)
|
|
26
|
+
simplecov (~> 0.9.1)
|
|
27
|
+
term-ansicolor (~> 1.3)
|
|
28
|
+
thor (~> 0.19.1)
|
|
29
|
+
debugger-linecache (1.2.0)
|
|
30
|
+
diff-lcs (1.2.5)
|
|
31
|
+
docile (1.1.5)
|
|
32
|
+
method_source (0.8.2)
|
|
33
|
+
mime-types (2.4.3)
|
|
34
|
+
multi_json (1.10.1)
|
|
35
|
+
netrc (0.10.2)
|
|
36
|
+
parser (2.2.0.3)
|
|
37
|
+
ast (>= 1.1, < 3.0)
|
|
38
|
+
powerpack (0.1.0)
|
|
39
|
+
pry (0.10.1)
|
|
40
|
+
coderay (~> 1.1.0)
|
|
41
|
+
method_source (~> 0.8.1)
|
|
42
|
+
slop (~> 3.4)
|
|
43
|
+
pry-byebug (3.0.1)
|
|
44
|
+
byebug (~> 3.4)
|
|
45
|
+
pry (~> 0.10)
|
|
46
|
+
rainbow (2.0.0)
|
|
47
|
+
rake (10.4.2)
|
|
48
|
+
rest-client (1.7.3)
|
|
49
|
+
mime-types (>= 1.16, < 3.0)
|
|
50
|
+
netrc (~> 0.7)
|
|
51
|
+
rspec (3.2.0)
|
|
52
|
+
rspec-core (~> 3.2.0)
|
|
53
|
+
rspec-expectations (~> 3.2.0)
|
|
54
|
+
rspec-mocks (~> 3.2.0)
|
|
55
|
+
rspec-core (3.2.0)
|
|
56
|
+
rspec-support (~> 3.2.0)
|
|
57
|
+
rspec-expectations (3.2.0)
|
|
58
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
59
|
+
rspec-support (~> 3.2.0)
|
|
60
|
+
rspec-mocks (3.2.0)
|
|
61
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
62
|
+
rspec-support (~> 3.2.0)
|
|
63
|
+
rspec-support (3.2.1)
|
|
64
|
+
rubocop (0.29.1)
|
|
65
|
+
astrolabe (~> 1.3)
|
|
66
|
+
parser (>= 2.2.0.1, < 3.0)
|
|
67
|
+
powerpack (~> 0.1)
|
|
68
|
+
rainbow (>= 1.99.1, < 3.0)
|
|
69
|
+
ruby-progressbar (~> 1.4)
|
|
70
|
+
ruby-progressbar (1.7.1)
|
|
71
|
+
rugged (0.21.4)
|
|
72
|
+
simplecov (0.9.2)
|
|
73
|
+
docile (~> 1.1.0)
|
|
74
|
+
multi_json (~> 1.0)
|
|
75
|
+
simplecov-html (~> 0.9.0)
|
|
76
|
+
simplecov-html (0.9.0)
|
|
77
|
+
slop (3.6.0)
|
|
78
|
+
term-ansicolor (1.3.0)
|
|
79
|
+
tins (~> 1.0)
|
|
80
|
+
thor (0.19.1)
|
|
81
|
+
tins (1.3.4)
|
|
82
|
+
|
|
83
|
+
PLATFORMS
|
|
84
|
+
ruby
|
|
85
|
+
|
|
86
|
+
DEPENDENCIES
|
|
87
|
+
coveralls
|
|
88
|
+
git_evolution!
|
|
89
|
+
pry-byebug
|
|
90
|
+
rspec
|
|
91
|
+
rubocop
|
|
92
|
+
simplecov
|
data/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# GitEvolution
|
|
2
2
|
|
|
3
|
+
[](https://travis-ci.org/kevinjalbert/git_evolution)
|
|
4
|
+
[](https://coveralls.io/r/kevinjalbert/git_evolution)
|
|
5
|
+
[](https://codeclimate.com/github/kevinjalbert/git_evolution)
|
|
6
|
+
|
|
3
7
|
TODO: Write a gem description
|
|
4
8
|
|
|
5
9
|
## Installation
|
data/Rakefile
CHANGED
data/bin/git-evolution
CHANGED
data/bin/git_evolution
CHANGED
data/git_evolution.gemspec
CHANGED
|
@@ -13,11 +13,15 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.homepage = ''
|
|
14
14
|
spec.license = 'MIT'
|
|
15
15
|
|
|
16
|
-
spec.files =
|
|
17
|
-
spec.
|
|
18
|
-
spec.
|
|
16
|
+
spec.files = Dir['**/*']
|
|
17
|
+
spec.test_files = Dir['{test,spec,features}/**/*']
|
|
18
|
+
spec.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
|
19
19
|
spec.require_paths = ['lib']
|
|
20
20
|
|
|
21
|
-
spec.
|
|
22
|
-
spec.
|
|
21
|
+
spec.add_dependency 'bundler', '~> 1.0'
|
|
22
|
+
spec.add_dependency 'rake', '~> 10.0'
|
|
23
|
+
spec.add_dependency 'rugged', '~> 0.21.0'
|
|
24
|
+
spec.add_dependency 'chronic', '~> 0.10.0'
|
|
25
|
+
|
|
26
|
+
spec.required_ruby_version = '~> 2.0'
|
|
23
27
|
end
|
data/lib/git_evolution.rb
CHANGED
|
@@ -1,43 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
def run(args)
|
|
3
|
-
start_line = args[0]
|
|
4
|
-
end_line = args[1]
|
|
5
|
-
file = args[2]
|
|
1
|
+
require_relative './git_evolution/initialize.rb'
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
module GitEvolution
|
|
4
|
+
def self.run(args)
|
|
5
|
+
options = OptionHandler.parse_options(args)
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
repo = Repository.new(options.file)
|
|
8
|
+
commits = repo.line_commits(options.start_line, options.end_line, options.file, options.since)
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
commit_info[sha] = {
|
|
17
|
-
author: commit_data[0],
|
|
18
|
-
date: commit_data[1],
|
|
19
|
-
title: commit_data[2],
|
|
20
|
-
body: commit_data[3..-1].join
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
ownership = Hash.new(0)
|
|
25
|
-
|
|
26
|
-
puts 'Commits:'
|
|
27
|
-
commit_info.each do |sha, data|
|
|
28
|
-
puts "#{data[:author]} (#{Time.at(data[:date].to_i)}) - #{sha}"
|
|
29
|
-
puts "#{data[:title]}"
|
|
30
|
-
puts
|
|
31
|
-
|
|
32
|
-
ownership[data[:author]] = ownership[data[:author]] + 1
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
puts '-' * 80
|
|
36
|
-
|
|
37
|
-
puts
|
|
38
|
-
puts 'Ownership:'
|
|
39
|
-
ownership.each do |author, count|
|
|
40
|
-
puts "#{author} - #{count}/#{commit_info.size} (#{(count.to_f / commit_info.size * 100).round(2)}%)"
|
|
41
|
-
end
|
|
10
|
+
ReportPresenter.new(commits).print
|
|
11
|
+
rescue StandardError => e
|
|
12
|
+
puts "[#{e.class}] #{e.message}"
|
|
13
|
+
puts e.backtrace
|
|
42
14
|
end
|
|
43
15
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module GitEvolution
|
|
2
|
+
class Commit
|
|
3
|
+
attr_reader :raw_commit, :sha, :author, :date, :subject, :body, :additions, :deletions
|
|
4
|
+
|
|
5
|
+
def initialize(raw_commit)
|
|
6
|
+
@raw_commit = raw_commit
|
|
7
|
+
|
|
8
|
+
parse_meta_data!
|
|
9
|
+
parse_body_data!
|
|
10
|
+
parse_diff_data!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def parse_meta_data!
|
|
14
|
+
@sha = raw_commit.scan(/^commit\s+(.*?)$/).flatten.first.strip
|
|
15
|
+
@author = raw_commit.scan(/^Author:\s+(.*?)$/).flatten.first.strip
|
|
16
|
+
@date= raw_commit.scan(/^Date:\s+(.*?)$/).flatten.first.strip
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parse_body_data!
|
|
20
|
+
raw_body_lines = (raw_commit + "\n\u0000").scan(/^Date:.*?$(.*?)^[diff|\u0000]/m).flatten.first.strip.split("\n")
|
|
21
|
+
@subject = raw_body_lines.first.strip
|
|
22
|
+
|
|
23
|
+
if raw_body_lines.size > 1
|
|
24
|
+
@body = raw_body_lines[1..-1].map { |line| line.gsub(/^\s+/, '') }.join("\n")
|
|
25
|
+
@body.sub!(/\n+/, '') if @body.start_with?("\n")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def parse_diff_data!
|
|
30
|
+
raw_diff_lines = raw_commit.scan(/^@@.*?$(.*)?/m).flatten.first
|
|
31
|
+
|
|
32
|
+
if raw_diff_lines
|
|
33
|
+
raw_diff_lines = raw_diff_lines.strip.split("\n")
|
|
34
|
+
@additions = raw_diff_lines.count { |line| line.start_with?('+') }
|
|
35
|
+
@deletions = raw_diff_lines.count { |line| line.start_with?('-') }
|
|
36
|
+
else
|
|
37
|
+
@additions = 0
|
|
38
|
+
@deletions = 0
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module GitEvolution
|
|
2
|
+
module OptionHandler
|
|
3
|
+
def self.parse_options(args)
|
|
4
|
+
options = OpenStruct.new(
|
|
5
|
+
range: nil,
|
|
6
|
+
since: nil,
|
|
7
|
+
start_line: nil,
|
|
8
|
+
end_line: nil,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
OptionParser.new do |opts|
|
|
12
|
+
opts.banner = 'Usage: git_evolution [options] <file>'
|
|
13
|
+
opts.version = VERSION
|
|
14
|
+
opts.on '-r', '--range N:N', String, 'The specified range of lines to consider within the file (optional)' do |value|
|
|
15
|
+
options.range = value
|
|
16
|
+
end
|
|
17
|
+
opts.on '-s', '--since STRING', String, 'Consider the commits which are more recent than the specified time (optional)' do |value|
|
|
18
|
+
options.since = value
|
|
19
|
+
end
|
|
20
|
+
end.parse!
|
|
21
|
+
|
|
22
|
+
options[:file] = File.expand_path(args[0])
|
|
23
|
+
options[:start_line], options[:end_line] = parse_range(options[:range])
|
|
24
|
+
|
|
25
|
+
validate_options!(options)
|
|
26
|
+
|
|
27
|
+
options
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.parse_range(range)
|
|
31
|
+
return if range.nil?
|
|
32
|
+
|
|
33
|
+
regex_matches = range.match(/^(\d+):(\d+)/)
|
|
34
|
+
raise 'The --range option was not in the valid format (N:N)' if regex_matches.nil?
|
|
35
|
+
|
|
36
|
+
start_line = regex_matches[1].to_i
|
|
37
|
+
end_line = regex_matches[2].to_i
|
|
38
|
+
|
|
39
|
+
return start_line, end_line
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.validate_options!(options)
|
|
43
|
+
if options.file.nil?
|
|
44
|
+
raise 'Missing required file argument'
|
|
45
|
+
elsif !File.exist?(options.file)
|
|
46
|
+
raise "File #{options.file} does not exist"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if !options.range.nil?
|
|
50
|
+
raise 'Start line cannot be greater than the end line' if options.start_line > options.end_line
|
|
51
|
+
|
|
52
|
+
file_length = File.new(options.file).readlines.size
|
|
53
|
+
raise "End line cannot be larger than the length of the file (#{file_length})" if options.end_line > file_length
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if !options.since.nil?
|
|
57
|
+
options.since = Chronic.parse(options.since)
|
|
58
|
+
raise 'The since time could not be properly parsed' if options.since.nil?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module GitEvolution
|
|
2
|
+
class ReportPresenter
|
|
3
|
+
def initialize(commits)
|
|
4
|
+
@commits = commits
|
|
5
|
+
@ownership = { commits: Hash.new(0), changes: Hash.new(0) }
|
|
6
|
+
|
|
7
|
+
calculate_ownership!
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def print
|
|
11
|
+
print_commits
|
|
12
|
+
puts
|
|
13
|
+
puts '-' * 80
|
|
14
|
+
puts
|
|
15
|
+
print_commit_ownership
|
|
16
|
+
puts
|
|
17
|
+
print_changes_ownership
|
|
18
|
+
puts
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def print_commits
|
|
22
|
+
puts 'Commits:'
|
|
23
|
+
@commits.each do |commit|
|
|
24
|
+
puts "#{commit.author} (#{commit.date}) - #{commit.sha}"
|
|
25
|
+
puts "#{commit.subject}"
|
|
26
|
+
puts
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def print_commit_ownership
|
|
31
|
+
puts 'Ownership (Commits):'
|
|
32
|
+
@ownership[:commits].each do |author, count|
|
|
33
|
+
puts "#{author} - #{count}/#{@commits.size} (#{(count.to_f / @commits.size * 100).round(2)}%)"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def print_changes_ownership
|
|
38
|
+
puts 'Ownership (Changes):'
|
|
39
|
+
|
|
40
|
+
total_additions = @commits.inject(0) { |sum, commit| sum + commit.additions }
|
|
41
|
+
total_deletions = @commits.inject(0) { |sum, commit| sum + commit.deletions }
|
|
42
|
+
total_changes = total_additions + total_deletions
|
|
43
|
+
|
|
44
|
+
@ownership[:changes].each do |author, count|
|
|
45
|
+
puts "#{author} - #{count}/#{total_changes} (#{(count.to_f / total_changes * 100).round(2)}%)"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def calculate_ownership!
|
|
50
|
+
@commits.each do |commit|
|
|
51
|
+
@ownership[:commits][commit.author] = @ownership[:commits][commit.author] + 1
|
|
52
|
+
@ownership[:changes][commit.author] = @ownership[:changes][commit.author] + commit.additions + commit.deletions
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
sort_ownership!
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def sort_ownership!
|
|
59
|
+
@ownership.keys.each do |keys|
|
|
60
|
+
@ownership[keys] = @ownership[keys].sort { |a,b| b[1] <=> a[1] }.to_h
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module GitEvolution
|
|
2
|
+
class Repository
|
|
3
|
+
def initialize(directory_name)
|
|
4
|
+
@git_repo = Rugged::Repository.discover(File.expand_path(directory_name))
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def dir
|
|
8
|
+
@git_repo.workdir
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def line_commits(start_line, end_line, file, since = nil)
|
|
12
|
+
raw_results = raw_line_history(start_line, end_line, file, since)
|
|
13
|
+
raw_results.split("\u0000").map { |raw_commit| Commit.new(raw_commit) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def raw_line_history(start_line, end_line, file, since = nil)
|
|
17
|
+
since_option = "--since '#{since}'"
|
|
18
|
+
|
|
19
|
+
Dir.chdir(dir) do
|
|
20
|
+
return `git --no-pager log -p -z\
|
|
21
|
+
#{since_option if since}\
|
|
22
|
+
#{"-L#{start_line},#{end_line}:#{file}" if start_line && end_line}\
|
|
23
|
+
--follow #{file}`
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
VERSION = '0.
|
|
1
|
+
module GitEvolution
|
|
2
|
+
VERSION = '0.1.2'
|
|
3
3
|
end
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
commit 01da64f8b1021a1007fc3ee9d0acbe87c02217e7
|
|
2
|
+
Author: Kevin Jalbert <kevin.j.jalbert@gmail.com>
|
|
3
|
+
Date: Mon Jun 8 07:31:34 2015 -0400
|
|
4
|
+
|
|
5
|
+
Add ability to acquire the ordered commits for a line range
|
|
6
|
+
|
|
7
|
+
Add spec to test #line_commits. Slight refactoring to make use of
|
|
8
|
+
#line_commits.
|
|
9
|
+
|
|
10
|
+
diff --git a/lib/git_evolution/repository.rb b/lib/git_evolution/repository.rb
|
|
11
|
+
--- a/lib/git_evolution/repository.rb
|
|
12
|
+
+++ b/lib/git_evolution/repository.rb
|
|
13
|
+
@@ -24,0 +25,5 @@
|
|
14
|
+
+ def line_history(start_line, end_line, file)
|
|
15
|
+
+ Dir.chdir(dir) do
|
|
16
|
+
+ return `git --no-pager log -L#{start_line},#{end_line}:#{file} --follow #{file}`
|
|
17
|
+
+ end
|
|
18
|
+
+ end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
commit 326f5329333e65aebb6ce7f8566d88a58964022a
|
|
2
|
+
Author: Kevin Jalbert <kevin.j.jalbert@gmail.com>
|
|
3
|
+
Date: Mon Jun 8 07:47:13 2015 -0400
|
|
4
|
+
|
|
5
|
+
Add ability to specify the '--since' option for line_{history|commits}
|
|
6
|
+
|
|
7
|
+
diff --git a/lib/git_evolution/repository.rb b/lib/git_evolution/repository.rb
|
|
8
|
+
--- a/lib/git_evolution/repository.rb
|
|
9
|
+
+++ b/lib/git_evolution/repository.rb
|
|
10
|
+
@@ -25,5 +25,7 @@
|
|
11
|
+
- def line_history(start_line, end_line, file)
|
|
12
|
+
+ def line_history(start_line, end_line, file, since = nil)
|
|
13
|
+
+ since_option = "--since '#{since}'"
|
|
14
|
+
+
|
|
15
|
+
Dir.chdir(dir) do
|
|
16
|
+
- return `git --no-pager log -L#{start_line},#{end_line}:#{file} --follow #{file}`
|
|
17
|
+
+ return `git --no-pager log #{since_option if since} -L#{start_line},#{end_line}:#{file} --follow #{file}`
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
commit 01da64f8b1021a1007fc3ee9d0acbe87c02217e7
|
|
2
|
+
Author: Kevin Jalbert <kevin.j.jalbert@gmail.com>
|
|
3
|
+
Date: Mon Jun 8 07:31:34 2015 -0400
|
|
4
|
+
|
|
5
|
+
Add ability to acquire the ordered commits for a line range
|
|
6
|
+
|
|
7
|
+
Add spec to test #line_commits. Slight refactoring to make use of
|
|
8
|
+
#line_commits.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe GitEvolution::Commit do
|
|
4
|
+
describe '.new' do
|
|
5
|
+
let(:raw_commit) { fixture('raw_commit.txt') }
|
|
6
|
+
|
|
7
|
+
subject { described_class.new(raw_commit) }
|
|
8
|
+
|
|
9
|
+
it 'valid commit parsing' do
|
|
10
|
+
expect(subject.sha).to eq('01da64f8b1021a1007fc3ee9d0acbe87c02217e7')
|
|
11
|
+
expect(subject.author).to eq('Kevin Jalbert <kevin.j.jalbert@gmail.com>')
|
|
12
|
+
expect(subject.date).to eq('Mon Jun 8 07:31:34 2015 -0400')
|
|
13
|
+
expect(subject.subject).to eq("Add ability to acquire the ordered commits for a line range")
|
|
14
|
+
expect(subject.body).to eq("Add spec to test #line_commits. Slight refactoring to make use of\n#line_commits.")
|
|
15
|
+
expect(subject.additions).to eq(5)
|
|
16
|
+
expect(subject.deletions).to eq(0)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'with no body' do
|
|
20
|
+
let(:raw_commit) { fixture('raw_commit_with_no_body.txt') }
|
|
21
|
+
|
|
22
|
+
it 'valid commit parsing' do
|
|
23
|
+
expect(subject.sha).to eq('326f5329333e65aebb6ce7f8566d88a58964022a')
|
|
24
|
+
expect(subject.author).to eq('Kevin Jalbert <kevin.j.jalbert@gmail.com>')
|
|
25
|
+
expect(subject.date).to eq('Mon Jun 8 07:47:13 2015 -0400')
|
|
26
|
+
expect(subject.subject).to eq("Add ability to specify the '--since' option for line_{history|commits}")
|
|
27
|
+
expect(subject.body).to eq(nil)
|
|
28
|
+
expect(subject.additions).to eq(4)
|
|
29
|
+
expect(subject.deletions).to eq(2)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'with no diff (i.e., merge commit)' do
|
|
34
|
+
let(:raw_commit) { fixture('raw_commit_with_no_diff.txt') }
|
|
35
|
+
|
|
36
|
+
it 'valid commit parsing' do
|
|
37
|
+
expect(subject.sha).to eq('01da64f8b1021a1007fc3ee9d0acbe87c02217e7')
|
|
38
|
+
expect(subject.author).to eq('Kevin Jalbert <kevin.j.jalbert@gmail.com>')
|
|
39
|
+
expect(subject.date).to eq('Mon Jun 8 07:31:34 2015 -0400')
|
|
40
|
+
expect(subject.subject).to eq("Add ability to acquire the ordered commits for a line range")
|
|
41
|
+
expect(subject.body).to eq("Add spec to test #line_commits. Slight refactoring to make use of\n#line_commits.")
|
|
42
|
+
expect(subject.additions).to eq(0)
|
|
43
|
+
expect(subject.deletions).to eq(0)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe GitEvolution::OptionHandler do
|
|
4
|
+
describe '.parse_options' do
|
|
5
|
+
subject { described_class.parse_options([file]) }
|
|
6
|
+
|
|
7
|
+
let!(:tmp_dir) { Dir.mktmpdir }
|
|
8
|
+
let(:file) { tmp_dir + '/file.txt' }
|
|
9
|
+
let(:start_line) { 1 }
|
|
10
|
+
let(:end_line) { 10 }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
IO.write(file, (1..20).map { ".\n" }.join)
|
|
14
|
+
allow(described_class).to receive(:parse_range) { [start_line, end_line] }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
after { FileUtils.rm_r(tmp_dir) }
|
|
18
|
+
|
|
19
|
+
it 'parses options correctly' do
|
|
20
|
+
expect(subject.start_line).to eq(start_line)
|
|
21
|
+
expect(subject.end_line).to eq(end_line)
|
|
22
|
+
expect(subject.file).to eq(file)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '.parse_range' do
|
|
27
|
+
context 'valid range' do
|
|
28
|
+
let(:range) { '10:20' }
|
|
29
|
+
let(:expected_start_line) { 10 }
|
|
30
|
+
let(:expected_end_line) { 20 }
|
|
31
|
+
|
|
32
|
+
it 'detects range' do
|
|
33
|
+
start_line, end_line = subject.parse_range(range)
|
|
34
|
+
expect(start_line).to eq(expected_start_line)
|
|
35
|
+
expect(end_line).to eq(expected_end_line)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'invalid range' do
|
|
40
|
+
let(:range) { '10.20' }
|
|
41
|
+
|
|
42
|
+
it 'raises exception' do
|
|
43
|
+
expect { described_class.parse_range(range) }.to raise_error
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context 'nil range' do
|
|
48
|
+
let(:range) { nil }
|
|
49
|
+
|
|
50
|
+
it 'returns nil' do
|
|
51
|
+
expect(described_class.parse_range(range)).to be_nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe '.validate_options!' do
|
|
57
|
+
let(:options) do
|
|
58
|
+
OpenStruct.new(
|
|
59
|
+
file: file,
|
|
60
|
+
range: range,
|
|
61
|
+
since: since,
|
|
62
|
+
start_line: start_line,
|
|
63
|
+
end_line: end_line
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
let!(:tmp_dir) { Dir.mktmpdir }
|
|
68
|
+
let(:file) { tmp_dir + '/file.txt' }
|
|
69
|
+
let(:range) { '1:2' }
|
|
70
|
+
let(:since) { '1 day ago' }
|
|
71
|
+
let(:start_line) { 1 }
|
|
72
|
+
let(:end_line) { 20 }
|
|
73
|
+
|
|
74
|
+
before { IO.write(file, (1..20).map { ".\n" }.join) }
|
|
75
|
+
|
|
76
|
+
after { FileUtils.rm_r(tmp_dir) }
|
|
77
|
+
|
|
78
|
+
it 'valid options' do
|
|
79
|
+
expect { described_class.validate_options!(options) }.to_not raise_error
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'start_line is larger than end_line' do
|
|
83
|
+
let(:start_line) { 10 }
|
|
84
|
+
let(:end_line) { 1 }
|
|
85
|
+
|
|
86
|
+
it 'invalid options' do
|
|
87
|
+
expect { described_class.validate_options!(options) }.to raise_error
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'file does not exist' do
|
|
92
|
+
let(:file) { tmp_dir + '/not_here.txt' }
|
|
93
|
+
|
|
94
|
+
before { FileUtils.rm(file) }
|
|
95
|
+
|
|
96
|
+
it 'invalid options' do
|
|
97
|
+
expect { described_class.validate_options!(options) }.to raise_error
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context 'missing file argument' do
|
|
101
|
+
it 'invalid options' do
|
|
102
|
+
options.file = nil
|
|
103
|
+
expect { described_class.validate_options!(options) }.to raise_error
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'end_line is larger than file length' do
|
|
109
|
+
let(:start_line) { 10 }
|
|
110
|
+
let(:end_line) { 40 }
|
|
111
|
+
|
|
112
|
+
it 'invalid options' do
|
|
113
|
+
expect { described_class.validate_options!(options) }.to raise_error
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context 'since option' do
|
|
118
|
+
context 'since is not parsable' do
|
|
119
|
+
let(:since) { 'csdcsdc' }
|
|
120
|
+
|
|
121
|
+
it 'invalid options' do
|
|
122
|
+
expect { described_class.validate_options!(options) }.to raise_error
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context 'since is parsable' do
|
|
127
|
+
let(:since) { '1 days ago' }
|
|
128
|
+
|
|
129
|
+
it 'valid options' do
|
|
130
|
+
expect { described_class.validate_options!(options) }.to_not raise_error
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe GitEvolution::Repository do
|
|
4
|
+
describe '.new' do
|
|
5
|
+
context 'valid repository directory' do
|
|
6
|
+
before(:each) { create_repository }
|
|
7
|
+
after(:each) { delete_repository }
|
|
8
|
+
|
|
9
|
+
it 'detects repository' do
|
|
10
|
+
repo = described_class.new(repository_dir)
|
|
11
|
+
expect(repo.dir).to eq(repository_dir)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'invalid repository directory' do
|
|
16
|
+
let!(:tmp_dir) { Dir.mktmpdir }
|
|
17
|
+
after { FileUtils.rm_r(tmp_dir) }
|
|
18
|
+
|
|
19
|
+
it 'detects no repository' do
|
|
20
|
+
expect { described_class.new(tmp_dir) }.to raise_error(Rugged::RepositoryError)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '#line_commits' do
|
|
26
|
+
context 'valid repository directory' do
|
|
27
|
+
before(:each) do
|
|
28
|
+
create_repository
|
|
29
|
+
|
|
30
|
+
add_to_index('README.md', "This is a Reedme\n\TODO stuff")
|
|
31
|
+
create_commit('John Smith', 'john@smith.com', Chronic.parse('1 day ago'), commit1_subject)
|
|
32
|
+
|
|
33
|
+
add_to_index('README.md', "This is a Readme\n\TODO stuff")
|
|
34
|
+
create_commit('John', 'john@smith.com', Chronic.parse('now'), commit2_subject, 'Fix typo: Reedme -> Readme')
|
|
35
|
+
end
|
|
36
|
+
after(:each) { delete_repository }
|
|
37
|
+
|
|
38
|
+
let(:commit1_subject) { 'Initial Commit' }
|
|
39
|
+
let(:commit2_subject) { 'Fix typo in README' }
|
|
40
|
+
|
|
41
|
+
it 'returns commits for the specifed line range' do
|
|
42
|
+
repo = described_class.new(repository_dir)
|
|
43
|
+
line_commits = repo.line_commits(1, 2, 'README.md')
|
|
44
|
+
|
|
45
|
+
expect(line_commits.size).to eq(2)
|
|
46
|
+
expect(line_commits.first).to be_a(GitEvolution::Commit)
|
|
47
|
+
expect(line_commits.first.subject).to eq(commit2_subject)
|
|
48
|
+
expect(line_commits.last.subject).to eq(commit1_subject)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '#raw_line_history' do
|
|
54
|
+
context 'valid repository directory' do
|
|
55
|
+
before(:each) do
|
|
56
|
+
create_repository
|
|
57
|
+
|
|
58
|
+
add_to_index('README.md', "This is a Reedme\n\TODO stuff")
|
|
59
|
+
create_commit('John Smith', 'john@smith.com', Chronic.parse('1 day ago'), commit1_subject)
|
|
60
|
+
|
|
61
|
+
add_to_index('README.md', "This is a Readme\n\TODO stuff")
|
|
62
|
+
create_commit('John', 'john@smith.com', Chronic.parse('now'), commit2_subject, 'Fix typo: Reedme -> Readme')
|
|
63
|
+
end
|
|
64
|
+
after(:each) { delete_repository }
|
|
65
|
+
|
|
66
|
+
let(:commit1_subject) { 'Initial Commit' }
|
|
67
|
+
let(:commit2_subject) { 'Fix typo in README' }
|
|
68
|
+
|
|
69
|
+
it 'returns raw commit log containing commits' do
|
|
70
|
+
repo = described_class.new(repository_dir)
|
|
71
|
+
raw_line_history = repo.raw_line_history(1, 2, 'README.md')
|
|
72
|
+
|
|
73
|
+
expect(raw_line_history).to include(commit1_subject)
|
|
74
|
+
expect(raw_line_history).to include(commit2_subject)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'with since option' do
|
|
78
|
+
it 'returns only commit within last 6 hours' do
|
|
79
|
+
repo = described_class.new(repository_dir)
|
|
80
|
+
raw_line_history = repo.raw_line_history(1, 2, 'README.md', '6 hours ago')
|
|
81
|
+
|
|
82
|
+
expect(raw_line_history).to_not include(commit1_subject)
|
|
83
|
+
expect(raw_line_history).to include(commit2_subject)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
|
2
|
+
|
|
3
|
+
Bundler.require(:test)
|
|
4
|
+
Bundler.require(:development)
|
|
5
|
+
|
|
6
|
+
Dir.glob(Dir.pwd + '/spec/support/**/*.rb') { |file| require file }
|
|
7
|
+
|
|
8
|
+
require 'git_evolution/initialize'
|
|
9
|
+
|
|
10
|
+
def fixture(file_name)
|
|
11
|
+
File.read([Dir.pwd, 'spec', 'fixtures', file_name].join('/'))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
RSpec.configure do |c|
|
|
15
|
+
c.include RepositoryHelper
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
begin
|
|
2
|
+
if ENV['CI']
|
|
3
|
+
require 'coveralls'
|
|
4
|
+
Coveralls.wear!
|
|
5
|
+
elsif ENV['COVERAGE']
|
|
6
|
+
require 'simplecov'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
if ENV['CI'] || ENV['COVERAGE']
|
|
10
|
+
SimpleCov.start do
|
|
11
|
+
add_filter '/spec/'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
rescue LoadError => e
|
|
15
|
+
warn(e)
|
|
16
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module RepositoryHelper
|
|
2
|
+
module_function
|
|
3
|
+
|
|
4
|
+
def create_repository
|
|
5
|
+
@tmp_git_dir = Dir.mktmpdir
|
|
6
|
+
@repo = Rugged::Repository.init_at(@tmp_git_dir)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def delete_repository
|
|
10
|
+
FileUtils.rm_r(@tmp_git_dir)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def repository_dir
|
|
14
|
+
File.realpath(@tmp_git_dir) + '/'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_to_index(file_name, blob_content)
|
|
18
|
+
object_id = @repo.write(blob_content, :blob)
|
|
19
|
+
@repo.index.add(path: file_name, oid: object_id, mode: 0100644)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_commit(author_name, author_email, time, subject, body = nil)
|
|
23
|
+
author = { email: author_email, name: author_name, time: time }
|
|
24
|
+
|
|
25
|
+
tree = @repo.index.write_tree(@repo)
|
|
26
|
+
|
|
27
|
+
commit = Rugged::Commit.create(@repo,
|
|
28
|
+
author: author,
|
|
29
|
+
message: "#{subject}\n\n#{body}".strip,
|
|
30
|
+
committer: author,
|
|
31
|
+
parents: @repo.empty? ? [] : [@repo.head.target].compact,
|
|
32
|
+
tree: tree,
|
|
33
|
+
update_ref: 'HEAD')
|
|
34
|
+
|
|
35
|
+
@repo.checkout('master', strategy: [:force])
|
|
36
|
+
|
|
37
|
+
commit
|
|
38
|
+
end
|
|
39
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git_evolution
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Jalbert
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.
|
|
20
|
-
type: :
|
|
19
|
+
version: '1.0'
|
|
20
|
+
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.
|
|
26
|
+
version: '1.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -31,13 +31,41 @@ dependencies:
|
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '10.0'
|
|
34
|
-
type: :
|
|
34
|
+
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '10.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rugged
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 0.21.0
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 0.21.0
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: chronic
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.10.0
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 0.10.0
|
|
41
69
|
description: Gem that provides the ability to determine the evolution of code within
|
|
42
70
|
a git repository
|
|
43
71
|
email:
|
|
@@ -48,9 +76,8 @@ executables:
|
|
|
48
76
|
extensions: []
|
|
49
77
|
extra_rdoc_files: []
|
|
50
78
|
files:
|
|
51
|
-
- ".gitignore"
|
|
52
|
-
- ".ruby-version"
|
|
53
79
|
- Gemfile
|
|
80
|
+
- Gemfile.lock
|
|
54
81
|
- LICENSE
|
|
55
82
|
- README.md
|
|
56
83
|
- Rakefile
|
|
@@ -58,7 +85,23 @@ files:
|
|
|
58
85
|
- bin/git_evolution
|
|
59
86
|
- git_evolution.gemspec
|
|
60
87
|
- lib/git_evolution.rb
|
|
88
|
+
- lib/git_evolution/commit.rb
|
|
89
|
+
- lib/git_evolution/initialize.rb
|
|
90
|
+
- lib/git_evolution/option_handler.rb
|
|
91
|
+
- lib/git_evolution/report_presenter.rb
|
|
92
|
+
- lib/git_evolution/repository.rb
|
|
61
93
|
- lib/git_evolution/version.rb
|
|
94
|
+
- pkg/git_evolution-0.1.1.gem
|
|
95
|
+
- pkg/git_evolution-0.1.2.gem
|
|
96
|
+
- spec/fixtures/raw_commit.txt
|
|
97
|
+
- spec/fixtures/raw_commit_with_no_body.txt
|
|
98
|
+
- spec/fixtures/raw_commit_with_no_diff.txt
|
|
99
|
+
- spec/git_evolution/commit_spec.rb
|
|
100
|
+
- spec/git_evolution/option_handler_spec.rb
|
|
101
|
+
- spec/git_evolution/repository_spec.rb
|
|
102
|
+
- spec/spec_helper.rb
|
|
103
|
+
- spec/support/coverage.rb
|
|
104
|
+
- spec/support/repository_helper.rb
|
|
62
105
|
homepage: ''
|
|
63
106
|
licenses:
|
|
64
107
|
- MIT
|
|
@@ -69,9 +112,9 @@ require_paths:
|
|
|
69
112
|
- lib
|
|
70
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
114
|
requirements:
|
|
72
|
-
- - "
|
|
115
|
+
- - "~>"
|
|
73
116
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0'
|
|
117
|
+
version: '2.0'
|
|
75
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
119
|
requirements:
|
|
77
120
|
- - ">="
|
|
@@ -79,9 +122,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
79
122
|
version: '0'
|
|
80
123
|
requirements: []
|
|
81
124
|
rubyforge_project:
|
|
82
|
-
rubygems_version: 2.4.
|
|
125
|
+
rubygems_version: 2.4.6
|
|
83
126
|
signing_key:
|
|
84
127
|
specification_version: 4
|
|
85
128
|
summary: Gem that provides the ability to determine the evolution of code within a
|
|
86
129
|
git repository
|
|
87
|
-
test_files:
|
|
130
|
+
test_files:
|
|
131
|
+
- spec/fixtures/raw_commit.txt
|
|
132
|
+
- spec/fixtures/raw_commit_with_no_body.txt
|
|
133
|
+
- spec/fixtures/raw_commit_with_no_diff.txt
|
|
134
|
+
- spec/git_evolution/commit_spec.rb
|
|
135
|
+
- spec/git_evolution/option_handler_spec.rb
|
|
136
|
+
- spec/git_evolution/repository_spec.rb
|
|
137
|
+
- spec/spec_helper.rb
|
|
138
|
+
- spec/support/coverage.rb
|
|
139
|
+
- spec/support/repository_helper.rb
|
data/.gitignore
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
*.gem
|
|
2
|
-
*.rbc
|
|
3
|
-
/.config
|
|
4
|
-
/coverage/
|
|
5
|
-
/InstalledFiles
|
|
6
|
-
/pkg/
|
|
7
|
-
/spec/reports/
|
|
8
|
-
/test/tmp/
|
|
9
|
-
/test/version_tmp/
|
|
10
|
-
/tmp/
|
|
11
|
-
|
|
12
|
-
## Specific to RubyMotion:
|
|
13
|
-
.dat*
|
|
14
|
-
.repl_history
|
|
15
|
-
build/
|
|
16
|
-
|
|
17
|
-
## Documentation cache and generated files:
|
|
18
|
-
/.yardoc/
|
|
19
|
-
/_yardoc/
|
|
20
|
-
/doc/
|
|
21
|
-
/rdoc/
|
|
22
|
-
|
|
23
|
-
## Environment normalisation:
|
|
24
|
-
/.bundle/
|
|
25
|
-
/lib/bundler/man/
|
|
26
|
-
|
|
27
|
-
# for a library or gem, you might want to ignore these files since the code is
|
|
28
|
-
# intended to run in multiple environments; otherwise, check them in:
|
|
29
|
-
# Gemfile.lock
|
|
30
|
-
# .ruby-version
|
|
31
|
-
# .ruby-gemset
|
|
32
|
-
|
|
33
|
-
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
34
|
-
.rvmrc
|
data/.ruby-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.2.0
|