overcommit 0.1.11 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,7 +30,7 @@ module Overcommit
30
30
  next if check_class.filetype && check.staged.empty?
31
31
 
32
32
  reporter.with_status(check) do
33
- check.run_check
33
+ run_and_filter_check(check)
34
34
  end
35
35
  end
36
36
 
@@ -67,6 +67,20 @@ module Overcommit
67
67
  def requires_modified_files?
68
68
  false
69
69
  end
70
+
71
+ # Filters temporary staged file names from the output of the check and
72
+ # replaces them with their original filenames.
73
+ def run_and_filter_check(check)
74
+ status, output = check.run_check
75
+
76
+ if output && !output.empty?
77
+ check.staged.each do |staged_file|
78
+ output = staged_file.filter_string(output)
79
+ end
80
+ end
81
+
82
+ [status, output]
83
+ end
70
84
  end
71
85
  end
72
86
  end
@@ -51,7 +51,7 @@ module Overcommit
51
51
  end
52
52
 
53
53
  def staged
54
- @staged ||= Utils.modified_files.map do |filename|
54
+ @staged ||= modified_files.map do |filename|
55
55
  if self.class.filetype.nil? || filename.end_with?(".#{self.class.filetype}")
56
56
  StagedFile.new(filename)
57
57
  end
@@ -11,7 +11,6 @@ module Overcommit::GitHook
11
11
  paths = staged.map { |s| s.path }.join(' ')
12
12
 
13
13
  output = `rhino #{CSS_LINTER_PATH} --quiet --format=compact #{paths} | grep 'Error - '`
14
- staged.each { |s| output = s.filter_string(output) }
15
14
  return (output !~ /Error - (?!Unknown @ rule)/ ? :good : :bad), output
16
15
  end
17
16
  end
@@ -15,7 +15,6 @@ module Overcommit::GitHook
15
15
 
16
16
  def run_check
17
17
  output = `bundle exec #{ERB_CHECKER} #{staged.map{ |file| file.path }.join(' ')}`
18
- staged.each { |s| output = s.filter_string(output) }
19
18
  return (output !~ /: compile error$/ ? :good : :bad), output
20
19
  end
21
20
  end
@@ -10,7 +10,6 @@ module Overcommit::GitHook
10
10
  /^\d+:\s*\/\// =~ line || # Skip comments
11
11
  /ALLOW_CONSOLE_LOG/ =~ line # and lines with ALLOW_CONSOLE_LOG
12
12
  end.join("\n")
13
- staged.each { |s| output = s.filter_string(output) }
14
13
  return (output.empty? ? :good : :bad), output
15
14
  end
16
15
  end
@@ -8,7 +8,6 @@ module Overcommit::GitHook
8
8
 
9
9
  paths = staged.map { |s| s.path }.join(' ')
10
10
  output = runner.call(paths)
11
- staged.each { |s| output = s.filter_string(output) }
12
11
 
13
12
  return (output.empty? ? :good : :bad), output
14
13
  end
@@ -8,13 +8,24 @@ module Overcommit::GitHook
8
8
  return :warn, 'rubocop not installed -- run `gem install rubocop`'
9
9
  end
10
10
 
11
- paths = staged.map { |s| s.path }.join(' ')
11
+ paths_to_staged_files = Hash[staged.map { |s| [s.path, s] }]
12
+ staged_files = paths_to_staged_files.keys
12
13
 
13
- output = `rubocop #{paths} 2>&1`
14
+ output = `rubocop --format=emacs --silent #{staged_files.join(' ')} 2>&1`
14
15
  return :good if $?.success?
15
16
 
16
- staged.each { |s| output = s.filter_string(output) }
17
- return :bad, output
17
+ # Keep lines from the output for files that we actually modified
18
+ error_lines, warning_lines = output.lines.partition do |output_line|
19
+ if match = output_line.match(/^([^:]+):(\d+)/)
20
+ file = match[1]
21
+ line = match[2]
22
+ end
23
+ paths_to_staged_files[file].modified_lines.include?(line.to_i)
24
+ end
25
+
26
+ return :bad, error_lines.join unless error_lines.empty?
27
+ return :warn, "Modified files have style lints (on lines you didn't modify)\n" <<
28
+ warning_lines.join
18
29
  end
