checker 0.0.1 → 0.7.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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +13 -0
  5. data/CHANGELOG +103 -0
  6. data/Gemfile +3 -0
  7. data/Gemfile.lock +64 -0
  8. data/LICENCE +21 -0
  9. data/README.md +142 -0
  10. data/Rakefile +4 -0
  11. data/bin/checker +1 -0
  12. data/checker.gemspec +11 -4
  13. data/lib/checker.rb +28 -3
  14. data/lib/checker/cli.rb +88 -4
  15. data/lib/checker/core_ext.rb +25 -2
  16. data/lib/checker/helper.rb +20 -0
  17. data/lib/checker/installator.rb +65 -0
  18. data/lib/checker/modules/base.rb +224 -0
  19. data/lib/checker/modules/coffeescript.rb +22 -0
  20. data/lib/checker/modules/conflict.rb +20 -0
  21. data/lib/checker/modules/console_log.rb +20 -0
  22. data/lib/checker/modules/haml.rb +12 -14
  23. data/lib/checker/modules/javascript.rb +32 -0
  24. data/lib/checker/modules/pry.rb +20 -0
  25. data/lib/checker/modules/rubocop.rb +17 -0
  26. data/lib/checker/modules/ruby.rb +5 -21
  27. data/lib/checker/modules/sass.rb +80 -0
  28. data/lib/checker/modules/slim.rb +21 -0
  29. data/lib/checker/modules/yaml.rb +19 -0
  30. data/lib/checker/options.rb +22 -0
  31. data/lib/checker/result.rb +21 -0
  32. data/lib/checker/results/console_log.rb +13 -0
  33. data/lib/checker/results/default.rb +13 -0
  34. data/lib/checker/results/javascript.rb +24 -0
  35. data/lib/checker/results/rubocop.rb +6 -0
  36. data/lib/checker/rvm.rb +16 -0
  37. data/lib/checker/version.rb +3 -0
  38. data/spec/assets/stylesheets/empty +0 -0
  39. data/spec/checker/cli_spec.rb +37 -0
  40. data/spec/checker/fixtures/conflict/with_conflict.rb +5 -0
  41. data/spec/checker/fixtures/conflict/without_conflict.rb +2 -0
  42. data/spec/checker/fixtures/console_log/with_console_log.js +3 -0
  43. data/spec/checker/fixtures/console_log/without_console_log.js +2 -0
  44. data/spec/checker/fixtures/pry/with_both.rb +4 -0
  45. data/spec/checker/fixtures/pry/with_pry.rb +3 -0
  46. data/spec/checker/fixtures/pry/with_pry_remote.rb +3 -0
  47. data/spec/checker/fixtures/pry/without_pry.rb +2 -0
  48. data/spec/checker/fixtures/ruby/bad.rb +2 -0
  49. data/spec/checker/fixtures/ruby/good.rb +3 -0
  50. data/spec/checker/fixtures/yaml/bad.yaml +18 -0
  51. data/spec/checker/fixtures/yaml/good.yaml +18 -0
  52. data/spec/checker/modules/base_spec.rb +53 -0
  53. data/spec/checker/modules/coffeescript_spec.rb +16 -0
  54. data/spec/checker/modules/conflict_spec.rb +23 -0
  55. data/spec/checker/modules/console_log_spec.rb +49 -0
  56. data/spec/checker/modules/haml_spec.rb +18 -0
  57. data/spec/checker/modules/javascript_spec.rb +69 -0
  58. data/spec/checker/modules/pry_spec.rb +35 -0
  59. data/spec/checker/modules/ruby_spec.rb +26 -0
  60. data/spec/checker/modules/sass_spec.rb +101 -0
  61. data/spec/checker/modules/slim_spec.rb +18 -0
  62. data/spec/checker/modules/yaml_spec.rb +27 -0
  63. data/spec/spec_helper.rb +27 -0
  64. data/templates/checker-prepare-commit-msg +15 -0
  65. metadata +125 -15
  66. data/README +0 -4
  67. data/lib/checker/cli/execute.rb +0 -61
  68. data/lib/checker/modules/all.rb +0 -16
  69. data/lib/checker/utils.rb +0 -48
data/lib/checker/cli.rb CHANGED
@@ -1,11 +1,95 @@
1
1
  require 'checker'
2
- require 'checker/cli/execute'
3
2
 
4
3
  module Checker
5
- module Modules; end
6
-
7
4
  class CLI
