Skip to content

Commit d77f93e

Browse files
committed
move lines provider to separate class
- delegate repository methods to rugged
1 parent 1aaddb3 commit d77f93e

File tree

12 files changed

+216
-188
lines changed

12 files changed

+216
-188
lines changed

lib/meta_commit.rb

+1
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ module Extension
3737
# services
3838
require "meta_commit/services/change_saver"
3939
require "meta_commit/services/parse"
40+
require "meta_commit/services/diff_lines_provider"
4041
require "meta_commit/git/repo"
4142
end

lib/meta_commit/changelog/commands/commit_diff_examiner.rb

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ class CommitDiffExaminer
44
# @param [MetaCommit::Services::Parse] parse_command
55
# @param [MetaCommit::Factories::ContextualAstNodeFactory] ast_path_factory
66
# @param [MetaCommit::Factories::DiffFactory] diff_factory
7-
def initialize(parse_command, ast_path_factory, diff_factory)
7+
# @param [MetaCommit::Factories::DiffFactory] diff_lines_provider
8+
def initialize(parse_command, ast_path_factory, diff_factory, diff_lines_provider)
89
@parse_command = parse_command
910
@ast_path_factory = ast_path_factory
1011
@diff_factory = diff_factory
12+
@diff_lines_provider = diff_lines_provider
1113
end
1214

13-
1415
# Creates diff objects with meta information of changes between left and right commit
1516
# @param [MetaCommit::Git::Repo] repo
1617
# @param [String] left_commit commit id
@@ -20,7 +21,10 @@ def meta(repo, left_commit, right_commit)
2021
diffs = []
2122
commit_id_old = left_commit.oid
2223
commit_id_new = right_commit.oid
23-
repo.diff_with_optimized_lines(left_commit, right_commit) do |old_file_path, new_file_path, patch, line|
24+
repo_diff = repo.diff(left_commit, right_commit, MetaCommit::Git::Repo::DIFF_OPTIONS)
25+
diff_lines = @diff_lines_provider.from(repo_diff)
26+
27+
diff_lines.each do |(old_file_path, new_file_path, patch, line)|
2428
old_file_content = repo.get_blob_at(commit_id_old, old_file_path, '')
2529
new_file_content = repo.get_blob_at(commit_id_new, new_file_path, '')
2630

lib/meta_commit/cli.rb

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ def message
1414
examiner = MetaCommit::Message::Commands::DiffIndexExaminer.new(
1515
container.resolve(:parse_command),
1616
container.resolve(:contextual_ast_node_factory),
17-
container.resolve(:diff_factory)
17+
container.resolve(:diff_factory),
18+
container.resolve(:diff_lines_provider)
1819
)
1920

2021
meta = examiner.index_meta(repository)
@@ -37,7 +38,8 @@ def changelog(from_tag=nil, to_tag=nil)
3738
examiner = MetaCommit::Changelog::Commands::CommitDiffExaminer.new(
3839
container.resolve(:parse_command),
3940
container.resolve(:contextual_ast_node_factory),
40-
container.resolve(:diff_factory)
41+
container.resolve(:diff_factory),
42+
container.resolve(:diff_lines_provider)
4143
)
4244

4345
meta = examiner.meta(repository, from_tag_commit, to_tag_commit)
@@ -59,7 +61,8 @@ def index
5961
examiner = MetaCommit::Index::Commands::DiffExaminer.new(
6062
container.resolve(:parse_command),
6163
container.resolve(:contextual_ast_node_factory),
62-
container.resolve(:diff_factory)
64+
container.resolve(:diff_factory),
65+
container.resolve(:diff_lines_provider)
6366
)
6467

6568
meta = examiner.meta(repository)

lib/meta_commit/container.rb

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def boot(config_store)
2020
register :parser_factory, MetaCommit::Factories::ParserFactory.new(self[:parser_classes])
2121
register :parse_command, MetaCommit::Services::Parse.new(self[:parser_factory])
2222
register :contextual_ast_node_factory, MetaCommit::Factories::ContextualAstNodeFactory.new
23+
register :diff_lines_provider, MetaCommit::Services::DiffLinesProvider.new
2324

2425
self
2526
end

lib/meta_commit/git/repo.rb

+3-89
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ module MetaCommit::Git
44
# Rugged::Repository wrapper
55
# @attr [Rugged::Repository] repo
66
class Repo
7+
extend Forwardable
8+
79
DIFF_OPTIONS = {:context_lines => 0, :ignore_whitespace => true}
810
INDEX_DIFF_OPTIONS = {:context_lines => 0, :ignore_whitespace => true, :reverse => true}
911

1012
FILE_NOT_EXISTS_OID = '0000000000000000000000000000000000000000'
1113

1214
attr_accessor :repo
15+
def_delegators :@repo, :diff, :path
1316

