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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +33 -0
- data/.editorconfig +20 -0
- data/.gitignore +9 -0
- data/.reek +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +26 -0
- data/.ruby-version +1 -0
- data/.travis.yml +32 -0
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +142 -0
- data/Rakefile +7 -0
- data/bin/check +66 -0
- data/bin/setup +61 -0
- data/lib/renuo-bin-check.rb +8 -0
- data/lib/renuo_bin_check/cacher.rb +46 -0
- data/lib/renuo_bin_check/default_scripts/default_rails.rb +160 -0
- data/lib/renuo_bin_check/initializer.rb +21 -0
- data/lib/renuo_bin_check/master_thread.rb +42 -0
- data/lib/renuo_bin_check/printer.rb +15 -0
- data/lib/renuo_bin_check/result.rb +10 -0
- data/lib/renuo_bin_check/script_config.rb +61 -0
- data/lib/renuo_bin_check/servant_thread.rb +43 -0
- data/lib/renuo_bin_check/version.rb +4 -0
- data/renuo-bin-check.gemspec +35 -0
- data/spec/code_climate.rb +0 -0
- data/spec/code_climate.travis.rb +4 -0
- data/spec/factories/cacher.rb +16 -0
- data/spec/factories/result.rb +29 -0
- data/spec/factories/script_config.rb +41 -0
- data/spec/integration/initializer_spec.rb +209 -0
- data/spec/renuo/bin-check/cacher_spec.rb +51 -0
- data/spec/renuo/bin-check/initializer_spec.rb +23 -0
- data/spec/renuo/bin-check/master_thread_spec.rb +46 -0
- data/spec/renuo/bin-check/printer_spec.rb +25 -0
- data/spec/renuo/bin-check/result_spec.rb +18 -0
- data/spec/renuo/bin-check/script_config_spec.rb +69 -0
- data/spec/renuo/bin-check/servant_thread_spec.rb +97 -0
- data/spec/spec-files/file1 +1 -0
- data/spec/spec-files/file2 +1 -0
- data/spec/spec-files/file2_copy +1 -0
- data/spec/spec-files/test_script_exit0 +5 -0
- data/spec/spec-files/test_script_exit1 +5 -0
- data/spec/spec-files/test_script_exit1_no_error_output +3 -0
- data/spec/spec-files/test_script_sleep1 +2 -0
- data/spec/spec-files/test_script_sleep2 +2 -0
- data/spec/spec_helper.rb +35 -0
- 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
|