pre-commit 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47b088bf66a3dce520c9a2e2c7b2573a5da3dc4d
4
- data.tar.gz: b2712aafb68d68ae5226e1a79800e705b8ec1947
3
+ metadata.gz: 0b7eca26aaae49efaf8967fb7a02d01521f272cc
4
+ data.tar.gz: 7e36f001ca2d85847d5038b757f442ffbb411a4e
5
5
  SHA512:
6
- metadata.gz: ed5b63347c42c6cd96782865d9513f2f63a3bb7ec5e924c27ef403667981b3e5d51ef6d557e719a7542ef0e36073de715aeeee83ea172105565e9df2755280ed
7
- data.tar.gz: c90634c849ddc7fd8e294fa408b3474c0c23e7f85a35bb6492e14311c289dac127ecca75b1b07bcc8ecfece8feefc61bf16d250be52298de32fd6ad53fe9b749
6
+ metadata.gz: f21965abc93d4cec2c941d53b519aa8bcf0416334a329784e061d8791108651f289184d7e0504e54da1b57e5b93d5395992753f856fbde69f08735c7810940e9
7
+ data.tar.gz: df10779b7b8a0be223b55b6f70a0cd476b080bc75074b39832a3b4409da5c966aefcd55f28ff5b95e8010142525e3e6fe611ca736247f0409b966e68f3dc2e54
data/README.md CHANGED
@@ -107,4 +107,14 @@ pre-commit run <file-list> # run on the list of files, patterns not supported
107
107
  - `yaml` - reads configuration from `/etc/pre_commit.yml`, `$HOME/.pre_commit.yml` and `config/pre_commit.yml`, allows `config/pre_commit.yml` updates
108
108
  - `env` - reads configuration from environment variables
109
109
 