1417
# @param [String] repo_path
1518
def initialize(repo_path)
@@ -46,43 +49,6 @@ def walk_by_commits
4649
end
4750
end
4851

49-
# Proxy to Rugged::Repository#diff
50-
# @param [Object] left
51-
# @param [Object] right
52-
# @param [Hash] options
53-
# @return [Rugged::Diff::Delta]
54-
def diff(left, right, options)
55-
@repo.diff(left, right, options)
56-
end
57-
58-
# Iterates over optimized lines in diff
59-
# @param [Object] left
60-
# @param [Object] right
61-
# @yield [old_file_path, new_file_path, patch, line]
62-
# @return [Object]
63-
def diff_with_optimized_lines(left, right)
64-
diff = @repo.diff(left, right, DIFF_OPTIONS)
65-
diff.deltas.zip(diff.patches).each do |delta, patch|
66-
lines = organize_lines(delta, patch)
67-
lines.each do |line|
68-
yield(delta.old_file[:path], delta.new_file[:path], patch, line)
69-
end
70-
end
71-
end
72-
73-
# Iterates over optimized lines in index diff
74-
# @yield [old_file_path, new_file_path, patch, line]
75-
# @return [Object]
76-
def index_diff_with_optimized_lines
77-
diff = index_diff(INDEX_DIFF_OPTIONS)
78-
diff.deltas.zip(diff.patches).each do |delta, patch|
79-
lines = organize_lines(delta, patch)
80-
lines.each do |line|
81-
yield(delta.old_file[:path], delta.new_file[:path], patch, line)
82-
end
83-
end
84-
end
85-
8652
# Proxy to Rugged::Index#diff
8753
# @param [Hash] options
8854
# @return [Rugged::Diff::Delta]
@@ -112,11 +78,6 @@ def get_content_of(rel_repo_file_path, default = nil)
11278
content
11379
end
11480

115-
# @return [String] path to .git folder of repository
116-
def path
117-
@repo.path
118-
end
119-
12081
# @return [String] directory of repository
12182
def dir
12283
@repo.path.reverse.sub('/.git'.reverse, '').reverse
@@ -135,52 +96,5 @@ def last_commit_oid
13596
@repo.last_commit.oid
13697
end
13798

138-
# @param [Object] delta
139-
# @param [Object] patch
140-
# @return [Array<MetaCommit::Models::Line>]
141-
def organize_lines(delta, patch)
142-
lines_to_walk = []
143-
# if whole file was changed examine one time only
144-
whole_file_changed = (delta.old_file[:oid] == FILE_NOT_EXISTS_OID) || (delta.new_file[:oid] == FILE_NOT_EXISTS_OID)
145-
skip_walking = false
146-
skip_next_line = false
147-
patch.hunks.each_with_index do |hunk|
148-
break if skip_walking
149-
hunk.lines.each_with_index do |line, line_index|
150-
break if skip_walking
151-
152-
if skip_next_line
153-
skip_next_line = false
154-
next
155-
end
156-
157-
next_line = hunk.lines[line_index + 1]
158-
is_replace_change = (line.deletion?) && (!next_line.nil? && next_line.addition?) && (line.old_lineno && next_line.new_lineno)
159-
160-
line_to_walk = MetaCommit::Models::Line.new
161-
if is_replace_change
162-
line_to_walk.line_origin = :replace
163-
line_to_walk.old_lineno = line.old_lineno
164-
line_to_walk.new_lineno = next_line.new_lineno
165-
line_to_walk.content_offset = next_line.content_offset
166-
else
167-
line_to_walk.line_origin = line.line_origin
168-
line_to_walk.old_lineno = line.old_lineno
169-
line_to_walk.new_lineno = line.new_lineno
170-
line_to_walk.content_offset = line.content_offset
171-
end
172-
if is_replace_change
173-
skip_next_line = true
174-
end
175-
lines_to_walk.push(line_to_walk)
176-
177-
skip_walking = true if whole_file_changed
178-
end
179-
end
180-
lines_to_walk
181-
end
182-
183-
private :organize_lines
184-
18599
end
186100
end

lib/meta_commit/index/commands/diff_examiner.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ class DiffExaminer
44
# @param [MetaCommit::Services::Parse] parse_command
55
# @param [MetaCommit::Factories::ContextualAstNodeFactory] ast_path_factory
66
# @param [MetaCommit::Factories::DiffFactory] diff_factory
7-
def initialize(parse_command, ast_path_factory, diff_factory)
7+
# @param [MetaCommit::Factories::DiffFactory] diff_lines_provider
8+
def initialize(parse_command, ast_path_factory, diff_factory, diff_lines_provider)
89
@parse_command = parse_command
910
@ast_path_factory = ast_path_factory
1011
@diff_factory = diff_factory
12+
@diff_lines_provider = diff_lines_provider
1113
end
1214