5
+ class << self
6
+ def execute
7
+ directory_to_check = nil
8
+
9
+ if ARGV.size == 0
10
+ modules = get_modules_to_check
11
+ else
12
+ if ARGV[0] == "install"
13
+ Checker::Installator.install!
14
+ elsif ARGV[0] == "reinstall"
15
+ Checker::Installator.reinstall!
16
+ elsif ARGV[0] == "help"
17
+ Checker::Helper.show_help!
18
+ elsif ARGV[0] == "modules"
19
+ Checker::Helper.show_modules!(self.available_modules)
20
+ elsif File.exist?(ARGV[0]) && File.directory?(ARGV[0])
21
+ directory_to_check = ARGV[0].gsub /\/+$/, ''
22
+ modules = 'all'
23
+ else
24
+ modules = ARGV.map(&:downcase)
25
+ end
26
+ end
27
+
28
+ if modules.empty? || modules.include?('all')
29
+ modules = available_modules
30
+ end
31
+
32
+ check_module_availability(modules) do |result|
33
+ puts "Modules not available: #{result.join(", ")}.\n"
34
+ puts "Available: all, #{available_modules.join(", ")}\n"
35
+ puts "Check your git config checker.check\n"
36
+ exit 1
37
+ end
38
+
39
+ module_instances = []
40
+ if !directory_to_check.nil?
41
+ files = Dir["#{directory_to_check}/**/*"]
42
+ else
43
+ files = modified_files
44
+ end
45
+ modules.each do |mod|
46
+ klass = "Checker::Modules::#{mod.classify}".constantize
47
+ module_instances << klass.new(files.dup)
48
+ end
49
+
50
+ files_checked = module_instances.map(&:files_to_check).flatten.uniq
51
+ puts "[ CHECKER #{Checker::VERSION} - #{files_checked.size} files ]".light_blue
52
+
53
+ results = module_instances.map(&:check)
54
+ show_full_status module_instances
55
+ exit (results.all_true? ? 0 : 1)
56
+ end
57
+
58
+ protected
59
+ def available_modules
60
+ Checker::Modules.constants.map(&:to_s).map(&:underscore) - ['base']
61
+ end
62
+
63
+ def check_module_availability(modules)
64
+ result = modules - available_modules
65
+ unless result.empty?
66
+ if block_given?
67
+ yield(result)
68
+ end
69
+ end
70
+ end
71
+
72
+ def get_modules_to_check
73
+ Checker::Options.modules_to_check
74
+ end
75
+
76
+ def modified_files
77
+ @modified_files ||= `git status --porcelain | egrep "^(A|M|R).*" | awk ' { if ($3 == "->") print $4; else print $2 } '`.split
78
+ end
8
79
 
9
- include Execute
80
+ def show_full_status modules
81
+ full_status = {:total => 0, :ok => 0, :warning => 0, :fail => 0}
82
+ modules.each do |m|
83
+ full_status = full_status.merge(m.full_results) { |k, v1, v2| v1 + v2 }
84
+ end
85
+ puts "-" * 80
86
+ print "#{full_status[:total]} checks preformed, "
87
+ print "#{full_status[:ok]} ok".green
88
+ print ", "
89
+ print "#{full_status[:warning]} warning".magenta
90
+ print ", "
91
+ puts "#{full_status[:fail]} fail".red
92
+ end
93
+ end
10
94
  end
11
95
  end
@@ -1,5 +1,3 @@
1
- require 'checker/utils'
2
-
3
1
  class CoreExt
4
2
  def self.constantize(camel_cased_word)
5
3
  names = camel_cased_word.split('::')
@@ -11,6 +9,23 @@ class CoreExt
11
9
  end
12
10
  constant
13
11
  end
12
+
13
+ def self.classify(underscored_word)
14
+ words = underscored_word.split("_")
15
+ words.each do |word|
16
+ word.capitalize!
17
+ end.join("")
18
+ end
19
+
20
+ def self.underscore(camel_cased_word)
21
+ word = camel_cased_word.to_s.dup
22
+ word.gsub!(/::/, '/')
23
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
24
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
25
+ word.tr!("-", "_")
26
+ word.downcase!
27
+ word
28
+ end
14
29
  end
15
30
 
16
31
  class String
@@ -18,6 +33,14 @@ class String
18
33
  CoreExt.constantize(self)
19
34
  end
20
35
 
36
+ def classify
37
+ CoreExt.classify(self)
38
+ end
39
+
40
+ def underscore
41
+ CoreExt.underscore(self)
42
+ end
43
+
21
44
  def ends_with?(patt)
22
45
  patt = Regexp.new(Regexp.escape(patt) + "$")
23
46
  self.match patt
