overcommit 0.27.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/bin/overcommit +0 -1
  3. data/config/default.yml +155 -2
  4. data/lib/overcommit.rb +2 -0
  5. data/lib/overcommit/cli.rb +1 -0
  6. data/lib/overcommit/configuration.rb +1 -1
  7. data/lib/overcommit/git_repo.rb +1 -2
  8. data/lib/overcommit/hook/base.rb +1 -1
  9. data/lib/overcommit/hook/commit_msg/gerrit_change_id.rb +1 -1
  10. data/lib/overcommit/hook/post_checkout/bower_install.rb +11 -0
  11. data/lib/overcommit/hook/post_checkout/bundle_install.rb +11 -0
  12. data/lib/overcommit/hook/post_checkout/npm_install.rb +11 -0
  13. data/lib/overcommit/hook/post_commit/bower_install.rb +11 -0
  14. data/lib/overcommit/hook/post_commit/bundle_install.rb +11 -0
  15. data/lib/overcommit/hook/post_commit/npm_install.rb +11 -0
  16. data/lib/overcommit/hook/post_merge/bower_install.rb +11 -0
  17. data/lib/overcommit/hook/post_merge/bundle_install.rb +11 -0
  18. data/lib/overcommit/hook/post_merge/npm_install.rb +11 -0
  19. data/lib/overcommit/hook/post_rewrite/bower_install.rb +11 -0
  20. data/lib/overcommit/hook/post_rewrite/bundle_install.rb +11 -0
  21. data/lib/overcommit/hook/post_rewrite/npm_install.rb +11 -0
  22. data/lib/overcommit/hook/pre_commit/base.rb +1 -1
  23. data/lib/overcommit/hook/pre_commit/chamber_security.rb +1 -1
  24. data/lib/overcommit/hook/pre_commit/coffee_lint.rb +19 -27
  25. data/lib/overcommit/hook/pre_commit/css_lint.rb +2 -2
  26. data/lib/overcommit/hook/pre_commit/es_lint.rb +2 -2
  27. data/lib/overcommit/hook/pre_commit/execute_permissions.rb +64 -0
  28. data/lib/overcommit/hook/pre_commit/go_lint.rb +2 -2
  29. data/lib/overcommit/hook/pre_commit/go_vet.rb +2 -2
  30. data/lib/overcommit/hook/pre_commit/haml_lint.rb +2 -2
  31. data/lib/overcommit/hook/pre_commit/hard_tabs.rb +1 -1
  32. data/lib/overcommit/hook/pre_commit/hlint.rb +32 -0
  33. data/lib/overcommit/hook/pre_commit/html_hint.rb +1 -1
  34. data/lib/overcommit/hook/pre_commit/html_tidy.rb +1 -1
  35. data/lib/overcommit/hook/pre_commit/image_optim.rb +1 -1
  36. data/lib/overcommit/hook/pre_commit/java_checkstyle.rb +2 -2
  37. data/lib/overcommit/hook/pre_commit/js_hint.rb +2 -2
  38. data/lib/overcommit/hook/pre_commit/js_lint.rb +2 -2
  39. data/lib/overcommit/hook/pre_commit/jscs.rb +2 -2
  40. data/lib/overcommit/hook/pre_commit/jsl.rb +1 -1
  41. data/lib/overcommit/hook/pre_commit/pep257.rb +2 -2
  42. data/lib/overcommit/hook/pre_commit/pep8.rb +2 -2
  43. data/lib/overcommit/hook/pre_commit/puppet_lint.rb +24 -0
  44. data/lib/overcommit/hook/pre_commit/pyflakes.rb +2 -2
  45. data/lib/overcommit/hook/pre_commit/pylint.rb +2 -2
  46. data/lib/overcommit/hook/pre_commit/python_flake8.rb +2 -2
  47. data/lib/overcommit/hook/pre_commit/reek.rb +2 -2
  48. data/lib/overcommit/hook/pre_commit/rubo_cop.rb +2 -2
  49. data/lib/overcommit/hook/pre_commit/ruby_lint.rb +2 -2
  50. data/lib/overcommit/hook/pre_commit/scalariform.rb +2 -2
  51. data/lib/overcommit/hook/pre_commit/scalastyle.rb +2 -2
  52. data/lib/overcommit/hook/pre_commit/scss_lint.rb +2 -2
  53. data/lib/overcommit/hook/pre_commit/semi_standard.rb +5 -3
  54. data/lib/overcommit/hook/pre_commit/shell_check.rb +2 -2
  55. data/lib/overcommit/hook/pre_commit/slim_lint.rb +2 -2
  56. data/lib/overcommit/hook/pre_commit/sqlint.rb +24 -0
  57. data/lib/overcommit/hook/pre_commit/standard.rb +5 -3
  58. data/lib/overcommit/hook/pre_commit/trailing_whitespace.rb +1 -1
  59. data/lib/overcommit/hook/pre_commit/travis_lint.rb +1 -1
  60. data/lib/overcommit/hook/pre_commit/vint.rb +2 -2
  61. data/lib/overcommit/hook/pre_commit/xml_lint.rb +2 -2
  62. data/lib/overcommit/hook/shared/bower_install.rb +13 -0
  63. data/lib/overcommit/hook/shared/bundle_install.rb +13 -0
  64. data/lib/overcommit/hook/shared/npm_install.rb +13 -0
  65. data/lib/overcommit/hook_context/base.rb +2 -2
  66. data/lib/overcommit/hook_context/pre_commit.rb +1 -1
  67. data/lib/overcommit/hook_context/run_all.rb +5 -0
  68. data/lib/overcommit/hook_signer.rb +2 -1
  69. data/lib/overcommit/installer.rb +4 -2
  70. data/lib/overcommit/os.rb +34 -0
  71. data/lib/overcommit/printer.rb +1 -1
  72. data/lib/overcommit/subprocess.rb +19 -1
  73. data/lib/overcommit/utils.rb +17 -5
  74. data/lib/overcommit/utils/file_utils.rb +69 -0
  75. data/lib/overcommit/version.rb +1 -1
  76. data/template-dir/hooks/commit-msg +2 -0
  77. data/template-dir/hooks/overcommit-hook +2 -0
  78. data/template-dir/hooks/post-checkout +2 -0
  79. data/template-dir/hooks/post-commit +2 -0
  80. data/template-dir/hooks/post-merge +2 -0
  81. data/template-dir/hooks/post-rewrite +2 -0
  82. data/template-dir/hooks/pre-commit +2 -0
  83. data/template-dir/hooks/pre-push +2 -0
  84. data/template-dir/hooks/pre-rebase +2 -0
  85. metadata +23 -16