1315
# Creates diff objects with meta information of changes in repository commits
@@ -27,7 +29,9 @@ def meta(repo)
2729
# @return [Array<MetaCommit::Contracts::Diff>]
2830
def examine_diff(repo, left_commit, right_commit)
2931
diffs = []
30-
repo.diff_with_optimized_lines(left_commit, right_commit) do |old_file_path, new_file_path, patch, line|
32+
repo_diff = repo.diff(left_commit, right_commit, MetaCommit::Git::Repo::DIFF_OPTIONS)
33+
diff_lines = @diff_lines_provider.from(repo_diff)
34+
diff_lines.each do |(old_file_path, new_file_path, patch, line)|
3135
old_file_content = repo.get_blob_at(left_commit.oid, old_file_path, '')
3236
new_file_content = repo.get_blob_at(right_commit.oid, new_file_path, '')
3337

lib/meta_commit/message/commands/diff_index_examiner.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@ class DiffIndexExaminer
44
# @param [MetaCommit::Services::Parse] parse_command
55
# @param [MetaCommit::Factories::ContextualAstNodeFactory] ast_path_factory
66
# @param [MetaCommit::Factories::DiffFactory] diff_factory
7-
def initialize(parse_command, ast_path_factory, diff_factory)
7+
# @param [MetaCommit::Factories::DiffFactory] diff_lines_provider
8+
def initialize(parse_command, ast_path_factory, diff_factory, diff_lines_provider)
89
@parse_command = parse_command
910
@ast_path_factory = ast_path_factory
1011
@diff_factory = diff_factory
12+
@diff_lines_provider = diff_lines_provider
1113
end
1214

1315
# Creates diff objects with meta information of changes in index staged files
1416
# @param [MetaCommit::Git::Repo] repo
1517
# @return [Array<MetaCommit::Contracts::Diff>]
1618
def index_meta(repo)
1719
diffs = MetaCommit::Models::Changes::Commit.new(repo.last_commit_oid, 'staged')
18-
repo.index_diff_with_optimized_lines do |old_file_path, new_file_path, patch, line|
20+
repo_diff = repo.index_diff(MetaCommit::Git::Repo::INDEX_DIFF_OPTIONS)
21+
diff_lines = @diff_lines_provider.from(repo_diff)
22+
diff_lines.each do |(old_file_path, new_file_path, patch, line)|
1923
commit_id_old = repo.last_commit_oid
2024
commit_id_new = 'staged'
2125

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
module MetaCommit::Services
2+
class DiffLinesProvider
3+
4+
# @param [Rugged::Diff::Delta] diff
5+
# @return [Array<Array>]
6+
def from(diff)
7+
result = []
8+
diff.deltas.zip(diff.patches).each do |delta, patch|
9+
lines = organize_lines(delta, patch)
10+
lines.each do |line|
11+
result.push [delta.old_file[:path], delta.new_file[:path], patch, line]
12+
end
13+
end
14+
result
15+
end
16+
17+
# @param [Object] delta
18+
# @param [Object] patch
19+
# @return [Array<MetaCommit::Models::Line>]
20+
def organize_lines(delta, patch)
21+
lines_to_walk = []
22+
# if whole file was changed examine one time only
23+
whole_file_changed = (delta.old_file[:oid] == MetaCommit::Git::Repo::FILE_NOT_EXISTS_OID) || (delta.new_file[:oid] == MetaCommit::Git::Repo::FILE_NOT_EXISTS_OID)
24+
skip_walking = false
25+
skip_next_line = false
26+
patch.hunks.each_with_index do |hunk|
27+
break if skip_walking
28+
hunk.lines.each_with_index do |line, line_index|
29+
break if skip_walking
30+
31+
if skip_next_line
32+
skip_next_line = false
33+
next
34+
end
35+
36+
next_line = hunk.lines[line_index + 1]
37+
is_replace_change = (line.deletion?) && (!next_line.nil? && next_line.addition?) && (line.old_lineno && next_line.new_lineno)
38+
39+
line_to_walk = MetaCommit::Models::Line.new
40+
if is_replace_change
41+
line_to_walk.line_origin = :replace
42+
line_to_walk.old_lineno = line.old_lineno
43+
line_to_walk.new_lineno = next_line.new_lineno
44+
line_to_walk.content_offset = next_line.content_offset
45+
else
46+
line_to_walk.line_origin = line.line_origin
47+
line_to_walk.old_lineno = line.old_lineno
48+
line_to_walk.new_lineno = line.new_lineno
49+
line_to_walk.content_offset = line.content_offset
50+
end
51+
if is_replace_change
52+
skip_next_line = true
53+
end
54+
lines_to_walk.push(line_to_walk)
55+
56+
skip_walking = true if whole_file_changed
57+
end
58+
end
59+
lines_to_walk
60+
end
61+
62+
protected :organize_lines
63+
end
64+
end

0 commit comments

Comments
 (0)