@@ -0,0 +1,20 @@
1
+ module Checker
2
+ class Helper
3
+ def self.show_help!
4
+ puts "Checker version #{Checker::VERSION}"
5
+ puts "* install - type 'checker install' to install git pre-commit-hook"
6
+ puts "* reinstall - type 'checker reinstall' to purge current hook git pre-commit-hook and install new one"
7
+ puts "* modules - type 'checker modules' to see available modules"
8
+ puts "* checks - type 'checker [module name]' to check your current git stage"
9
+ puts "* [dir] - type 'checker [directory]' to check all files in specified directory"
10
+ puts " ex. 'checker lib/'; 'checker .' etc"
11
+ puts "* help - type 'checker help' to see this message :)"
12
+ exit 0
13
+ end
14
+
15
+ def self.show_modules!(modules)
16
+ puts "Available modules are: all, #{modules.join(", ")}"
17
+ exit 0
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,65 @@
1
+ module Checker
2
+ class Installator
3
+ def self.template
4
+ dir = File.expand_path('../../..', __FILE__)
5
+ temp = File.read(File.join(dir, "/templates/checker-prepare-commit-msg"))
6
+ ERB.new(temp).result
7
+ end
8
+
9
+ def self.hooks_dir
10
+ "#{Dir.pwd}/.git/hooks"
11
+ end
12
+
13
+ def self.check_hook!
14
+ unless Dir.exist?(hooks_dir)
15
+ puts "Git Hooks dir not found. Are you sure you are inside project with git?"
16
+ exit 1
17
+ end
18
+ end
19
+
20
+ def self.reinstall!
21
+ check_hook!
22
+
23
+ pre_commit = "#{hooks_dir}/prepare-commit-msg"
24
+ if File.exists?(pre_commit)
25
+ puts "Removing current git precommit hook..."
26
+ File.delete(pre_commit)
27
+ end
28
+
29
+ install!
30
+ end
31
+
32
+ def self.install!
33
+ check_hook!
34
+
35
+ pre_commit = "#{hooks_dir}/prepare-commit-msg"
36
+ if File.exist?(pre_commit)
37
+ puts "Appending checker script to existing prepare-commit-msg hook..."
38
+ begin
39
+ open(pre_commit, 'a') do |f|
40
+ f.puts(self.template)
41
+ f.chmod(0755)
42
+ end
43
+ rescue Exception => e
44
+ puts "Couldn't append checker script: #{e.message}"
45
+ exit 1
46
+ end
47
+ exit 0
48
+ else
49
+ tmp = self.template
50
+ str = "#!/bin/bash \n #{tmp}"
51
+ begin
52
+ open(pre_commit, "w") do |f|
53
+ f.puts(str)
54
+ f.chmod(0755)
55
+ end
56
+ rescue Exception => e
57
+ puts "Couldn't write checker script: #{e.message}"
58
+ exit 1
59
+ end
60
+ puts "Script installed!"
61
+ exit 0
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,224 @@
1
+ module Checker
2
+ module Modules
3
+ class Base
4
+ attr_accessor :files, :full_results
5
+
6
+ def initialize(file_list = nil)
7
+ self.files = file_list
8
+ self.full_results = {:total => 0, :ok => 0, :warning => 0, :fail => 0}
9
+ end
10
+
11
+ def check
12
+ check_files_existing or return true
13
+ print_module_header
14
+ check_executable or return true
15
+ check_all_files
16
+ valid?
17
+ end
18
+
19
+ def valid?
20
+ @results.all_true?
21
+ end
22
+
23
+ def files_to_check
24
+ @files_to_check ||= begin
25
+ if self.class.extensions.any?
26
+ self.files.select { |f|
27
+ self.class.extensions.map { |ex| f.ends_with?(".#{ex}") }.any?
28
+ }
29
+ else
30
+ self.files
31
+ end
32
+ end
33
+ end
34
+
35
+ def classname
36
+ self.class.to_s.split('::').last
37
+ end
38
+
39
+ private
40
+
41
+ def print_module_header
42
+ color "[ #{name} - #{files_to_check.size} files ]\n", :light_blue
43
+ end
44
+
45
+ def dependency_message
46
+ "Executable not found, skipping...\n"
47
+ end
48
+
49
+ def check_files_existing
50
+ files_to_check.any?
51
+ end
52
+
53
+ def check_executable
54
+ if check_for_executable
55
+ true
56
+ else
57
+ color dependency_message, :magenta
58
+ false
59
+ end
60
+ end
61
+
62
+ def check_for_executable
63
+ true
64
+ end
65
+
66
+ def check_all_files
67
+ with_checker_cache do
68
+ @results = files_to_check.map do |file_name|
69
+ gather_result :total
70
+ color " Checking #{file_name}...", :yellow
71
+ result = check_one_file(file_name)
72
+ show_status result.status
73
+ gather_result result.status
74
+ flush_and_forget_output result.status
75
+ result.success?
76
+ end
77
+ end
78
+ end
79
+
80
+ def check_one(filename, options = {})
81
+ puts "Called from #{self.class} - extend me in here!"
82
+ false
83
+ end
84
+
85
+ def check_one_file file_name
86
+ checksum = ::Digest::MD5.hexdigest(file_name)
87
+ debug(file_name)
88
+ checkout_file(file_name, checksum)
89
+ check_one(checkout_file_name(checksum), :extension => File.extname(file_name))
90
+ end
91
+
92
+ def self.extensions *args
93
+ @extensions ||= []
94
+ if args.empty?
95
+ @extensions
96
+ else
97
+ @extensions += args
98
+ end
99
+ end
100
+
101
+ def gather_result result
102
+ self.full_results[result] += 1
103
+ end
104
+
105
+ def plain_command(cmd, options = {})
106
+ cmd = parse_command(cmd, options)
107
+ execute(cmd, options)
108
+ end
109
+
110
+ def silent_command(cmd, options = {})
111
+ options = { :output => false, :return_boolean => true }.merge(options)
112
+ cmd = parse_command(cmd, options)
113
+ execute(cmd, options)
114
+ end
115
+
116
+ def flush_and_forget_output(status)
117
+ print @buffer.to_s if (status == :warning or status == :fail)
118
+ @buffer = ""
119
+ end
120
+
121
+ def print_success_message
122
+ puts " [OK]".green
123
+ end
124
+
125
+ def print_warning_message
126
+ puts " [WARNING]".magenta
127
+ end
128
+
129
+ def print_fail_message
130
+ puts " [FAIL]".red
131
+ end
132
+
133
+ def show_status(status)
134
+ if status == :ok
135
+ print_success_message
136
+ elsif status == :warning
137
+ print_warning_message
138
+ else
139
+ print_fail_message
140
+ end
141
+ end
142
+
143
+ def execute(cmd, options = {})
144
+ debug("executing: #{cmd}")
145
+ io = IO.popen(cmd)
146
+ Process.wait(io.pid)
147
+ @buffer ||= ""
148
+ @buffer << io.read
149
+ options[:return_boolean] ? success? : exitstatus
150
+ end
151
+
152
+ def exitstatus
153
+ $? && $?.exitstatus
154
+ end
155
+
156
+ def success?
157
+ $? && $?.success?
158
+ end
159
+
160
+ def parse_command command, options
161
+ options = { :bundler => true, :output => true, :rvm => true }.merge(options)
162
+ command = bundler_command(command) if use_bundler? && options[:bundler]
163
+ command = rvm_command(command) if use_rvm? && options[:rvm]
164
+ command << " > /dev/null" unless options[:output]
165
+ "#{command} 2>&1"
166
+ end
167
+
168
+ def color(str, color)
169
+ print str.colorize(color) if str.length > 0
170
+ end
171
+
172
+ def name
173
+ classname.underscore.upcase
174
+ end
175
+
176
+ def use_bundler?
177
+ File.exists?("Gemfile.lock")
178
+ end
179
+
180
+ def bundler_command(command)
181
+ "bundle exec #{command}"
182
+ end
183
+
184
+ def use_rvm?
185
+ File.exists?(rvm_shell)
186
+ end
187
+
188
+ def rails_project?
189
+ use_bundler? && File.read("Gemfile.lock").match(/ rails /)
190
+ end
191
+
192
+ def rails_with_ap?
193
+ rails_project? && File.exists?("app/assets")
194
+ end
195
+
196
+ def rvm_command(command)
197
+ Checker::RVM.rvm_command(command)
198
+ end
199
+
200
+ def rvm_shell
201
+ Checker::RVM.rvm_shell
202
+ end
203
+
204
+ def with_checker_cache
205
+ begin
206
+ `mkdir .checker-cache`
207
+ yield if block_given?
208
+ ensure
209
+ `rm -rf .checker-cache > /dev/null 2>&1`
210
+ ## for sass check
211
+ `rm -rf app/assets/stylesheets/checker-cache*` if rails_with_ap?
212
+ end
213
+ end
214
+
215
+ def checkout_file file_name, target
216
+ `git show :0:#{file_name} > #{checkout_file_name(target)} 2>/dev/null`
217
+ end
218
+
219
+ def checkout_file_name target
220
+ ".checker-cache/#{target}"
221
+ end
222
+ end
223
+ end
224
+ end