19
30
  end
20
31
  end
@@ -9,7 +9,7 @@ module Overcommit::GitHook
9
9
  staged.each do |staged|
10
10
  syntax = `ruby -c #{staged.path} 2>&1`
11
11
  unless $?.success?
12
- output += staged.filter_string(syntax).lines.to_a
12
+ output += syntax.lines.to_a
13
13
  clean = false
14
14
  end
15
15
  end
@@ -14,7 +14,6 @@ module Overcommit::GitHook
14
14
 
15
15
  output = `scss-lint #{paths} 2>&1`
16
16
 
17
- staged.each { |s| output = s.filter_string(output) }
18
17
  return (output.empty? ? :good : :bad), output
19
18
  end
20
19
  end
@@ -7,7 +7,6 @@ module Overcommit::GitHook
7
7
 
8
8
  # Catches hard tabs
9
9
  output = `grep -Inl "\t" #{paths}`
10
- staged.each { |s| output = s.filter_string(output) }
11
10
  unless output.empty?
12
11
  return :stop, "Don't use hard tabs:\n#{output}"
13
12
  end
@@ -1,13 +1,14 @@
1
+ require 'set'
1
2
  require 'tempfile'
3
+
2
4
  # We run syntax checks against the version of the file that is staged in
3
5
  # the index, not the one in the work tree. This class is a simple wrapper
4
6
  # to make working with staged files easier.
5
-
6
7
  module Overcommit
7
8
  class StagedFile
8
9
  attr_reader :contents
9
10
 
10
- def initialize path
11
+ def initialize(path)
11
12
  @original_path = path
12
13
  @tempfile = Tempfile.new([path.gsub('/', '_'), File.extname(path)])
13
14
  self.contents = `git show :#{@original_path}`
@@ -15,7 +16,7 @@ module Overcommit
15
16
 
16
17
  # Given error output from a syntax checker, replace references to the
17
18
  # temporary file path with the original path.
18
- def filter_string string
19
+ def filter_string(string)
19
20
  string.gsub(path, @original_path)
20
21
  end
21
22
 
@@ -35,5 +36,38 @@ module Overcommit
35
36
  @tempfile.write @contents
36
37
  @tempfile.flush
37
38
  end
39
+
40
+ # Returns the set of line numbers corresponding to the lines that were
41
+ # changed in this file.
42
+ def modified_lines
43
+ @modified_lines ||= extract_modified_lines
44
+ end
45
+
46
+ private
47
+
48
+ DIFF_HUNK_REGEX = /
49
+ ^@@\s
50
+ [^\s]+\s # Ignore old file range
51
+ \+(\d+)(?:,(\d+))? # Extract range of hunk containing start line and number of lines
52
+ \s@@.*$
53
+ /x
54
+
55
+ def extract_modified_lines
56
+ lines = Set.new
57
+
58
+ `git diff --cached -U0 -- #{@original_path}`.
59
+ scan(DIFF_HUNK_REGEX) do |start_line, lines_added|
60
+
61
+ lines_added = (lines_added || 1).to_i # When blank, one line was added
62
+ cur_line = start_line.to_i
63
+
64
+ lines_added.times do
65
+ lines.add cur_line
66
+ cur_line += 1
67
+ end
68
+ end
69
+
70
+ lines
71
+ end
38
72
  end
39
73
  end
@@ -50,8 +50,7 @@ module Overcommit
50
50
  # Get a list of staged Added, Copied, or Modified files (ignore renames
51
51
  # and deletions, since there should be nothing to check).
52
52
  def modified_files
53
- @modified_files ||=
54
- `git diff --cached --name-only --diff-filter=ACM`.split "\n"
53
+ `git diff --cached --name-only --diff-filter=ACM`.split "\n"
55
54
  end
56
55
 
57
56
  private
@@ -1,3 +1,3 @@
1
1
  module Overcommit
2
- VERSION = '0.1.11'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: overcommit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-10 00:00:00.000000000 Z
12
+ date: 2013-07-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec