pre-commit 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/lib/pre-commit/cli.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'pre-commit/configuration'
|
3
|
+
require 'pre-commit/installer'
|
4
|
+
require 'pre-commit/list_evaluator'
|
2
5
|
|
3
6
|
module PreCommit
|
4
7
|
|
@@ -6,36 +9,60 @@ module PreCommit
|
|
6
9
|
|
7
10
|
class Cli
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
def initialize(*args)
|
13
|
+
@args = args
|
14
|
+
end
|
11
15
|
|
12
|
-
|
16
|
+
def execute()
|
17
|
+
action_name = @args.shift or 'help'
|
18
|
+
action = "execute_#{action_name}".to_sym
|
19
|
+
if respond_to?(action)
|
20
|
+
then send(action, *@args)
|
21
|
+
else execute_help(action_name, *@args)
|
22
|
+
end
|
23
|
+
end
|
13
24
|
|
14
|
-
def
|
15
|
-
|
25
|
+
def execute_help(*args)
|
26
|
+
warn "Unknown parameters: #{args * " "}" unless args.empty?
|
27
|
+
warn "Usage: pre-commit install"
|
28
|
+
warn "Usage: pre-commit list"
|
29
|
+
warn "Usage: pre-commit plugins"
|
30
|
+
warn "Usage: pre-commit <enable|disbale> <git|yaml> <checks|warnings> check1 [check2...]"
|
31
|
+
args.empty? # return status, it's ok if user requested help
|
16
32
|
end
|
17
33
|
|
18
|
-
def
|
19
|
-
key
|
20
|
-
|
34
|
+
def execute_install(key = nil, *args)
|
35
|
+
PreCommit::Installer.new(key).install
|
36
|
+
end
|
21
37
|
|
22
|
-
|
38
|
+
def execute_list(*args)
|
39
|
+
puts list_evaluator.list
|
40
|
+
true
|
41
|
+
end
|
23
42
|
|
24
|
-
|
25
|
-
|
43
|
+
def execute_plugins(*args)
|
44
|
+
puts list_evaluator.plugins
|
45
|
+
true
|
26
46
|
end
|
27
47
|
|
28
|
-
|
48
|
+
def execute_enable(*args)
|
49
|
+
config.enable(*args)
|
50
|
+
rescue ArgumentError
|
51
|
+
execute_help('enable', *args)
|
52
|
+
end
|
29
53
|
|
30
|
-
def
|
31
|
-
|
54
|
+
def execute_disable(*args)
|
55
|
+
config.disable(*args)
|
56
|
+
rescue ArgumentError
|
57
|
+
execute_help('disable', *args)
|
58
|
+
end
|
32
59
|
|
33
|
-
|
34
|
-
|
35
|
-
|
60
|
+
def config
|
61
|
+
@config ||= PreCommit::Configuration.new(PreCommit.pluginator)
|
62
|
+
end
|
36
63
|
|
37
|
-
|
38
|
-
|
64
|
+
def list_evaluator
|
65
|
+
@list_evaluator ||= PreCommit::ListEvaluator.new(config)
|
39
66
|
end
|
40
67
|
|
41
68
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'pluginator'
|
2
|
+
require 'pre-commit/configuration/providers'
|
3
|
+
require 'pre-commit/plugins_list'
|
4
|
+
|
5
|
+
module PreCommit
|
6
|
+
class Configuration
|
7
|
+
attr_reader :pluginator, :providers
|
8
|
+
|
9
|
+
def initialize(pluginator, providers = nil)
|
10
|
+
@pluginator = (pluginator or PreCommit.pluginator)
|
11
|
+
@providers = (providers or Providers.new(@pluginator))
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(name)
|
15
|
+
@providers[name.to_sym]
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_arr(name)
|
19
|
+
value = get(name)
|
20
|
+
case value
|
21
|
+
when nil then []
|
22
|
+
when Array then value
|
23
|
+
else raise PreCommit::NotAnArray.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_combined(name)
|
28
|
+
get_arr(name) + get_arr("#{name}_add")
|
29
|
+
end
|
30
|
+
|
31
|
+
def enable(plugin_name, type, check1, *checks)
|
32
|
+
checks.unshift(check1) # check1 is ArgumentError triger
|
33
|
+
checks.map!(&:to_sym)
|
34
|
+
@providers.update( plugin_name, "#{type}_remove", :-, checks )
|
35
|
+
@providers.update( plugin_name, "#{type}_add", :+, (checks or []) - (@providers.default(type) or []) )
|
36
|
+
true
|
37
|
+
rescue PreCommit::PluginNotFound => e
|
38
|
+
$stderr.puts e
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def disable(plugin_name, type, check1, *checks)
|
43
|
+
checks.unshift(check1) # check1 is ArgumentError triger
|
44
|
+
checks.map!(&:to_sym)
|
45
|
+
@providers.update( plugin_name, "#{type}_add", :-, checks )
|
46
|
+
@providers.update( plugin_name, "#{type}_remove", :+, checks )
|
47
|
+
true
|
48
|
+
rescue PreCommit::PluginNotFound => e
|
49
|
+
warn e
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'plugins/pluginator/extensions/conversions'
|
2
|
+
|
3
|
+
module PreCommit
|
4
|
+
class NotAnArray < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class PluginNotFound < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
class Configuration
|
11
|
+
class Providers
|
12
|
+
include Pluginator::Extensions::Conversions
|
13
|
+
|
14
|
+
def initialize(pluginator, plugins = nil)
|
15
|
+
@pluginator = pluginator
|
16
|
+
@plugins = plugins
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](name)
|
20
|
+
plugins.map{|plugin| plugin[name] }.compact.last
|
21
|
+
end
|
22
|
+
|
23
|
+
def default(name)
|
24
|
+
plugins[0][name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def update(plugin_name, name, operation, list)
|
28
|
+
plugin = find_update_plugin(plugin_name)
|
29
|
+
name = name.to_sym
|
30
|
+
value = plugin[name] || []
|
31
|
+
raise PreCommit::NotAnArray.new unless Array === value
|
32
|
+
value = value.send(operation, list)
|
33
|
+
plugin.update(name, value)
|
34
|
+
end
|
35
|
+
|
36
|
+
def list
|
37
|
+
plugins.map{|plugin| "#{class2string(class2name(plugin.class))}(#{plugin.class.priority})" }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def plugins
|
42
|
+
@plugins ||= @pluginator['configuration/providers'].sort_by(&:priority).map(&:new)
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_update_plugin(plugin_name)
|
46
|
+
plugin = plugins.detect{|plugin| class2string(class2name(plugin.class)) == plugin_name.to_s}
|
47
|
+
raise PluginNotFound.new("Plugin not found for #{plugin_name}.") unless plugin
|
48
|
+
plugin
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pre-commit/configuration'
|
3
|
+
|
4
|
+
module PreCommit
|
5
|
+
|
6
|
+
class Installer
|
7
|
+
|
8
|
+
TARGET_HOOK_PATH = '.git/hooks/pre-commit'
|
9
|
+
TEMPLATE_DIR = File.expand_path("../../../templates/hooks/", __FILE__)
|
10
|
+
|
11
|
+
attr_reader :key
|
12
|
+
|
13
|
+
def initialize(key = nil)
|
14
|
+
@key = key || "default"
|
15
|
+
end
|
16
|
+
|
17
|
+
def hook
|
18
|
+
templates[key.sub(/^--/, "")]
|
19
|
+
end
|
20
|
+
|
21
|
+
def target
|
22
|
+
TARGET_HOOK_PATH
|
23
|
+
end
|
24
|
+
|
25
|
+
def install
|
26
|
+
if
|
27
|
+
hook
|
28
|
+
then
|
29
|
+
FileUtils.cp(hook, target)
|
30
|
+
FileUtils.chmod(0755, target)
|
31
|
+
puts "Installed #{hook} to #{target}"
|
32
|
+
true
|
33
|
+
else
|
34
|
+
warn "Could not find template #{key}"
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def templates
|
42
|
+
return @templates if @templates
|
43
|
+
pattern = File.join(TEMPLATE_DIR, "*")
|
44
|
+
|
45
|
+
@templates =
|
46
|
+
Dir.glob(pattern).inject({}) do |hash, file|
|
47
|
+
key = file.match(/\/([^\/]+?)$/)[1]
|
48
|
+
hash[key] = file
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'pluginator'
|
2
|
+
require 'pre-commit/configuration'
|
3
|
+
require 'plugins/pluginator/extensions/conversions'
|
4
|
+
require 'pre-commit/plugins_list'
|
5
|
+
|
6
|
+
module PreCommit
|
7
|
+
class ListEvaluator
|
8
|
+
include Pluginator::Extensions::Conversions
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
def initialize(config)
|
13
|
+
@config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def list
|
17
|
+
<<-DATA
|
18
|
+
Available providers: #{config.providers.list.join(" ")}
|
19
|
+
Available checks : #{plugin_names.join(" ")}
|
20
|
+
Default checks : #{config.get_arr(:checks).join(" ")}
|
21
|
+
Enabled checks : #{checks_config.join(" ")}
|
22
|
+
Evaluated checks : #{checks_evaluated.join(" ")}
|
23
|
+
Default warnings : #{config.get_arr(:warnings).join(" ")}
|
24
|
+
Enabled warnings : #{warnings_config.join(" ")}
|
25
|
+
Evaluated warnings : #{warnings_evaluated.join(" ")}
|
26
|
+
DATA
|
27
|
+
end
|
28
|
+
|
29
|
+
def plugins
|
30
|
+
list = config.pluginator['checks'].map{|plugin| [class2string(class2name(plugin)), plugin] }.sort
|
31
|
+
separator = list.map{|name, plugin| name.length }.max
|
32
|
+
list.map{ |name, plugin| format_plugin(name, separator, plugin) }.flatten
|
33
|
+
end
|
34
|
+
|
35
|
+
def checks_config
|
36
|
+
get_combined_checks - get_arr_checks_remove
|
37
|
+
end
|
38
|
+
|
39
|
+
def checks_evaluated(type = :evaluated_names)
|
40
|
+
PreCommit::PluginsList.new(get_combined_checks, get_arr_checks_remove) do |name|
|
41
|
+
config.pluginator.find_check(name)
|
42
|
+
end.send(type)
|
43
|
+
end
|
44
|
+
|
45
|
+
def warnings_config
|
46
|
+
get_combined_warnings - get_arr_warnings_remove
|
47
|
+
end
|
48
|
+
|
49
|
+
def warnings_evaluated(type = :evaluated_names)
|
50
|
+
PreCommit::PluginsList.new(get_combined_warnings, get_arr_warnings_remove) do |name|
|
51
|
+
config.pluginator.find_check(name)
|
52
|
+
end.send(type)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def plugin_names
|
58
|
+
config.pluginator['checks'].map{|plugin| class2string(class2name(plugin)) }.sort
|
59
|
+
end
|
60
|
+
|
61
|
+
def format_plugin(name, separator, plugin)
|
62
|
+
line = [sprintf("%#{separator}s : %s", name, plugin.description)]
|
63
|
+
line << sprintf("%#{separator}s - includes: %s", "", plugin.includes.join(" ")) if plugin.respond_to?(:includes)
|
64
|
+
line << sprintf("%#{separator}s - excludes: %s", "", plugin.excludes.join(" ")) if plugin.respond_to?(:excludes)
|
65
|
+
line
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_combined_checks
|
69
|
+
@get_combined_checks ||= config.get_combined(:checks)
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_arr_checks_remove
|
73
|
+
@get_arr_checks_remove ||= config.get_arr("checks_remove")
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_combined_warnings
|
77
|
+
@get_combined_warnings ||= config.get_combined(:warnings)
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_arr_warnings_remove
|
81
|
+
@get_arr_warnings_remove ||= config.get_arr("warnings_remove")
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module PreCommit
|
2
|
+
|
3
|
+
def self.pluginator
|
4
|
+
Pluginator.find('pre_commit', :extends => [:find_check])
|
5
|
+
end
|
6
|
+
|
7
|
+
class PluginsList
|
8
|
+
attr_reader :configured_names, :configured_remove
|
9
|
+
|
10
|
+
def initialize(configured_names, configured_remove, &block)
|
11
|
+
@configured_names = configured_names
|
12
|
+
@configured_remove = configured_remove
|
13
|
+
@class_finder = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluated_names
|
17
|
+
evaluated_names_(evaluated_names_pairs).flatten.compact
|
18
|
+
end
|
19
|
+
|
20
|
+
def list_to_run
|
21
|
+
list_to_run_(evaluated_names_pairs).flatten.compact
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def evaluated_names_(list)
|
27
|
+
list.map{|name, klass, includes| [name] + evaluated_names_(includes||[]) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def list_to_run_(list)
|
31
|
+
list.map{|name, klass, includes| [klass] + list_to_run_(includes||[]) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def evaluated_names_pairs
|
35
|
+
list = find_classes_and_includes(configured_names)
|
36
|
+
excludes = excludes(list).flatten.compact
|
37
|
+
list = filter_excludes(list, excludes)
|
38
|
+
list = filter_excludes(list, configured_remove_aliases)
|
39
|
+
list = filter_callable(list)
|
40
|
+
list
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_classes_and_includes(list)
|
44
|
+
find_classes(list).map{ |name, klass| class_and_includes(name, klass) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_class(name)
|
48
|
+
@class_finder.call(name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_classes(list)
|
52
|
+
list.map{|name| [name, find_class(name)] }.reject{|name, klass| klass.nil? }
|
53
|
+
end
|
54
|
+
|
55
|
+
def class_and_includes(name, klass)
|
56
|
+
[ name, klass, klass.respond_to?(:includes) ? find_classes_and_includes(klass.includes) : [] ]
|
57
|
+
end
|
58
|
+
|
59
|
+
def excludes(list)
|
60
|
+
list.map{|name, klass, includes| class_excludes(klass) + excludes(includes) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def class_excludes(klass)
|
64
|
+
klass.respond_to?(:excludes) ? klass.excludes : []
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_excludes(list, excludes)
|
68
|
+
list.map{|name, klass, includes| excludes.include?(name) ? nil : [name, klass, filter_excludes(includes, excludes)] }.compact
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter_callable(list)
|
72
|
+
list.map{|name, klass, includes|
|
73
|
+
(klass.instance_methods.include?(:call) ? [name, klass] : [nil, nil]) << filter_callable(includes)
|
74
|
+
}.compact
|
75
|
+
end
|
76
|
+
|
77
|
+
def configured_remove_aliases
|
78
|
+
@configured_remove_aliases ||= configured_remove.map{|remove|
|
79
|
+
list = [remove]
|
80
|
+
klass = find_class(remove)
|
81
|
+
list += klass.aliases if klass.respond_to?(:aliases)
|
82
|
+
list
|
83
|
+
}.flatten.compact
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/lib/pre-commit/runner.rb
CHANGED
@@ -1,20 +1,65 @@
|
|
1
|
+
require 'pluginator'
|
2
|
+
require 'pre-commit/utils/staged_files'
|
3
|
+
require 'pre-commit/configuration'
|
4
|
+
require 'pre-commit/list_evaluator'
|
5
|
+
|
1
6
|
module PreCommit
|
2
7
|
class Runner
|
8
|
+
include PreCommit::Utils::StagedFiles
|
3
9
|
|
4
|
-
|
5
|
-
checks_to_run = PreCommit.checks_to_run
|
10
|
+
attr_reader :pluginator, :config
|
6
11
|
|
7
|
-
|
8
|
-
|
12
|
+
def initialize(stderr = nil, staged_files = nil, config = nil, pluginator = nil)
|
13
|
+
@stderr = (stderr or $stderr)
|
14
|
+
@pluginator = (pluginator or PreCommit.pluginator)
|
15
|
+
@config = (config or PreCommit::Configuration.new(@pluginator))
|
16
|
+
@staged_files = staged_files
|
17
|
+
end
|
9
18
|
|
10
|
-
|
11
|
-
|
12
|
-
|
19
|
+
def run
|
20
|
+
run_single(:warnings)
|
21
|
+
run_single(:checks ) or return false
|
22
|
+
true
|
23
|
+
end
|
13
24
|
|
14
|
-
|
25
|
+
def run_single(name)
|
26
|
+
show_output(name, execute(list_to_run(name)))
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_output(name, list)
|
30
|
+
if list.any?
|
31
|
+
@stderr.puts send(name, list)
|
32
|
+
return false
|
15
33
|
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute(list)
|
38
|
+
list.map{|cmd| cmd.new(pluginator, config, list).call(staged_files.dup) }.compact
|
39
|
+
end
|
40
|
+
|
41
|
+
def list_to_run(name)
|
42
|
+
list_evaluator.send(:"#{name}_evaluated", :list_to_run)
|
43
|
+
end
|
44
|
+
|
45
|
+
def list_evaluator
|
46
|
+
@list_evaluator ||= PreCommit::ListEvaluator.new(config)
|
47
|
+
end
|
48
|
+
|
49
|
+
def warnings(list)
|
50
|
+
<<-WARNINGS
|
51
|
+
pre-commit: Some warnings were raised. These will not stop commit:
|
52
|
+
#{list.join("\n")}
|
53
|
+
WARNINGS
|
54
|
+
end
|
55
|
+
|
56
|
+
def checks(list)
|
57
|
+
<<-ERRORS
|
58
|
+
pre-commit: Stopping commit because of errors.
|
59
|
+
#{list.join("\n")}
|
60
|
+
pre-commit: You can bypass this check using `git commit -n`
|
16
61
|
|
17
|
-
|
62
|
+
ERRORS
|
18
63
|
end
|
19
64
|
|
20
65
|
end
|