@@ -0,0 +1,11 @@
1
+ require 'overcommit/hook/shared/bundle_install'
2
+
3
+ module Overcommit::Hook::PostRewrite
4
+ # Runs `bundle install` when a change is detected in the repository's
5
+ # dependencies.
6
+ #
7
+ # @see {Overcommit::Hook::Shared::BundleInstall}
8
+ class BundleInstall < Base
9
+ include Overcommit::Hook::Shared::BundleInstall
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'overcommit/hook/shared/npm_install'
2
+
3
+ module Overcommit::Hook::PostRewrite
4
+ # Runs `npm install` when a change is detected in the repository's
5
+ # dependencies.
6
+ #
7
+ # @see {Overcommit::Hook::Shared::NpmInstall}
8
+ class NpmInstall < Base
9
+ include Overcommit::Hook::Shared::NpmInstall
10
+ end
11
+ end
@@ -5,7 +5,7 @@ module Overcommit::Hook::PreCommit
5
5
  class Base < Overcommit::Hook::Base
6
6
  extend Forwardable
7
7
 
8
- def_delegators :@context, :modified_lines_in_file, :amendment?
8
+ def_delegators :@context, :modified_lines_in_file, :amendment?, :initial_commit?
9
9
 
10
10
  private
11
11
 
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://github.com/thekompanee/chamber
5
5
  class ChamberSecurity < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
 
