pre-commit 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -16
- data/bin/pre-commit +1 -12
- data/lib/plugins/pluginator/extensions/find_check.rb +26 -0
- data/lib/plugins/pre_commit/checks/before_all.rb +23 -7
- data/lib/plugins/pre_commit/checks/ci.rb +10 -3
- data/lib/plugins/pre_commit/checks/closure.rb +12 -4
- data/lib/plugins/pre_commit/checks/coffeelint.rb +9 -4
- data/lib/plugins/pre_commit/checks/common.rb +17 -0
- data/lib/plugins/pre_commit/checks/console_log.rb +23 -7
- data/lib/plugins/pre_commit/checks/csslint.rb +32 -0
- data/lib/plugins/pre_commit/checks/debugger.rb +14 -10
- data/lib/plugins/pre_commit/checks/gemfile_path.rb +18 -7
- data/lib/plugins/pre_commit/checks/jshint.rb +10 -4
- data/lib/plugins/pre_commit/checks/jslint.rb +11 -5
- data/lib/plugins/pre_commit/checks/local.rb +10 -2
- data/lib/plugins/pre_commit/checks/merge_conflict.rb +15 -6
- data/lib/plugins/pre_commit/checks/migration.rb +32 -26
- data/lib/plugins/pre_commit/checks/nb_space.rb +10 -2
- data/lib/plugins/pre_commit/checks/php.rb +10 -4
- data/lib/plugins/pre_commit/checks/pry.rb +15 -6
- data/lib/plugins/pre_commit/checks/rails.rb +17 -0
- data/lib/plugins/pre_commit/checks/rspec_focus.rb +19 -7
- data/lib/plugins/pre_commit/checks/rubocop.rb +20 -8
- data/lib/plugins/pre_commit/checks/ruby.rb +17 -0
- data/lib/plugins/pre_commit/checks/ruby_symbol_hashrockets.rb +17 -8
- data/lib/plugins/pre_commit/checks/tabs.rb +15 -8
- data/lib/plugins/pre_commit/checks/whitespace.rb +28 -5
- data/lib/plugins/pre_commit/configuration/providers/README.md +10 -0
- data/lib/plugins/pre_commit/configuration/providers/default.rb +34 -0
- data/lib/plugins/pre_commit/configuration/providers/git.rb +26 -0
- data/lib/plugins/pre_commit/configuration/providers/git_old.rb +28 -0
- data/lib/plugins/pre_commit/configuration/providers/yaml.rb +67 -0
- data/lib/pre-commit.rb +28 -1
- data/lib/pre-commit/checks.rb +1 -98
- data/lib/pre-commit/checks/grep.rb +57 -0
- data/lib/{plugins/pre_commit → pre-commit}/checks/js.rb +15 -7
- data/lib/pre-commit/checks/plugin.rb +13 -0
- data/lib/pre-commit/cli.rb +46 -19
- data/lib/pre-commit/configuration.rb +54 -0
- data/lib/pre-commit/configuration/providers.rb +53 -0
- data/lib/pre-commit/installer.rb +54 -0
- data/lib/pre-commit/list_evaluator.rb +85 -0
- data/lib/pre-commit/plugins_list.rb +87 -0
- data/lib/pre-commit/runner.rb +54 -9
- data/lib/pre-commit/support/csslint/csslint.js +9259 -0
- data/lib/pre-commit/utils/git_conversions.rb +56 -0
- data/lib/pre-commit/utils/staged_files.rb +21 -0
- metadata +47 -30
- data/lib/pre-commit/support/templates/automatic_hook +0 -35
- data/lib/pre-commit/support/templates/default_hook +0 -35
- data/lib/pre-commit/support/templates/manual_hook +0 -14
- data/lib/pre-commit/utils.rb +0 -27
@@ -1,11 +1,29 @@
|
|
1
|
+
require 'pre-commit/checks/plugin'
|
2
|
+
|
1
3
|
module PreCommit
|
2
4
|
module Checks
|
3
|
-
class Whitespace
|
4
|
-
|
5
|
-
|
5
|
+
class Whitespace < Plugin
|
6
|
+
|
7
|
+
def self.aliases
|
8
|
+
[:white_space]
|
9
|
+
end
|
10
|
+
|
11
|
+
def files_filter(staged_files)
|
12
|
+
if
|
13
|
+
@list.map(&:name).include?("PreCommit::Checks::Rubocop")
|
14
|
+
then
|
15
|
+
staged_files.reject{|name| name =~ /\.rb$/ }
|
16
|
+
else
|
17
|
+
staged_files
|
18
|
+
end
|
6
19
|
end
|
7
|
-
|
8
|
-
|
20
|
+
|
21
|
+
def files_string(staged_files)
|
22
|
+
files_filter(staged_files).map{|file| "'#{file}'" }.join(" ")
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(staged_files)
|
26
|
+
errors = `git diff-index --check --cached HEAD -- #{files_string(staged_files)} 2>&1`
|
9
27
|
return if $?.success?
|
10
28
|
|
11
29
|
# Initial commit: diff against the empty tree object
|
@@ -16,6 +34,11 @@ module PreCommit
|
|
16
34
|
|
17
35
|
errors
|
18
36
|
end
|
37
|
+
|
38
|
+
def self.description
|
39
|
+
"Finds white space."
|
40
|
+
end
|
41
|
+
|
19
42
|
end
|
20
43
|
end
|
21
44
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module PreCommit
|
2
|
+
class CanNotUpdateDefauls < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class Configuration
|
6
|
+
class Providers
|
7
|
+
class Default
|
8
|
+
|
9
|
+
DEFAULTS =
|
10
|
+
{
|
11
|
+
:warnings => [],
|
12
|
+
:checks => [:common, :rails]
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.priority
|
16
|
+
0
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(defaults = nil)
|
20
|
+
@defaults = defaults || DEFAULTS
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](name)
|
24
|
+
@defaults[name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def update(name, value)
|
28
|
+
raise PreCommit::CanNotUpdateDefauls.new("Can not update default settings")
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pre-commit/utils/git_conversions'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
class Configuration
|
5
|
+
class Providers
|
6
|
+
|
7
|
+
class Git
|
8
|
+
include PreCommit::Utils::GitConversions
|
9
|
+
|
10
|
+
def self.priority
|
11
|
+
10
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](name)
|
15
|
+
git_to_ruby(`git config pre-commit.#{name.to_s.gsub(/_/,".")} 2>/dev/null`)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(name, value)
|
19
|
+
`git config pre-commit.#{name.to_s.gsub(/_/,".")} "#{ruby_to_git(value)}" 2>/dev/null`
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'plugins/pre_commit/configuration/providers/git'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
class Configuration
|
5
|
+
class Providers
|
6
|
+
|
7
|
+
class GitOld < Git
|
8
|
+
|
9
|
+
def self.priority
|
10
|
+
11
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](name)
|
14
|
+
value = super(name)
|
15
|
+
if
|
16
|
+
name == :checks && value && ! value.kind_of?(Array)
|
17
|
+
then
|
18
|
+
value = value.chomp.split(/,\s*/).map(&:to_sym) || []
|
19
|
+
update(name, value) unless value.empty?
|
20
|
+
end
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
class Configuration
|
5
|
+
class Providers
|
6
|
+
|
7
|
+
class Yaml
|
8
|
+
def self.priority
|
9
|
+
20
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](name)
|
13
|
+
config[name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(name, value)
|
17
|
+
content = read_config(local_file)
|
18
|
+
content[name] = value
|
19
|
+
save_config(local_file, content)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def config
|
25
|
+
return @config if @config
|
26
|
+
@config = {}
|
27
|
+
@config.merge!(read_config(system_file))
|
28
|
+
@config.merge!(read_config(global_file))
|
29
|
+
@config.merge!(read_config(local_file))
|
30
|
+
@config
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_config(path)
|
34
|
+
content = YAML.load_file(path) if File.exist?(path)
|
35
|
+
content || {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_config(path, content)
|
39
|
+
parent = File.expand_path('..', path)
|
40
|
+
Dir.mkdir(parent) unless Dir.exist?(parent)
|
41
|
+
File.open(path, "w") do |file|
|
42
|
+
file.write(YAML.dump(content))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def system_file
|
47
|
+
@system_file ||= '/etc/pre_commit.yml'
|
48
|
+
end
|
49
|
+
|
50
|
+
def global_file
|
51
|
+
@global_file ||= File.join(ENV['HOME'], '.pre_commit.yml')
|
52
|
+
end
|
53
|
+
|
54
|
+
def local_file
|
55
|
+
File.join(top_level, 'config', 'pre_commit.yml')
|
56
|
+
end
|
57
|
+
|
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
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/pre-commit.rb
CHANGED
@@ -1 +1,28 @@
|
|
1
|
-
require 'pre-commit/
|
1
|
+
require 'pre-commit/runner'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
|
5
|
+
# Can not delete this method with out a deprecation strategy.
|
6
|
+
# It is refered to in the generated pre-commit hook in versions 0.0-0.1.1
|
7
|
+
#
|
8
|
+
# NOTE: The deprecation strategy *may* be just delete it since, we're still
|
9
|
+
# pre 1.0.
|
10
|
+
#
|
11
|
+
# Actually, on the deprecation note. This method isn't really the problem.
|
12
|
+
# The problem is the default generated pre-commit hook. It shouldn't have
|
13
|
+
# logic in it. The we have freedom to change the gem implementation however
|
14
|
+
# we want, and nobody is forced to update their pre-commit binary.
|
15
|
+
def self.checks_to_run
|
16
|
+
warn "WARNING: You are using old hook version, you can update it with: pre-commit install"
|
17
|
+
runner.list_to_run(:checks)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.run
|
21
|
+
runner.run or exit 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.runner
|
25
|
+
@runner ||= PreCommit::Runner.new
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/pre-commit/checks.rb
CHANGED
@@ -1,98 +1 @@
|
|
1
|
-
require '
|
2
|
-
require 'pre-commit/utils'
|
3
|
-
|
4
|
-
module PreCommit
|
5
|
-
|
6
|
-
DEFAULT_CHECKS = [
|
7
|
-
:white_space, :console_log, :debugger, :pry, :tabs, :jshint,
|
8
|
-
:migrations, :merge_conflict, :local, :nb_space
|
9
|
-
]
|
10
|
-
|
11
|
-
DEFAULT_WARNINGS = []
|
12
|
-
|
13
|
-
# Can not delete this method with out a deprecation strategy.
|
14
|
-
# It is refered to in the generated pre-commit hook in versions 0.0-0.1.1
|
15
|
-
#
|
16
|
-
# NOTE: The deprecation strategy *may* be just delete it since, we're still
|
17
|
-
# pre 1.0.
|
18
|
-
|
19
|
-
#
|
20
|
-
# Actually, on the deprecation note. This method isn't really the problem.
|
21
|
-
# The problem is the default generated pre-commit hook. It shouldn't have
|
22
|
-
# logic in it. The we have freedom to change the gem implementation however
|
23
|
-
# we want, and nobody is forced to update their pre-commit binary.
|
24
|
-
def self.checks_to_run
|
25
|
-
@checks_to_run ||= find_plugins(configured_checks)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.warnings_to_run
|
29
|
-
@warnings_to_run ||= find_plugins(configured_warnings)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.configured_checks
|
33
|
-
@configured_checks ||= get_git_config('checks', DEFAULT_CHECKS)
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.configured_warnings
|
37
|
-
@configured_warnings ||= get_git_config('warnings', DEFAULT_WARNINGS)
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.get_git_config(name, default)
|
41
|
-
array_or_default(
|
42
|
-
`git config pre-commit.#{name}`.chomp.split(/,\s*/).map(&:to_sym),
|
43
|
-
default
|
44
|
-
)
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.array_or_default(list, default)
|
48
|
-
list = default if list.nil? || list.empty?
|
49
|
-
list
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.find_plugins(names)
|
53
|
-
names.map{|name| find_plugin(name) }.compact
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.find_plugin(name)
|
57
|
-
pluginator.first_class('checks', name) ||
|
58
|
-
pluginator.first_ask('checks', 'supports', name) ||
|
59
|
-
begin
|
60
|
-
$stderr.puts "Could not find plugin supporting #{name}."
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.pluginator
|
66
|
-
@pluginator ||= Pluginator.find('pre_commit', :extends => [:first_ask, :first_class] )
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.execute_list(list)
|
70
|
-
list.map { |cmd| cmd.call(@staged_files.dup) }.compact
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.run
|
74
|
-
@staged_files = Utils.staged_files
|
75
|
-
show_warnings( execute_list(warnings_to_run) )
|
76
|
-
show_errors( execute_list(checks_to_run ) )
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.show_warnings(warnings)
|
80
|
-
if warnings.any?
|
81
|
-
$stderr.puts "pre-commit: Some warnings were raised. These will not stop commit:"
|
82
|
-
$stderr.puts warnings.join("\n")
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.show_errors(errors)
|
87
|
-
if errors.any?
|
88
|
-
$stderr.puts "pre-commit: Stopping commit because of errors."
|
89
|
-
$stderr.puts errors.join("\n")
|
90
|
-
$stderr.puts
|
91
|
-
$stderr.puts "pre-commit: You can bypass this check using `git commit -n`"
|
92
|
-
$stderr.puts
|
93
|
-
exit 1
|
94
|
-
else
|
95
|
-
exit 0
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
1
|
+
require 'pre-commit'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'pre-commit/checks/plugin'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
module Checks
|
5
|
+
class Grep < Plugin
|
6
|
+
class PaternNotSet < StandardError
|
7
|
+
def message
|
8
|
+
"Please define 'pattern' method."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# overwrite those:
|
13
|
+
|
14
|
+
def files_filter(staged_files)
|
15
|
+
staged_files
|
16
|
+
end
|
17
|
+
|
18
|
+
def extra_grep
|
19
|
+
@extra_grep or ""
|
20
|
+
end
|
21
|
+
|
22
|
+
def message
|
23
|
+
@message or ""
|
24
|
+
end
|
25
|
+
|
26
|
+
def pattern
|
27
|
+
@pattern or raise PaternNotSet.new
|
28
|
+
end
|
29
|
+
|
30
|
+
# general code:
|
31
|
+
|
32
|
+
def call(staged_files)
|
33
|
+
staged_files = files_filter(staged_files)
|
34
|
+
return if staged_files.empty?
|
35
|
+
errors = `#{grep} #{pattern} #{staged_files.join(" ")}#{extra_grep}`
|
36
|
+
return unless $?.success?
|
37
|
+
"#{message}#{errors}"
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def grep(grep_version = nil)
|
43
|
+
grep_version ||= detect_grep_version
|
44
|
+
if grep_version =~ /FreeBSD/
|
45
|
+
"grep -EnIH"
|
46
|
+
else
|
47
|
+
"grep -PnIH"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def detect_grep_version
|
52
|
+
`grep --version | head -n 1 | sed -e 's/^[^0-9.]*\([0-9.]*\)$/\1/'`
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require 'pre-commit/
|
1
|
+
require 'pre-commit/checks/plugin'
|
2
2
|
|
3
3
|
module PreCommit
|
4
4
|
module Checks
|
5
|
-
class Js
|
6
|
-
def
|
5
|
+
class Js < Plugin
|
6
|
+
def call(staged_files)
|
7
7
|
require 'execjs'
|
8
8
|
rescue RuntimeError, LoadError => e
|
9
9
|
$stderr.puts "Could not load execjs: #{e}"
|
10
10
|
else
|
11
|
-
staged_files = staged_files
|
11
|
+
staged_files = files_filter(staged_files)
|
12
12
|
return if staged_files.empty?
|
13
13
|
|
14
14
|
errors = []
|
@@ -21,15 +21,23 @@ module PreCommit
|
|
21
21
|
errors.join("\n")
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def linter_src
|
25
25
|
raise "Must be defined by subclass"
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def files_filter(staged_files)
|
29
|
+
staged_files.grep(/\.js$/)
|
30
|
+
end
|
31
|
+
|
32
|
+
def error_selector
|
33
|
+
'reason'
|
34
|
+
end
|
35
|
+
|
36
|
+
def display_error(error_object, file)
|
29
37
|
return "" unless error_object
|
30
38
|
|
31
39
|
line = error_object['line'].to_i + 1
|
32
|
-
"#{error_object[
|
40
|
+
"#{error_object[error_selector]}\n#{file}:#{line} #{error_object['evidence']}"
|
33
41
|
end
|
34
42
|
end
|
35
43
|
end
|