From d9bf9ef631d76cfe78bb75f6dd5a802332cfdce6 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Wed, 23 Mar 2016 00:28:21 -0400 Subject: [PATCH 1/7] Enabled Auto-correct functionality with -a flag --- lib/rubocop/git/cli.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/rubocop/git/cli.rb b/lib/rubocop/git/cli.rb index b302510..ed53bf3 100644 --- a/lib/rubocop/git/cli.rb +++ b/lib/rubocop/git/cli.rb @@ -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 From ec358f6feca0a739ec62c4b17255c6d0326f6879 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Wed, 23 Mar 2016 00:34:12 -0400 Subject: [PATCH 2/7] Updated Readme.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6c5a4c9..33e6ead 100644 --- a/README.md +++ b/README.md @@ -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 From c2d9a507e9971413fbb19f264ddac69439fc6fa7 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Wed, 23 Mar 2016 00:34:57 -0400 Subject: [PATCH 3/7] removed comma in readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33e6ead..14f63f0 100644 --- a/README.md +++ b/README.md @@ -25,7 +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. + -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 From ebb9f1a4cca7602ea65bfbe116793ab574ba5c40 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Fri, 1 Apr 2016 22:48:27 -0400 Subject: [PATCH 4/7] Added autocorrect feature --- lib/rubocop/git.rb | 3 ++ lib/rubocop/git/patch.rb | 29 ++++++++++- lib/rubocop/git/rubo_comment.rb | 85 +++++++++++++++++++++++++++++++++ lib/rubocop/git/runner.rb | 12 ++++- 4 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 lib/rubocop/git/rubo_comment.rb diff --git a/lib/rubocop/git.rb b/lib/rubocop/git.rb index 86034e7..bf95227 100644 --- a/lib/rubocop/git.rb +++ b/lib/rubocop/git.rb @@ -1,5 +1,7 @@ require 'rubocop/git/version' require 'rubocop' +require 'tempfile' +require 'fileutils' module RuboCop module Git @@ -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 diff --git a/lib/rubocop/git/patch.rb b/lib/rubocop/git/patch.rb index 02da7f5..bab4081 100644 --- a/lib/rubocop/git/patch.rb +++ b/lib/rubocop/git/patch.rb @@ -4,15 +4,17 @@ class Patch RANGE_INFORMATION_LINE = /^@@ .+\+(?\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 @@ -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 diff --git a/lib/rubocop/git/rubo_comment.rb b/lib/rubocop/git/rubo_comment.rb new file mode 100644 index 0000000..bfc0c7b --- /dev/null +++ b/lib/rubocop/git/rubo_comment.rb @@ -0,0 +1,85 @@ +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 + #create temp file for processing + temp_file = Tempfile.new('temp') + #open file + 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 diff --git a/lib/rubocop/git/runner.rb b/lib/rubocop/git/runner.rb index 1264ab3..00cc2b4 100644 --- a/lib/rubocop/git/runner.rb +++ b/lib/rubocop/git/runner.rb @@ -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 @@ -45,14 +52,15 @@ def git_diff(options) def display_violations(io) formatter = RuboCop::Formatter::ClangStyleFormatter.new(io) formatter.started(nil) - + #binding.pry violations.map do |violation| + #binding.pry formatter.file_finished( violation.filename, violation.offenses.compact.sort.freeze ) end - + #binding.pry formatter.finished(@files.map(&:filename).freeze) end end From 8779f43f46920f02c726f5c72e368c26a6c6df6d Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Fri, 1 Apr 2016 22:54:19 -0400 Subject: [PATCH 5/7] Cleaned up comments --- lib/rubocop/git/rubo_comment.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/rubocop/git/rubo_comment.rb b/lib/rubocop/git/rubo_comment.rb index bfc0c7b..03a99d4 100644 --- a/lib/rubocop/git/rubo_comment.rb +++ b/lib/rubocop/git/rubo_comment.rb @@ -14,9 +14,7 @@ def initialize(files) def add_comments @files.each do |file| patch_info = Patch.new(file.patch).additions_map - #create temp file for processing temp_file = Tempfile.new('temp') - #open file line_count = edited_line_count = current_patch = 0 in_patch = false edit_locations = [] From 7b79c6dfd4391d4e2c869666660f10ed5f063510 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Fri, 1 Apr 2016 22:57:55 -0400 Subject: [PATCH 6/7] Cleaned up binding.pry commented out code --- lib/rubocop/git/runner.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/rubocop/git/runner.rb b/lib/rubocop/git/runner.rb index 00cc2b4..da5eff3 100644 --- a/lib/rubocop/git/runner.rb +++ b/lib/rubocop/git/runner.rb @@ -52,15 +52,12 @@ def git_diff(options) def display_violations(io) formatter = RuboCop::Formatter::ClangStyleFormatter.new(io) formatter.started(nil) - #binding.pry violations.map do |violation| - #binding.pry formatter.file_finished( violation.filename, violation.offenses.compact.sort.freeze ) end - #binding.pry formatter.finished(@files.map(&:filename).freeze) end end From 549b184fec8ade5d494733b639a43dd018d1b882 Mon Sep 17 00:00:00 2001 From: Nicholas Gillespie Date: Fri, 1 Apr 2016 23:02:56 -0400 Subject: [PATCH 7/7] added some line breaks to make code easier to read --- lib/rubocop/git/rubo_comment.rb | 9 +++++++++ lib/rubocop/git/runner.rb | 2 ++ 2 files changed, 11 insertions(+) diff --git a/lib/rubocop/git/rubo_comment.rb b/lib/rubocop/git/rubo_comment.rb index 03a99d4..d2c53bc 100644 --- a/lib/rubocop/git/rubo_comment.rb +++ b/lib/rubocop/git/rubo_comment.rb @@ -15,31 +15,38 @@ 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 @@ -55,11 +62,13 @@ 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 diff --git a/lib/rubocop/git/runner.rb b/lib/rubocop/git/runner.rb index da5eff3..4945e2a 100644 --- a/lib/rubocop/git/runner.rb +++ b/lib/rubocop/git/runner.rb @@ -52,12 +52,14 @@ 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, violation.offenses.compact.sort.freeze ) end + formatter.finished(@files.map(&:filename).freeze) end end