9
9
  return :pass if result.stdout.empty?
10
10
  [:fail, "These settings appear to need to be secured but were not: #{result.stdout}"]
@@ -3,38 +3,30 @@ module Overcommit::Hook::PreCommit
3
3
  #
4
4
  # @see http://www.coffeelint.org/
5
5
  class CoffeeLint < Base
6
- def run
7
- result = execute(command + applicable_files)
6
+ MESSAGE_REGEX = /
7
+ ^(?<file>.+)
8
+ ,(?<line>\d*),\d*
9
+ ,(?<type>\w+)
10
+ ,(?<msg>.+)$
11
+ /x
8
12
 
9
- begin
10
- parse_json_messages(result.stdout)
11
- rescue JSON::ParserError => e
12
- [:fail, "Error parsing coffeelint output: #{e.message}"]
13
- end
13
+ MESSAGE_TYPE_CATEGORIZER = lambda do |type|
14
+ type.include?('w') ? :warning : :error
14
15
  end
15
16
 
16
- private
17
-
18
- def parse_json_messages(output)
19
- JSON.parse(output).collect do |file, messages|
20
- messages.collect { |msg| extract_message(file, msg) }
21
- end.flatten
17
+ def run
18
+ result = execute(command, args: applicable_files)
19
+ parse_messages(result.stdout)
22
20
  end
23
21
 
24
- def extract_message(file, message_hash)
25
- type = message_hash['level'].include?('w') ? :warning : :error
26
- line = message_hash['lineNumber']
27
- rule = message_hash['rule']
28
- msg = message_hash['message']
29
- text =
30
- if rule == 'coffeescript_error'
31
- # Syntax errors are output in different format.
32
- # Splice in the file name and grab the first line.
33
- msg.sub('[stdin]', file).split("\n")[0]
34
- else
35
- "#{file}:#{line}: #{msg} (#{rule})"
36
- end
37
- Overcommit::Hook::Message.new(type, file, line, text)
22
+ private
23
+
24
+ def parse_messages(output)
25
+ output.scan(MESSAGE_REGEX).map do |file, line, type, msg|
26
+ type = MESSAGE_TYPE_CATEGORIZER.call(type)
27
+ text = "#{file}:#{line}:#{type} #{msg}"
28
+ Overcommit::Hook::Message.new(type, file, line, text)
29
+ end
38
30
  end
39
31
  end
40
32
  end
@@ -4,13 +4,13 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://github.com/CSSLint/csslint
5
5
  class CssLint < Base
6
6
  MESSAGE_REGEX = /
7
- ^(?<file>[^:]+):\s
7
+ ^(?<file>(?:\w:)?[^:]+):\s
8
8
  (?:line\s(?<line>\d+)[^EW]+)?
9
9
  (?<type>Error|Warning)
10
10
  /x
11
11
 
12
12
  def run
13
- result = execute(command + applicable_files)
13
+ result = execute(command, args: applicable_files)
14
14
  output = result.stdout.chomp
15
15
  return :pass if result.success? && output.empty?
16
16
 
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see http://eslint.org/
5
5
  class EsLint < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  output = result.stdout.chomp
9
9
  return :pass if result.success? && output.empty?
10
10
 
@@ -12,7 +12,7 @@ module Overcommit::Hook::PreCommit
12
12
  # path/to/file.js: line 1, col 0, Error - Error message (ruleName)
13
13
  extract_messages(
14
14
  output.split("\n").grep(/Warning|Error/),
15
- /^(?<file>[^:]+):[^\d]+(?<line>\d+).*?(?<type>Error|Warning)/,
15
+ /^(?<file>(?:\w:)?[^:]+):[^\d]+(?<line>\d+).*?(?<type>Error|Warning)/,
16
16
  lambda { |type| type.downcase.to_sym }
17
17
  )