110
+ ## Excluding files from checks
111
+
112
+ `pre-commit` uses `git` to get list of files to check, you can ignore
113
+ the list of git files to check with:
114
+
115
+ 1. `.gitignore` - git supported file shared beteen all checkouts
116
+ 2. `.git/info/exclude` - git supported file only for this checkout
117
+ 3. `.pre_commit.ignore` - `pre-commit` specific list can be shared,
118
+ [Allowed filters](http://www.ruby-doc.org/core-2.1.3/File.html#method-c-fnmatch)
119
+
110
120
  ## [Contributing](CONTRIBUTING.md)
@@ -9,15 +9,15 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def extra_grep
12
- " | grep -v \/\/"
12
+ %w{-v //}
13
13
  end
14
14
 
15
15
  def message
16
- "before(:all) found:\n"
16
+ "before(:all) found:"
17
17
  end
18
18
 
19
19
  def pattern
20
- '-e "before.*:all"'
20
+ "before.*:all"
21
21
  end
22
22
 
23
23
  def self.description
@@ -7,7 +7,9 @@ module PreCommit
7
7
 
8
8
  def call(_)
9
9
  return if system("rake #{Ci::CI_TASK_NAME} --silent")
10
- "your test suite has failed, for the full output run `#{CI_TASK_NAME}`"
10
+ PreCommit::ErrorList.new(
11
+ "your test suite has failed, for the full output run `#{CI_TASK_NAME}`"
12
+ )
11
13
  end
12
14
 
13
15
  def self.description
@@ -8,9 +8,13 @@ module PreCommit
8
8
  staged_files = staged_files.grep(/\.coffee$/)
9
9
  return if staged_files.empty?
10
10
 
11
- args = (config_file_flag + staged_files).join(' ')
11
+ result =
12
+ in_groups(staged_files).map do |files|
13
+ args = %w{coffeelint} + config_file_flag + files
14
+ execute(args)
15
+ end.compact
12
16
 
13
- execute("coffeelint #{args}")
17
+ result.empty? ? nil : result.join("\n")
14
18
  end
15
19
 
16
20
  def config_file_flag
@@ -9,15 +9,15 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def extra_grep
12
- " | grep -v \/\/"
12
+ %w{-v //}
13
13
  end
14
14
 
15
15
  def message
16
- "console.log found:\n"
16
+ "console.log found:"
17
17
  end
18
18
 
19
19
  def pattern
20
- '-e "console\\.log"'
20
+ "console\\.log"
21
21
  end
22
22
 
23
23
  def self.description
@@ -9,11 +9,11 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def message
12
- "debugger statement(s) found:\n"
12
+ "debugger statement(s) found:"
13
13
  end
14
14
 
15
15
  def pattern
16
- '-e "^[ ]*debugger"'
16
+ "^[ ]*debugger"
17
17
  end
18
18
 
19
19
  def self.description
@@ -9,15 +9,15 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def message
12
- "local path found in Gemfile:\n"
12
+ "local path found in Gemfile:"
13
13
  end
14
14
 
15
15
  def pattern
16
- "'path:|:path\\s*=>'"
16
+ "path:|:path\\s*=>"
17
17
  end
18
18
 
19
19
  def extra_grep
20
- " | grep -v '#'"
20
+ %w{-v #}
21
21
  end
22
22
 
23
23
  def self.description
@@ -4,17 +4,8 @@ module PreCommit
4
4
  module Checks
5
5
  class Jshint < Js
6
6
 
7
- def js_config
8
- if config_file
9
- ExecJS.exec("return (#{File.read(config_file)});")
10
- else
11
- {}
12
- end
13
- end
14
-
15
7
  def run_check(file)
16
- context = ExecJS.compile(File.read(linter_src))
17
- context.call("JSHINT", File.read(file), js_config, js_config["globals"])
8
+ context.call("JSHINT._getErrors", File.read(file), js_config, js_config["globals"])
18
9
  end
19
10
 
20
11
  def linter_src
@@ -29,6 +20,25 @@ module PreCommit
29
20
  "Checks javascript files with JSHint."
30
21
  end
31
22
 
23
+ private
24
+
25
+ def context
26
+ @context ||= ExecJS.compile(File.read(linter_src) << <<-JAVASCRIPT)
27
+ ;JSHINT._getErrors = function(source, options, globals) {
28
+ JSHINT(source, options, globals);
29
+ return JSHINT.errors;
30
+ }
31
+ JAVASCRIPT
32
+ end
33
+
34
+ def js_config
35
+ @js_config ||= if config_file
36
+ ExecJS.exec("return (#{File.read(config_file)});")
37
+ else
38
+ {}
39
+ end
40
+ end
41
+
32
42
  end
33
43
  end
34
44
  end
@@ -4,16 +4,22 @@ module PreCommit
4
4
  module Checks
5
5
  class Local < Plugin
6
6
 
7
- DEFAULT_LOCATION = "config/pre-commit.rb"
7
+ attr_writer :script
8
8
 
9
- def call(staged_files, script=Local::DEFAULT_LOCATION)
10
- return unless File.exist?(script)
9
+ def call(staged_files)
10
+ return unless script
11
11
  output = `ruby #{script} #{staged_files.join(" ")} 2>&1`
12
12
  "#{script} failed:\n#{output}" unless $?.success?
13
13
  end
14
14
 
15
15
  def self.description
16
- "Executes 'ruby #{DEFAULT_LOCATION}'."
16
+ "Executes a custom script located at config/pre_commit.rb"
17
+ end
18
+
19
+ def script
20
+ @script ||= ["config/pre_commit.rb", "config/pre-commit.rb"].detect do |file|
21
+ File.exist?(file)
22
+ end
17
23
  end
18
24
 
19
25
  end
@@ -5,11 +5,11 @@ module PreCommit
5
5
  class MergeConflict < Grep
6
6
 
7
7
  def message
8
- "detected a merge conflict\n"
8
+ "detected a merge conflict"
9
9
  end
10
10
 
11
11
  def pattern
12
- "'<<<<<<<'"
12
+ "<<<<<<<"
13
13
  end
14
14
 
15
15
  def self.description
@@ -5,7 +5,7 @@ module PreCommit
5
5
  class Pry < Grep
6
6
 
7
7
  def message
8
- "binding.pry found:\n"
8
+ "binding.pry found:"
9
9
  end
10
10
 
11
11
  def pattern
@@ -9,11 +9,11 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def message
12
- ":focus found in specs:\n"
12
+ ":focus found in specs:"
13
13
  end
14
14
 
15
15
  def pattern
16
- "'(describe|context|it).*(:focus|focus:).*do'"
16
+ "(describe|context|it).*(:focus|focus:).*do"
17
17
  end
18
18
 
19
19
  def self.description
@@ -21,7 +21,7 @@ module PreCommit
21
21
  staged_files = staged_files.grep(/\.rb$/)
22
22
  return if staged_files.empty?
23
23
 
24
- args = config_file_flag + ["--force-exclusion"] + staged_files
24
+ args = config_file_flag + user_supplied_flags + ["--force-exclusion"] + staged_files
25
25
 
26
26
  success, captured = capture { ::RuboCop::CLI.new.run(args) == 0 }
27
27
  captured unless success
@@ -41,6 +41,10 @@ module PreCommit
41
41
  config_file ? ['-c', config_file] : []
42
42
  end
43
43
 
44
+ def user_supplied_flags
45
+ Array(config.get('rubocop.flags')).reject(&:empty?)
46
+ end
47
+
44
48
  def alternate_config_file
45
49
  '.rubocop.yml'
46
50
  end
@@ -9,11 +9,11 @@ module PreCommit
9
9
  end
10
10
 
11
11
  def message
12
- "detected :symbol => value hashrocket:\n"
12
+ "detected :symbol => value hashrocket:"
13
13
  end
14
14
 
15
15
  def pattern
16
- '\'[^:](:{1}(?:\$|@|@@|[_A-Za-z])?\w*[=!?]?\s*=>\s*)\''
16
+ '[^:](:{1}(?:\$|@|@@|[_A-Za-z])?\w*[=!?]?\s*=>\s*)'
17
17
  end
18
18
 
19
19
  def self.description
@@ -8,9 +8,13 @@ module PreCommit
8
8
  staged_files = staged_files.grep(/\.scss$/)
9
9
  return if staged_files.empty?
10
10
 
11
- args = (config_file_flag + staged_files).join(' ')
11
+ result =
12
+ in_groups(staged_files).map do |files|
13
+ args = %w{scss-lint} + config_file_flag + files
14
+ execute(args)
15
+ end.compact
12
16
 
13
- execute("scss-lint #{args}")
17
+ result.empty? ? nil : result.join("\n")
14
18
  end
15
19
 
16
20
  def config_file_flag
@@ -5,11 +5,11 @@ module PreCommit
5
5
  class Tabs < Grep
6
6
 
7
7
  def message
8
- "detected tab before initial space:\n"
8
+ "detected tab before initial space:"
9
9
  end
10
10
 
11
11
  def pattern
12
- "'^ *\t'"
12
+ "^ *\t"
13
13
  end
14
14
 
15
15
  def self.description
@@ -1,10 +1,13 @@
1
1
  require 'yaml'
2
+ require "pre-commit/configuration/top_level"
2
3
 
3
4
  module PreCommit
4
5
  class Configuration
5
6
  class Providers
6
7
 
7
8
  class Yaml
9
+ include PreCommit::Configuration::TopLevel
10
+
8
11
  def self.priority
9
12
  20
10
13
  end
@@ -55,11 +58,6 @@ module PreCommit
55
58
  File.join(top_level, 'config', 'pre_commit.yml')
56
59
  end
57
60
 
58
- def top_level
59
- top_level = `git rev-parse --show-toplevel`.chomp.strip
60
- raise "no git repo!" if top_level == ""
61
- top_level
62
- end
63
61
  end
64
62
 
65
63
  end
@@ -1,9 +1,10 @@
1
- require 'pre-commit/checks/plugin'
2
- require 'shellwords'
1
+ require 'pre-commit/checks/shell'
2
+ require 'pre-commit/error_list'
3
+ require 'pre-commit/line'
3
4
 
4
5
  module PreCommit
5
6
  module Checks
6
- class Grep < Plugin
7
+ class Grep < Shell
7
8
  class PaternNotSet < StandardError
8
9
  def message
9
10
  "Please define 'pattern' method."
@@ -17,7 +18,7 @@ module PreCommit
17
18
  end
18
19
 
19
20
  def extra_grep
20
- @extra_grep or ""
21
+ @extra_grep or []
21
22
  end
22
23
 
23
24
  def message
@@ -31,21 +32,43 @@ module PreCommit
31
32
  # general code:
32
33
 
33
34
  def call(staged_files)
34
- staged_files = files_filter(staged_files).map(&:shellescape)
35
+ staged_files = files_filter(staged_files)
35
36
  return if staged_files.empty?
36
- errors = `#{grep} #{pattern} #{staged_files.join(" ")}#{extra_grep}`
37
- return unless $?.success?
38
- "#{message}#{errors}"
37
+
38
+ result =
39
+ in_groups(staged_files).map do |files|
40
+ args = grep + [pattern] + files
41
+ args += ["|", "grep"] + extra_grep if !extra_grep.nil? and !extra_grep.empty?
42
+ execute(args, success_status: false)
43
+ end.compact
44
+
45
+ result.empty? ? nil : parse_errors(message, result)
39
46
  end
40
47
 
41
48
  private
42
49
 
50
+ def parse_errors(message, list)
51
+ result = PreCommit::ErrorList.new(message)
52
+ result.errors +=
53
+ list.map do |group|
54
+ group.split(/\n/)
55
+ end.flatten.compact.map do |line|
56
+ PreCommit::Line.new(nil, *parse_error(line))
57
+ end
58
+ result
59
+ end
60
+
61
+ def parse_error(line)
62
+ matches = /^([^:]+):([[:digit:]]+):(.*)$/.match(line)
63
+ matches and matches.captures
64
+ end
65
+
43
66
  def grep(grep_version = nil)
44
67
  grep_version ||= detect_grep_version
45
68
  if grep_version =~ /FreeBSD/
46
- "grep -EnIH"
69
+ %w{grep -EnIH}
47
70
  else
48
- "grep -PnIH"
71
+ %w{grep -PnIH}
49
72
  end
50
73
  end
51
74
 
@@ -1,5 +1,6 @@
1
1
  require 'plugins/pluginator/extensions/conversions'
2
2
  require 'pre-commit/checks/plugin/config_file'
3
+ require 'pre-commit/line'
3
4
 
4
5
  module PreCommit
5
6
  module Checks
@@ -28,6 +29,17 @@ module PreCommit
28
29
  def alternate_config_file
29
30
  ''
30
31
  end
32
+
33
+ # group files in packs smaller then 127kB (1000 files)
34
+ # 127k based on http://www.in-ulm.de/~mascheck/various/argmax/
35
+ # and 262144 limit on OSX - my env size /2 to be safe
36
+ # assuming mean file length shorter then 127 chars splitting to
37
+ # groups of 1000 files, each_slice for simplicity, doing real
38
+ # check could be to time consuming
39
+ def in_groups(files, group_size = 1000)
40
+ files.each_slice(group_size)
41
+ end
42
+
31
43
  end
32
44
  end
33
45
  end
@@ -1,5 +1,5 @@
1
1
  require 'pre-commit/checks/plugin'
2
- require 'open3'
2
+ require 'shellwords'
3
3
 
4
4
  module PreCommit
5
5
  module Checks
@@ -7,9 +7,22 @@ module PreCommit
7
7
 
8
8
  private
9
9
 
10
- def execute(command)
11
- _, stdout, stderr, process = Open3.popen3(command)
12
- stdout.read + stderr.read unless process.value.success?
10
+ def execute(*args)
11
+ options = args.last.is_a?(::Hash) ? args.pop : {}
12
+ args = build_command(*args)
13
+ execute_raw(args, options)
14
+ end
15
+
16
+ def build_command(*args)
17
+ args.flatten.map do |arg|
18
+ arg = arg.shellescape if arg != '|' && arg != '&&' && arg != '||'
19
+ arg
20
+ end.join(" ")
21
+ end
22
+
23
+ def execute_raw(command, options = {})
24
+ result = `#{command} 2>&1`
25
+ $?.success? == (options.fetch(:success_status, true)) ? nil : result
13
26
  end
14
27
  end
15
28
  end