Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added auto correct with -a flag #19

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Or install it yourself as:
Usage: rubocop-git [options] [[commit] commit]
-c, --config FILE Specify configuration file
-r, --require FILE Require Ruby file
-a, --auto-correct Auto-correct offenses
-d, --debug Display debug info
-D, --display-cop-names Display cop names in offense messages
--cached git diff --cached
Expand Down
3 changes: 3 additions & 0 deletions lib/rubocop/git.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'rubocop/git/version'
require 'rubocop'
require 'tempfile'
require 'fileutils'

module RuboCop
module Git
Expand All @@ -15,5 +17,6 @@ module Git
autoload :Runner, 'rubocop/git/runner'
autoload :StyleChecker, 'rubocop/git/style_checker'
autoload :StyleGuide, 'rubocop/git/style_guide'
autoload :RuboComment, 'rubocop/git/rubo_comment'
end
end
4 changes: 4 additions & 0 deletions lib/rubocop/git/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def option_parser
require file
end

opt.on('-a', '--auto-correct', 'Auto-correct offenses.') do
@options.rubocop[:auto_correct] = true
end

opt.on('-d', '--debug', 'Display debug info') do
@options.rubocop[:debug] = true
end
Expand Down
29 changes: 28 additions & 1 deletion lib/rubocop/git/patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ class Patch
RANGE_INFORMATION_LINE = /^@@ .+\+(?<line_number>\d+),/
MODIFIED_LINE = /^\+(?!\+|\+)/
NOT_REMOVED_LINE = /^[^-]/
PATCH_INFO_LINE = /\+([0-9,]+)/

def initialize(body)
@body = body || ''
@changes = []
end

def additions
line_number = 0

lines.each_with_index.inject([]) do |additions, (content, patch_position)|
lines.each_with_index.inject(@changes) do |additions, (content, patch_position)|
case content
when RANGE_INFORMATION_LINE
line_number = Regexp.last_match[:line_number].to_i
Expand All @@ -27,6 +29,31 @@ def additions
end
end

# maps out additions line numbers to indicate start and end of code changes
# [[5,7], [11,11]] indicates changes from line 5, 6, 7 and then
# another one at 11
def additions_map
if @changes.empty?
self.additions
end

map = []
starting_line = ending_line = 0

@changes.each do |addition|
if starting_line == 0
starting_line = ending_line = addition.line_number
elsif addition.line_number == ( ending_line + 1 )
ending_line = addition.line_number
else # this row is not part of the last rows "group"
map.push([starting_line, ending_line])
starting_line = ending_line = addition.line_number
end
end
map.push([starting_line, ending_line])
map
end

private

def lines
Expand Down
92 changes: 92 additions & 0 deletions lib/rubocop/git/rubo_comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
module RuboCop::Git
class RuboComment
RUBOCOP_DISABLE = "# rubocop:disable all\n"
RUBOCOP_ENABLE = "# rubocop:enable all\n"
WHITE_SPACE = /^\s*/

def initialize(files)
@edit_map = {}
@files = files
end

# adds rubocop enable and disabled comments to files
# making sure only edited lines are processed by rubocop
def add_comments
@files.each do |file|
patch_info = Patch.new(file.patch).additions_map
temp_file = Tempfile.new('temp')

line_count = edited_line_count = current_patch = 0
in_patch = false
edit_locations = []

begin
File.open(file.filename, "r").each_line do |line|
line_count += 1
edited_line_count += 1

if line_count == patch_info[current_patch].first
temp_file.puts generate_spaces(line) + RUBOCOP_ENABLE
in_patch = true
edit_locations.push edited_line_count
edited_line_count += 1

elsif in_patch && patch_info[current_patch].last + 1 == line_count
temp_file.puts generate_spaces(line) + RUBOCOP_DISABLE
in_patch = false
edit_locations.push edited_line_count
edited_line_count += 1
current_patch += 1 unless (current_patch + 1) >= patch_info.size

elsif line_count == 1 #adds disable at top of file
temp_file.puts generate_spaces(line) + RUBOCOP_DISABLE
edit_locations.push edited_line_count
edited_line_count += 1

end
temp_file.puts line
end

temp_file.close
FileUtils.mv(temp_file.path, file.filename)
@edit_map[file.filename] = edit_locations
ensure
temp_file.close
temp_file.unlink
end
end
end

# removes all added comments that where added from add_comments
def remove_comments
@files.each do |file|
temp_file = Tempfile.new('temp')
line_count = 0

begin
File.open(file.filename, "r").each_line do |line|
line_count += 1
temp_file.puts line unless @edit_map[file.filename].find_index line_count
end

temp_file.close
FileUtils.mv(temp_file.path, file.filename)
ensure
temp_file.close
temp_file.unlink
end
end
end

private

# generates whitespaces to make en/disable comments match line indent
# preventing rubocop errors
def generate_spaces(line)
whitespaces = ""
WHITE_SPACE.match(line).to_s.split('').size.times { whitespaces << " " }
whitespaces
end

end
end
9 changes: 8 additions & 1 deletion lib/rubocop/git/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ def run(options)

@options = options
@files = DiffParser.parse(git_diff(options))
rubo_comment = RuboComment.new(@files)

#adds comments to files and reparses diff after changes are made
rubo_comment.add_comments
@files = DiffParser.parse(git_diff(options))

display_violations($stdout)
#removes comments after rubocop processing
rubo_comment.remove_comments

exit(1) if violations.any?
end
Expand Down Expand Up @@ -45,7 +52,7 @@ def git_diff(options)
def display_violations(io)
formatter = RuboCop::Formatter::ClangStyleFormatter.new(io)
formatter.started(nil)

violations.map do |violation|
formatter.file_finished(
violation.filename,
Expand Down