18
18
  end
@@ -0,0 +1,64 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Checks for files with execute permissions, which are usually not necessary
3
+ # in source code files (and are typically caused by a misconfigured editor
4
+ # assigning incorrect default permissions).
5
+ class ExecutePermissions < Base
6
+ def run
7
+ file_modes = {}
8
+
9
+ # We have to look in two places to determine the execute permissions of a
10
+ # file. The first is the Git tree for currently known file modes of all
11
+ # files, the second is the index for any staged changes to file modes.
12
+ # Staged changes take priority if they exist.
13
+ #
14
+ # This complexity is necessary because this hook can be run in the RunAll
15
+ # context, where there may be no staged changes but we stil want to check
16
+ # the permissions.
17
+ extract_from_git_tree(file_modes) unless initial_commit?
18
+ extract_from_git_index(file_modes)
19
+
20
+ file_modes.map do |file, mode|
21
+ next unless execute_permissions?(mode)
22
+
23
+ Overcommit::Hook::Message.new(
24
+ :error,
25
+ file,
26
+ nil,
27
+ "File #{file} has unnecessary execute permissions",
28
+ )
29
+ end.compact
30
+ end
31
+
32
+ private
33
+
34
+ def extract_from_git_tree(file_modes)
35
+ result = execute(%w[git ls-tree HEAD --], args: applicable_files)
36
+ raise 'Unable to access git tree' unless result.success?
37
+
38
+ result.stdout.split("\n").each do |line|
39
+ mode, _type, _hash, file = line.split(/\s+/, 4)
40
+ file_modes[file] = mode
41
+ end
42
+ end
43
+
44
+ def extract_from_git_index(file_modes)
45
+ result = execute(%w[git diff --raw --cached --], args: applicable_files)
46
+ raise 'Unable to access git index' unless result.success?
47
+
48
+ result.stdout.split("\n").each do |line|
49
+ _old_mode, new_mode, _old_hash, _new_hash, _status, file = line.split(/\s+/, 6)
50
+ file_modes[file] = new_mode
51
+ end
52
+ end
53
+
54
+ # Check if the 1st bit is toggled, indicating execute permissions.
55
+ #
56
+ # Git tracks only execute permissions, not individual read/write/execute
57
+ # permissions for user, group, and other, since that concept does not exist
58
+ # on all operating systems. If any of the user/group/other permissions
59
+ # have the executable bit set, they all will. Thus we check the first bit.
60
+ def execute_permissions?(mode)
61
+ (mode.to_i(8) & 1) == 1
62
+ end
63
+ end
64
+ end
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://github.com/golang/lint
5
5
  class GoLint < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  output = result.stdout + result.stderr
9
9
  # Unfortunately the exit code is always 0
10
10
  return :pass if output.empty?
@@ -13,7 +13,7 @@ module Overcommit::Hook::PreCommit
13
13
  # path/to/file.go:1:1: Error message
14
14
  extract_messages(
15
15
  output.split("\n"),
16
- /^(?<file>[^:]+):(?<line>\d+)/
16
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/
17
17
  )
18
18
  end
19
19
  end
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://godoc.org/code.google.com/p/go-zh.tools/cmd/vet
5
5
  class GoVet < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  return :pass if result.success?
9
9
 
10
10
  if result.stderr =~ /no such tool "vet"/
@@ -15,7 +15,7 @@ module Overcommit::Hook::PreCommit
15
15
  # path/to/file.go:7: Error message
16
16
  extract_messages(
17
17
  result.stderr.split("\n"),
18
- /^(?<file>[^:]+):(?<line>\d+)/
18
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/
19
19
  )
20
20
  end
21
21
  end
@@ -8,12 +8,12 @@ module Overcommit::Hook::PreCommit
8
8
  end
9
9
 
10
10
  def run
11
- result = execute(command + applicable_files)
11
+ result = execute(command, args: applicable_files)
12
12
  return :pass if result.success?
13
13
 
