renuo-bin-check 0.2.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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +33 -0
  3. data/.editorconfig +20 -0
  4. data/.gitignore +9 -0
  5. data/.reek +18 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +26 -0
  8. data/.ruby-version +1 -0
  9. data/.travis.yml +32 -0
  10. data/CHANGELOG.md +36 -0
  11. data/CODE_OF_CONDUCT.md +13 -0
  12. data/CONTRIBUTING.md +41 -0
  13. data/Gemfile +3 -0
  14. data/LICENSE +22 -0
  15. data/README.md +142 -0
  16. data/Rakefile +7 -0
  17. data/bin/check +66 -0
  18. data/bin/setup +61 -0
  19. data/lib/renuo-bin-check.rb +8 -0
  20. data/lib/renuo_bin_check/cacher.rb +46 -0
  21. data/lib/renuo_bin_check/default_scripts/default_rails.rb +160 -0
  22. data/lib/renuo_bin_check/initializer.rb +21 -0
  23. data/lib/renuo_bin_check/master_thread.rb +42 -0
  24. data/lib/renuo_bin_check/printer.rb +15 -0
  25. data/lib/renuo_bin_check/result.rb +10 -0
  26. data/lib/renuo_bin_check/script_config.rb +61 -0
  27. data/lib/renuo_bin_check/servant_thread.rb +43 -0
  28. data/lib/renuo_bin_check/version.rb +4 -0
  29. data/renuo-bin-check.gemspec +35 -0
  30. data/spec/code_climate.rb +0 -0
  31. data/spec/code_climate.travis.rb +4 -0
  32. data/spec/factories/cacher.rb +16 -0
  33. data/spec/factories/result.rb +29 -0
  34. data/spec/factories/script_config.rb +41 -0
  35. data/spec/integration/initializer_spec.rb +209 -0
  36. data/spec/renuo/bin-check/cacher_spec.rb +51 -0
  37. data/spec/renuo/bin-check/initializer_spec.rb +23 -0
  38. data/spec/renuo/bin-check/master_thread_spec.rb +46 -0
  39. data/spec/renuo/bin-check/printer_spec.rb +25 -0
  40. data/spec/renuo/bin-check/result_spec.rb +18 -0
  41. data/spec/renuo/bin-check/script_config_spec.rb +69 -0
  42. data/spec/renuo/bin-check/servant_thread_spec.rb +97 -0
  43. data/spec/spec-files/file1 +1 -0
  44. data/spec/spec-files/file2 +1 -0
  45. data/spec/spec-files/file2_copy +1 -0
  46. data/spec/spec-files/test_script_exit0 +5 -0
  47. data/spec/spec-files/test_script_exit1 +5 -0
  48. data/spec/spec-files/test_script_exit1_no_error_output +3 -0
  49. data/spec/spec-files/test_script_sleep1 +2 -0
  50. data/spec/spec-files/test_script_sleep2 +2 -0
  51. data/spec/spec_helper.rb +35 -0
  52. metadata +288 -0