14
14
  extract_messages(
15
15
  result.stdout.split("\n"),
16
- /^(?<file>[^:]+):(?<line>\d+)[^ ]* (?<type>[^ ]+)/,
16
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)[^ ]* (?<type>[^ ]+)/,
17
17
  MESSAGE_TYPE_CATEGORIZER,
18
18
  )
19
19
  end
@@ -6,7 +6,7 @@ module Overcommit::Hook::PreCommit
6
6
 
7
7
  extract_messages(
8
8
  result.stdout.split("\n"),
9
- /^(?<file>[^:]+):(?<line>\d+)/,
9
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/,
10
10
  )
11
11
  end
12
12
  end
@@ -0,0 +1,32 @@
1
+ module Overcommit::Hook::PreCommit
2
+ # Runs `hlint` against any modified Haskell files.
3
+ #
4
+ # @see https://github.com/ndmitchell/hlint
5
+ class Hlint < Base
6
+ MESSAGE_REGEX = /
7
+ ^(?<file>(?:\w:)?[^:]+)
8
+ :(?<line>\d+)
9
+ :\d+
10
+ :\s*(?<type>\w+)
11
+ /x
12
+
13
+ MESSAGE_TYPE_CATEGORIZER = lambda do |type|
14
+ type.include?('W') ? :warning : :error
15
+ end
16
+
17
+ def run
18
+ result = execute(command, args: applicable_files)
19
+ return :pass if result.success?
20
+
21
+ raw_messages = result.stdout.split("\n").grep(MESSAGE_REGEX)
22
+
23
+ # example message:
24
+ # path/to/file.hs:1:0: Error: message
25
+ extract_messages(
26
+ raw_messages,
27
+ MESSAGE_REGEX,
28
+ MESSAGE_TYPE_CATEGORIZER
29
+ )
30
+ end
31
+ end
32
+ end
@@ -13,7 +13,7 @@ module Overcommit::Hook::PreCommit
13
13
  file = lines[0][/(.+):/, 1]
14
14
  extract_messages(
15
15
  lines[1..-1].map { |msg| "#{file}: #{msg}" },
16
- /^(?<file>[^:]+): line (?<line>\d+)/
16
+ /^(?<file>(?:\w:)?[^:]+): line (?<line>\d+)/
17
17
  )
18
18
  end.flatten
19
19
  end
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see http://www.html-tidy.org/
5
5
  class HtmlTidy < Base
6
6
  MESSAGE_REGEX = /
7
- ^(?<file>[^:]+):\s
7
+ ^(?<file>(?:\w:)?[^:]+):\s
8
8
  line\s(?<line>\d+)\s
9
9
  column\s(?<col>\d+)\s-\s
10
10
  (?<type>Error|Warning):\s(?<message>.+)$
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://github.com/toy/image_optim
5
5
  class ImageOptim < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  return [:fail, result.stdout + result.stderr] unless result.success?
9
9
 
10
10
  optimized_files = extract_optimized_files(result.stdout)
@@ -3,10 +3,10 @@ module Overcommit::Hook::PreCommit
3
3
  #
4
4
  # @see http://checkstyle.sourceforge.net/
5
5
  class JavaCheckstyle < Base
6
- MESSAGE_REGEX = /^(?<file>[^:]+):(?<line>\d+)/
6
+ MESSAGE_REGEX = /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/
7
7
 
8
8
  def run
9
- result = execute(command + applicable_files)
9
+ result = execute(command, args: applicable_files)
10
10
  output = result.stdout.chomp
11
11
  return :pass if result.success?
12
12
 
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see http://jshint.com/
5
5
  class JsHint < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  output = result.stdout.chomp
9
9
 
10
10
  return :pass if result.success? && output.empty?
@@ -13,7 +13,7 @@ module Overcommit::Hook::PreCommit
13
13
  # path/to/file.js: line 1, col 0, Error message (E001)
14
14
  extract_messages(
15
15
  output.split("\n").grep(/E|W/),
16
- /^(?<file>[^:]+):[^\d]+(?<line>\d+).+\((?<type>E|W)\d+\)/,
16
+ /^(?<file>(?:\w:)?[^:]+):[^\d]+(?<line>\d+).+\((?<type>E|W)\d+\)/,
17
17
  lambda { |type| type.include?('W') ? :warning : :error }
18
18
  )
19
19
  end
@@ -3,10 +3,10 @@ module Overcommit::Hook::PreCommit
3
3
  #
4
4
  # @see http://www.jslint.com/
5
5
  class JsLint < Base
6
- MESSAGE_REGEX = /(?<file>[^:]+):(?<line>\d+)/
6
+ MESSAGE_REGEX = /(?<file>(?:\w:)?[^:]+):(?<line>\d+)/
7
7
 
8
8
  def run
9
- result = execute(command + applicable_files)
9
+ result = execute(command, args: applicable_files)
10
10
  return :pass if result.success?
11
11
 
12
12
  # example message:
@@ -5,7 +5,7 @@ module Overcommit::Hook::PreCommit
5
5
  # @see http://jscs.info/
6
6
  class Jscs < Base
7
7
  def run
8
- result = execute(command + applicable_files)
8
+ result = execute(command, args: applicable_files)
9
9
  return :pass if result.success?
10
10
 
11
11
  if result.status == 1
@@ -17,7 +17,7 @@ module Overcommit::Hook::PreCommit
17
17
  # path/to/file.js: line 7, col 0, ruleName: Error message
18
18
  extract_messages(
19
19
  result.stdout.split("\n"),
20
- /^(?<file>[^:]+):[^\d]+(?<line>\d+)/,
20
+ /^(?<file>(?:\w:)?[^:]+):[^\d]+(?<line>\d+)/,
21
21
  )
22
22
  end
23
23
  end
@@ -3,7 +3,7 @@ module Overcommit::Hook::PreCommit
3
3
  #
4
4
  # @see http://www.javascriptlint.com/
5
5
  class Jsl < Base
6
- MESSAGE_REGEX = /(?<file>.+)\((?<line>\d+)\):(?<type>[^:]+)/
6
+ MESSAGE_REGEX = /(?<file>(?:\w:)?.+)\((?<line>\d+)\):(?<type>[^:]+)/
7
7
 
8
8
  MESSAGE_TYPE_CATEGORIZER = lambda do |type|
9
9
  type =~ /warning/ ? :warning : :error
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://pypi.python.org/pypi/pep257
5
5
  class Pep257 < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  return :pass if result.success?
9
9
 
10
10
  output = result.stderr.chomp
@@ -14,7 +14,7 @@ module Overcommit::Hook::PreCommit
14
14
  # D102: Docstring missing
15
15
  extract_messages(
16
16
  output.gsub(/:\s+/, ': ').split("\n"),
17
- /^(?<file>[^:]+):(?<line>\d+)/
17
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/
18
18
  )
19
19
  end
20
20
  end
@@ -4,7 +4,7 @@ module Overcommit::Hook::PreCommit
4
4
  # @see https://pypi.python.org/pypi/pep8
5
5
  class Pep8 < Base
6
6
  def run
7
- result = execute(command + applicable_files)
7
+ result = execute(command, args: applicable_files)
8
8
  output = result.stdout.chomp
9
9
 
10
10
  return :pass if result.success? && output.empty?
@@ -13,7 +13,7 @@ module Overcommit::Hook::PreCommit
13
13
  # path/to/file.py:88:5: E301 expected 1 blank line, found 0
14
14
  extract_messages(
15
15
  output.split("\n"),
16
- /^(?<file>[^:]+):(?<line>\d+):\d+:\s(?<type>E|W)/,
16
+ /^(?<file>(?:\w:)?[^:]+):(?<line>\d+):\d+:\s(?<type>E|W)/,
17
17
  lambda { |type| type.include?('W') ? :warning : :error }
18
18
  )
19
19
  end