data/bin/setup ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ # path to your application root.
5
+ APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6
+
7
+ def run(name, file_which_must_not_exist = nil)
8
+ unless file_which_must_not_exist && File.exist?(file_which_must_not_exist)
9
+ puts "== #{name} =="
10
+ yield
11
+ puts
12
+ end
13
+ end
14
+
15
+ def install_or_update_gem(gem)
16
+ if ENV['UPDATE']
17
+ system "gem install #{gem}"
18
+ else
19
+ system "which #{gem.gsub('_', '-')} || gem install #{gem}"
20
+ end
21
+ end
22
+
23
+ Dir.chdir APP_ROOT do
24
+ run 'Installing dependencies' do
25
+ system 'gem install bundler --conservative'
26
+ system 'bundle check || bundle install --jobs=3 --retry=3'
27
+ install_or_update_gem('pry')
28
+ install_or_update_gem('rubocop')
29
+ install_or_update_gem('reek')
30
+ install_or_update_gem('filewatcher')
31
+ end
32
+
33
+ run 'Installing JS dependencies' do
34
+ system 'which coffeelint || npm install -g coffeelint'
35
+ system 'which tsc || npm install -g typescript'
36
+ system 'which tslint || npm install -g tslint'
37
+ end
38
+
39
+ run 'Copying config/application.yml', 'config/application.yml' do
40
+ system 'cp config/application.example.yml config/application.yml'
41
+ end
42
+
43
+ run('Preparing database') do
44
+ system 'bin/rake db:version >> /dev/null 2>&1 || bin/rake db:create:all && bin/rake db:setup'
45
+ end
46
+
47
+ run 'Removing old logs and tempfiles' do
48
+ system 'rm -f log/*'
49
+ system 'rm -rf tmp/cache'
50
+ end
51
+
52
+ run 'Creating pre-commit hook link', '.git/hooks/pre-commit' do
53
+ system 'ln -s ../../bin/check .git/hooks/pre-commit'
54
+ end
55
+
56
+ run('Setting dev host in /etc/hosts') do
57
+ system 'grep \'<appname>.dev\' /etc/hosts || echo \'127.0.0.1 <appname>.dev\' | sudo tee -a /etc/hosts'
58
+ end
59
+
60
+ run('Running checks') { abort('bin/check failed') unless system('bin/check') }
61
+ end
@@ -0,0 +1,8 @@
1
+ require 'renuo_bin_check/cacher'
2
+ require 'renuo_bin_check/initializer'
3
+ require 'renuo_bin_check/master_thread'
4
+ require 'renuo_bin_check/printer'
5
+ require 'renuo_bin_check/result'
6
+ require 'renuo_bin_check/script_config'
7
+ require 'renuo_bin_check/servant_thread'
8
+ require 'renuo_bin_check/version'
@@ -0,0 +1,46 @@
1
+ require 'digest'
2
+ require 'fileutils'
3
+ require 'renuo_bin_check/result'
4
+
5
+ module RenuoBinCheck
6
+ class Cacher
7
+ def initialize(name, paths)
8
+ @name = name
9
+ @file_names = paths.map { |path| Dir[path] }.flatten.sort
10
+ @hash = hash_files
11
+ end
12
+
13
+ def exists?
14
+ File.exist?("tmp/bin-check/#{@name}/#{@hash}")
15
+ end
16
+
17
+ def result
18
+ read
19
+ end
20
+
21
+ def cache(result)
22
+ FileUtils.mkdir_p "tmp/bin-check/#{@name}/#{@hash}"
23
+ File.write "tmp/bin-check/#{@name}/#{@hash}/standard_output", result.standard_output
24
+ File.write "tmp/bin-check/#{@name}/#{@hash}/error_output", result.error_output
25
+ File.write "tmp/bin-check/#{@name}/#{@hash}/exit_code", result.exit_code
26
+ end
27
+
28
+ private
29
+
30
+ def read
31
+ standard_output = File.read("tmp/bin-check/#{@name}/#{@hash}/standard_output")
32
+ error_output = File.read("tmp/bin-check/#{@name}/#{@hash}/error_output")
33
+ exit_code = File.read("tmp/bin-check/#{@name}/#{@hash}/exit_code").to_i
34
+ Result.new(standard_output, error_output, exit_code)
35
+ end
36
+
37
+ def hash_files
38
+ Digest::MD5.hexdigest @file_names.map { |file_name| hash_file(file_name) if File.file? file_name }.to_s
39
+ end
40
+
41
+ #:reek:UtilityFunction
42
+ def hash_file(file_name)
43
+ Digest::MD5.file(file_name).hexdigest + Digest::MD5.hexdigest(file_name)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,160 @@
1
+ module RenuoBinCheck
2
+ # rubocop:disable Metrics/ModuleLength
3
+ module DefaultScripts
4
+ # rubocop:disable Metrics/AbcSize
5
+ # rubocop:disable Metrics/MethodLength
6
+ # :reek:TooManyStatements
7
+ def rails
8
+ bin_check = RenuoBinCheck::Initializer.new
9
+
10
+ mini_profiler(bin_check)
11
+ todo(bin_check)
12
+ console_log(bin_check)
13
+ put_without_brackets(bin_check)
14
+ put_with_brackets(bin_check)
15
+ pp_and_p(bin_check)
16
+ p_with_brackets(bin_check)
17
+ rubocop_autocorrect(bin_check)
18
+ slim_lint(bin_check)
19
+ scss_lint(bin_check)
20
+ tslint(bin_check)
21
+ brakeman(bin_check)
22
+ reek(bin_check)
23
+ rspec(bin_check)
24
+
25
+ bin_check.run
26
+ end
27
+ # rubocop:enable Metrics/AbcSize
28
+ # rubocop:enable Metrics/MethodLength
29
+
30
+ def mini_profiler(bin_check)
31
+ bin_check.check do |config|
32
+ config.command "grep 'rack-mini-profiler' Gemfile.lock >> /dev/null"
33
+ config.reversed_exit true
34
+ config.files ['Gemfile.lock']
35
+ end
36
+ end
37
+
38
+ def todo(bin_check)
39
+ bin_check.check do |config|
40
+ config.command "grep --exclude-dir='app/assets/typings/**' -i -r 'TODO' app spec config db Rakefile README.md"\
41
+ ' Gemfile'
42
+ config.reversed_exit true
43
+ config.files ['app/**/*', 'spec/**/*', 'config/**/*', 'db/**/*', 'Rakefile', 'README.md', 'Gemfile']
44
+ end
45
+ end
46
+
47
+ def console_log(bin_check)
48
+ bin_check.check do |config|
49
+ config.command "grep -i -r 'console.log' app spec"
50
+ config.reversed_exit true
51
+ config.files ['app/**/*', 'spec/**/*']
52
+ end
53
+ end
54
+
55
+ def put_without_brackets(bin_check)
56
+ bin_check.check do |config|
57
+ config.command "grep -i -r ' puts ' app spec"
58
+ config.reversed_exit true
59
+ config.files ['app/**/*', 'spec/**/*']
60
+ end
61
+ end
62
+
63
+ def put_with_brackets(bin_check)
64
+ bin_check.check do |config|
65
+ config.command "grep -i -r ' puts(' app spec"
66
+ config.reversed_exit true
67
+ config.files ['app/**/*', 'spec/**/*']
68
+ end
69
+ end
70
+
71
+ def pp_and_p(bin_check)
72
+ bin_check.check do |config|
73
+ config.command "grep -i -r '( pp? [^=])|(= pp? )' app spec"
74
+ config.reversed_exit true
75
+ config.files ['app/**/*', 'spec/**/*']
76
+ end
77
+ end
78
+
79
+ def p_with_brackets(bin_check)
80
+ bin_check.check do |config|
81
+ config.command "grep -i -r ' p(' app spec"
82
+ config.reversed_exit true
83
+ config.files ['app/**/*', 'spec/**/*']
84
+ end
85
+ end
86
+
87
+ def rubocop_autocorrect(bin_check)
88
+ bin_check.check do |config|
89
+ config.command 'bundle exec rubocop -a -D -c .rubocop.yml'
90
+ config.files ['app/**/*.rb', 'spec/**/*.rb']
91
+ end
92
+ end
93
+
94
+ def slim_lint(bin_check)
95
+ bin_check.check do |config|
96
+ config.command 'bundle exec slim-lint app/views/ -c .slim-lint.yml'
97
+ config.files ['app/views/**/*.slim']
98
+ end
99
+ end
100
+
101
+ def scss_lint(bin_check)
102
+ bin_check.check do |config|
103
+ config.command 'scss-lint app/assets/stylesheets/**/*.scss'
104
+ config.files ['app/assets/stylesheets/**/*.scss']
105
+ end
106
+ end
107
+
108
+ def tslint(bin_check)
109
+ bin_check.check do |config|
110
+ config.command 'tslint -c tslint.json app/assets/javascripts/**/*.ts'
111
+ config.files ['app/assets/javascripts/**/*.ts']
112
+ end
113
+ end
114
+
115
+ def coffeelint(bin_check)
116
+ bin_check.check do |config|
117
+ config.command 'coffeelint -f .coffeelint.json app/assets/javascripts/**/*.coffee'
118
+ config.files ['app/assets/javascripts/**/*.coffee']
119
+ end
120
+ end
121
+
122
+ def brakeman(bin_check)
123
+ bin_check.check do |config|
124
+ config.command 'bundle exec brakeman -q -z --summary > /dev/null'
125
+ end
126
+ end
127
+
128
+ def reek(bin_check)
129
+ bin_check.check do |config|
130
+ config.command 'bundle exec reek'
131
+ config.files ['app/**/*.rb']
132
+ end
133
+ end
134
+
135
+ def rspec(bin_check)
136
+ bin_check.check do |config|
137
+ config.command 'bundle exec rspec'
138
+ config.files ['app/**/*.rb', 'spec/**/*.rb']
139
+ end
140
+ end
141
+
142
+ module_function :rails
143
+ module_function :mini_profiler
144
+ module_function :todo
145
+ module_function :console_log
146
+ module_function :put_without_brackets
147
+ module_function :put_with_brackets
148
+ module_function :pp_and_p
149
+ module_function :p_with_brackets
150
+ module_function :rubocop_autocorrect
151
+ module_function :slim_lint
152
+ module_function :scss_lint
153
+ module_function :tslint
154
+ module_function :coffeelint
155
+ module_function :brakeman
156
+ module_function :reek
157
+ module_function :rspec
158
+ end
159
+ # rubocop:enable Metrics/ModuleLength
160
+ end
@@ -0,0 +1,21 @@
1
+ require 'renuo_bin_check/printer'
2
+
3
+ module RenuoBinCheck
4
+ class Initializer
5
+ attr_reader :master_thread
6
+
7
+ def initialize
8
+ @master_thread = MasterThread.new(Printer.new)
9
+ end
10
+
11
+ def check
12
+ config = ScriptConfig.new
13
+ yield(config)
14
+ @master_thread.add_thread(config)
15
+ end
16
+
17
+ def run
18
+ @master_thread.finalize
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ require 'thwait'
2
+
3
+ module RenuoBinCheck
4
+ class MasterThread
5
+ attr_reader :threads, :printer
6
+
7
+ def initialize(printer)
8
+ @threads = []
9
+ @results = []
10
+ @printer = printer
11
+ end
12
+
13
+ def add_thread(script_config)
14
+ threads << Thread.new do
15
+ servant = ServantThread.new(script_config)
16
+ Thread.current[:result] = servant.run
17
+ end
18
+ end
19
+
20
+ def finalize
21
+ waiter = ThreadsWait.new(threads)
22
+ until waiter.empty?
23
+ result = waiter.next_wait[:result]
24
+ @results << result
25
+ exit_with_error(result) if result.exit_code == 1
26
+ end
27
+ exit_with_success
28
+ end
29
+
30
+ private
31
+
32
+ def exit_with_error(result)
33
+ @printer.print_error_output(result)
34
+ exit 1
35
+ end
36
+
37
+ def exit_with_success
38
+ @printer.print_standard_output(@results)
39
+ exit 0
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ module RenuoBinCheck
2
+ class Printer
3
+ # :reek:UtilityFunction
4
+ def print_standard_output(results)
5
+ results.each { |result| $stdout.puts result.standard_output }
6
+ end
7
+
8
+ # :reek:UtilityFunction
9
+ def print_error_output(result)
10
+ error_output = result.error_output
11
+ error_output = result.standard_output if error_output == ''
12
+ $stderr.puts error_output
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module RenuoBinCheck
2
+ class Result
3
+ attr_reader :standard_output, :error_output, :exit_code
4
+ def initialize(standard_output, error_output, exit_code)
5
+ @standard_output = standard_output
6
+ @error_output = error_output
7
+ @exit_code = exit_code
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,61 @@
1
+ module RenuoBinCheck
2
+ # :reek:TooManyInstanceVariables:
3
+ class ScriptConfig
4
+ attr_accessor :script_command, :script_files, :script_name, :script_reversed_exit, :script_standard_output,
5
+ :script_error_output, :appended_standard_output, :appended_error_output
6
+
7
+ def command(command)
8
+ @script_command = command
9
+ end
10
+
11
+ def files(files)
12
+ @script_files = files
13
+ end
14
+
15
+ def name(name)
16
+ @script_name = name
17
+ end
18
+
19
+ def success_message(standard_output)
20
+ if standard_output[0] == '+'
21
+ @appended_standard_output = standard_output.sub('+', '')
22
+ else
23
+ @script_standard_output = standard_output
24
+ end
25
+ end
26
+
27
+ def error_message(error_output)
28
+ if error_output[0] == '+'
29
+ @appended_error_output = error_output.sub('+', '')
30
+ else
31
+ @script_error_output = error_output
32
+ end
33
+ end
34
+
35
+ def reversed_exit(reversed_exit)
36
+ @script_reversed_exit = reversed_exit
37
+ end
38
+
39
+ def script_name
40
+ @script_name ||= Digest::MD5.hexdigest(@script_command)
41
+ end
42
+
43
+ def reversed_exit?
44
+ @script_reversed_exit
45
+ end
46
+
47
+ def appended_standard_output
48
+ @appended_standard_output ||= ''
49
+ end
50
+
51
+ def appended_error_output
52
+ @appended_error_output ||= ''
53
+ end
54
+
55
+ def script_command
56
+ raise 'There must be a command set for each script you want to run. Find further instruction on how to use this' \
57
+ ' Gem here in the Readme: https://github.com/renuo/renuo-bin-check' unless @script_command
58
+ @script_command
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ require 'open3'
2
+ require 'renuo_bin_check/result'
3
+
4
+ module RenuoBinCheck
5
+ class ServantThread
6
+ attr_reader :script_config
7
+ def initialize(script_config)
8
+ @script_config = script_config
9
+ script_files = @script_config.script_files
10
+ @cacher = Cacher.new(@script_config.script_name, script_files) if script_files
11
+ end
12
+
13
+ def run
14
+ @script_config.script_files ? run_with_cache : run_command
15
+ end
16
+
17
+ private
18
+
19
+ def run_with_cache
20
+ @cacher.cache(run_command) unless @cacher.exists?
21
+ @cacher.result
22
+ end
23
+
24
+ def run_command
25
+ standard_output, error_output, process = Open3.capture3(@script_config.script_command)
26
+ @result = Result.new(standard_output, error_output, process.exitstatus)
27
+ override_output
28
+ @script_config.reversed_exit? ? reverse_result : @result
29
+ end
30
+
31
+ def override_output
32
+ standard_output = @script_config.script_standard_output ||= @result.standard_output
33
+ error_output = @script_config.script_error_output ||= @result.error_output
34
+ @result = Result.new(standard_output + @script_config.appended_standard_output,
35
+ error_output + @script_config.appended_error_output,
36
+ @result.exit_code)
37
+ end
38
+
39
+ def reverse_result
40
+ Result.new(@result.error_output, @result.standard_output, @result.exit_code == 0 ? 1 : 0)
41
+ end
42
+ end
43
+ end