vehiculum_audit 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +30 -0
- data/.gitignore +56 -0
- data/.rspec_status +3 -0
- data/.rubocop.yml +157 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +255 -0
- data/LICENSE +21 -0
- data/README.md +40 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/configs/.fasterer.yml +3 -0
- data/lib/configs/.reek.yml +20 -0
- data/lib/configs/.rspec +5 -0
- data/lib/configs/.rubocop.yml +157 -0
- data/lib/tasks/vehiculum_audit.rake +214 -0
- data/lib/vehiculum_audit.rb +7 -0
- data/lib/vehiculum_audit/railtie.rb +20 -0
- data/lib/vehiculum_audit/version.rb +5 -0
- data/vehiculum_audit.gemspec +44 -0
- metadata +329 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Vehiculum mobility solutions GmbH
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# vehiculum-audit
|
2
|
+
|
3
|
+
A set of tools for convenient technical analysis of web applications built with Ruby and Ruby on Rails.
|
4
|
+
|
5
|
+
- Brakeman - a static analysis security vulnerability scanner for Ruby on Rails applications
|
6
|
+
- Bullet - a gem that finds and kills N+1 queries and unused eager loading
|
7
|
+
- Bundler-audit - a patch-level verification for Bundler
|
8
|
+
- Fasterer - a gem that helps Rubies go faster
|
9
|
+
- Reek - a code smell detector
|
10
|
+
- RuboCop - a Ruby static code analyzer and code formatter
|
11
|
+
|
12
|
+
The tools are configured for displaying output to the console in a single format which results in better readability and no need to switch between the tools.
|
13
|
+
|
14
|
+
The complete list of the tools and links to official repositories can be found in vehiculum_audit.gemspec file.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```
|
21
|
+
gem 'vehiculum_audit', group: %w(development test)
|
22
|
+
```
|
23
|
+
Then execute the following commands:
|
24
|
+
|
25
|
+
```
|
26
|
+
$ bundle
|
27
|
+
$ rails vehiculum_audit:install
|
28
|
+
```
|
29
|
+
|
30
|
+
## How to use this gem?
|
31
|
+
|
32
|
+
By executing the command below, you'll get a list of commands that will allow you to launch either all the tools at a time or launch every single tool separately.
|
33
|
+
|
34
|
+
```
|
35
|
+
$ rails --tasks vehiculum_audit
|
36
|
+
```
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the MIT License.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'vehiculum_audit'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
exclude_paths:
|
2
|
+
- db/migrate
|
3
|
+
|
4
|
+
Attribute:
|
5
|
+
enabled: false
|
6
|
+
|
7
|
+
ControlParameter:
|
8
|
+
enabled: false
|
9
|
+
|
10
|
+
FeatureEnvy:
|
11
|
+
enabled: false
|
12
|
+
|
13
|
+
IrresponsibleModule:
|
14
|
+
enabled: false
|
15
|
+
|
16
|
+
TooManyStatements:
|
17
|
+
max_statements: 6
|
18
|
+
|
19
|
+
UtilityFunction:
|
20
|
+
enabled: false
|
data/lib/configs/.rspec
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-minitest
|
3
|
+
- rubocop-rake
|
4
|
+
|
5
|
+
inherit_gem:
|
6
|
+
vehiculum-codestyle:
|
7
|
+
- default.yml
|
8
|
+
|
9
|
+
inherit_from: .rubocop_todo.yml
|
10
|
+
|
11
|
+
Style/Documentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/MixinUsage:
|
15
|
+
Exclude:
|
16
|
+
- 'bin/setup'
|
17
|
+
- 'bin/update'
|
18
|
+
|
19
|
+
Metrics/MethodLength:
|
20
|
+
Max: 68
|
21
|
+
|
22
|
+
Metrics/ClassLength:
|
23
|
+
Max: 258
|
24
|
+
Exclude:
|
25
|
+
- 'app/components/consumer/factories/persist_leasing_request.rb'
|
26
|
+
|
27
|
+
Metrics/ModuleLength:
|
28
|
+
Max: 212
|
29
|
+
|
30
|
+
Metrics/ParameterLists:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/ExponentialNotation:
|
34
|
+
Enabled: false
|
35
|
+
EnforcedStyle: engineering
|
36
|
+
|
37
|
+
Style/HashEachMethods:
|
38
|
+
Enabled: true
|
39
|
+
|
40
|
+
Style/HashTransformKeys:
|
41
|
+
Enabled: true
|
42
|
+
|
43
|
+
Style/HashTransformValues:
|
44
|
+
Enabled: true
|
45
|
+
|
46
|
+
Style/MethodMissingSuper:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/MissingRespondToMissing:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/NumericLiteralPrefix:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Naming/VariableNumber:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Naming/PredicateName:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Style/DoubleNegation:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/EmptyMethod:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Style/StringLiteralsInInterpolation:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
# Nodody really wants this. We are using Ruby! ` return ` as direct call should be used as less as possible
|
71
|
+
Style/GuardClause:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
Style/FormatStringToken:
|
75
|
+
Exclude:
|
76
|
+
- spec/**/*
|
77
|
+
|
78
|
+
Style/CaseEquality:
|
79
|
+
Exclude:
|
80
|
+
- spec/**/*
|
81
|
+
|
82
|
+
Style/SafeNavigation:
|
83
|
+
Enabled: false
|
84
|
+
|
85
|
+
Metrics/AbcSize:
|
86
|
+
Max: 99
|
87
|
+
Exclude:
|
88
|
+
- spec/**/*
|
89
|
+
|
90
|
+
Metrics/CyclomaticComplexity:
|
91
|
+
Max: 13
|
92
|
+
|
93
|
+
Metrics/PerceivedComplexity:
|
94
|
+
Max: 14
|
95
|
+
|
96
|
+
Layout/LineLength:
|
97
|
+
Max: 120
|
98
|
+
IgnoredPatterns: ['(\A|\s)#']
|
99
|
+
|
100
|
+
Layout/MultilineHashBraceLayout:
|
101
|
+
EnforcedStyle: symmetrical
|
102
|
+
|
103
|
+
Layout/HashAlignment:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
Layout/ParameterAlignment:
|
107
|
+
Enabled: false
|
108
|
+
|
109
|
+
Layout/SpaceAroundMethodCallOperator:
|
110
|
+
Enabled: true
|
111
|
+
|
112
|
+
Metrics/BlockLength:
|
113
|
+
Enabled: false
|
114
|
+
|
115
|
+
# Allows to create getter and setter methods with get_ and set_
|
116
|
+
Naming/AccessorMethodName:
|
117
|
+
Enabled: false
|
118
|
+
|
119
|
+
Naming/MemoizedInstanceVariableName:
|
120
|
+
Enabled: false
|
121
|
+
|
122
|
+
Lint/AmbiguousBlockAssociation:
|
123
|
+
Exclude:
|
124
|
+
- "spec/**/*"
|
125
|
+
|
126
|
+
Lint/AmbiguousOperator:
|
127
|
+
Enabled: true
|
128
|
+
|
129
|
+
Lint/RaiseException:
|
130
|
+
Enabled: true
|
131
|
+
|
132
|
+
Lint/StructNewOverride:
|
133
|
+
Enabled: true
|
134
|
+
|
135
|
+
AllCops:
|
136
|
+
DisplayCopNames: true
|
137
|
+
TargetRubyVersion: 2.6.5
|
138
|
+
CacheRootDirectory: tmp/test-results
|
139
|
+
Exclude:
|
140
|
+
- db/**/*
|
141
|
+
- bin/**
|
142
|
+
- utils/**/*
|
143
|
+
- Guardfile
|
144
|
+
- config/**/*
|
145
|
+
- node_modules/**/*
|
146
|
+
- vendor/**/*
|
147
|
+
- Gemfile
|
148
|
+
- Gemfile.lock
|
149
|
+
|
150
|
+
RSpec/RepeatedDescription:
|
151
|
+
Enabled: false
|
152
|
+
|
153
|
+
RSpec/RepeatedExampleGroupBody:
|
154
|
+
Enabled: false
|
155
|
+
|
156
|
+
RSpec/RepeatedExampleGroupDescription:
|
157
|
+
Enabled: false
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'traceroute'
|
2
|
+
|
3
|
+
namespace :vehiculum_audit do
|
4
|
+
task :create_configs do
|
5
|
+
configs = [
|
6
|
+
{ gem: 'RSpec', file: '.rspec' },
|
7
|
+
{ gem: 'Rubocop', file: '.rubocop.yml' },
|
8
|
+
{ gem: 'Reek', file: '.reek.yml' },
|
9
|
+
{ gem: 'Fasterer', file: '.fasterer.yml' }
|
10
|
+
]
|
11
|
+
|
12
|
+
configs.each do |config|
|
13
|
+
print "Creating config for #{config[:gem]}... "
|
14
|
+
|
15
|
+
cp File.join(File.join(File.dirname(__dir__), 'configs'), config[:file]), Dir.pwd, preserve: true, verbose: false
|
16
|
+
|
17
|
+
puts 'Done!'.green
|
18
|
+
end
|
19
|
+
|
20
|
+
mkdir_p File.join(Dir.pwd, 'doc'), verbose: false
|
21
|
+
end
|
22
|
+
|
23
|
+
task :install_bullet do
|
24
|
+
print 'Creating config for Bullet... '
|
25
|
+
|
26
|
+
file = File.join(Dir.pwd, 'config', 'environments', 'development.rb')
|
27
|
+
content = File.read(file)
|
28
|
+
|
29
|
+
unless content =~ /Bullet/
|
30
|
+
config = <<~BULLET
|
31
|
+
config.after_initialize do
|
32
|
+
Bullet.tap do |bullet|
|
33
|
+
bullet.enable = true
|
34
|
+
bullet.alert = false
|
35
|
+
bullet.bullet_logger = true
|
36
|
+
bullet.console = false
|
37
|
+
bullet.growl = false
|
38
|
+
bullet.rails_logger = true
|
39
|
+
bullet.add_footer = false
|
40
|
+
bullet.airbrake = false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
BULLET
|
44
|
+
|
45
|
+
config = config.split("\n").map { |l| l.prepend(' ' * 2) }.join("\n")
|
46
|
+
|
47
|
+
File.write(file, content.gsub(/^end/, "\n#{config}\nend"))
|
48
|
+
end
|
49
|
+
|
50
|
+
puts 'Done!'.green
|
51
|
+
end
|
52
|
+
|
53
|
+
task :install_simplecov do
|
54
|
+
print 'Creating config for Simplecov... '
|
55
|
+
|
56
|
+
file = File.join(Dir.pwd, 'spec', 'spec_helper.rb')
|
57
|
+
content = File.read(file)
|
58
|
+
|
59
|
+
unless content =~ /simplecov/
|
60
|
+
config = <<~SIMPLECOV
|
61
|
+
require 'simplecov'
|
62
|
+
|
63
|
+
SimpleCov.start 'rails' do
|
64
|
+
coverage_dir File.join('doc', 'coverage')
|
65
|
+
|
66
|
+
groups = %w[channels commands controllers decorators features forms
|
67
|
+
helpers jobs libs mailers models policies queries
|
68
|
+
serializers services tasks uploaders values]
|
69
|
+
|
70
|
+
groups.each { |name| add_group name.capitalize, "/app/\#{name}" }
|
71
|
+
end
|
72
|
+
SIMPLECOV
|
73
|
+
|
74
|
+
File.write(file, config + "\n" + content)
|
75
|
+
end
|
76
|
+
|
77
|
+
puts 'Done!'.green
|
78
|
+
end
|
79
|
+
|
80
|
+
task :info do
|
81
|
+
puts
|
82
|
+
|
83
|
+
box 'Important!', color: :red do
|
84
|
+
<<~INFO
|
85
|
+
You need to install the following utilites:
|
86
|
+
|
87
|
+
On MacOS:
|
88
|
+
|
89
|
+
$ brew install graphviz
|
90
|
+
|
91
|
+
On Linux:
|
92
|
+
|
93
|
+
$ apt-get install graphviz
|
94
|
+
INFO
|
95
|
+
end
|
96
|
+
|
97
|
+
box 'How to use'
|
98
|
+
|
99
|
+
puts <<~INFO
|
100
|
+
You can run all linters using this command:
|
101
|
+
|
102
|
+
$ rails vehiculum_audit:all
|
103
|
+
|
104
|
+
Check output into the console and go to the <project_root>/doc directory.
|
105
|
+
There you will find diagrams and some reports in html format.
|
106
|
+
|
107
|
+
If you want to see test coverage report you need to run tests first:
|
108
|
+
|
109
|
+
$ rspec
|
110
|
+
|
111
|
+
For more information see:
|
112
|
+
|
113
|
+
$ rails -T vehiculum_audit
|
114
|
+
INFO
|
115
|
+
|
116
|
+
puts
|
117
|
+
end
|
118
|
+
|
119
|
+
desc 'Install VehiculumAudit'
|
120
|
+
task :install do
|
121
|
+
box '~ * ~ VehiculumAudit ~ * ~'.upcase
|
122
|
+
|
123
|
+
%w[create_configs install_bullet install_simplecov info].each do |task|
|
124
|
+
Rake::Task["vehiculum_audit:#{task}"].invoke
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
desc 'Bundler audit'
|
129
|
+
task :bundler_audit do
|
130
|
+
system 'bundle audit check --update'
|
131
|
+
end
|
132
|
+
|
133
|
+
desc 'Run Reek'
|
134
|
+
task :reek do
|
135
|
+
system 'bundle exec reek -c .reek.yml'
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Run Rubocop'
|
139
|
+
task :rubocop do
|
140
|
+
system 'bundle exec rubocop'
|
141
|
+
end
|
142
|
+
|
143
|
+
desc 'Run Fasterer'
|
144
|
+
task :fasterer do
|
145
|
+
system 'bundle exec fasterer'
|
146
|
+
end
|
147
|
+
|
148
|
+
desc 'Run Brakeman'
|
149
|
+
task :brakeman do
|
150
|
+
system 'bundle exec brakeman -q'
|
151
|
+
end
|
152
|
+
|
153
|
+
desc 'Run Traceroute'
|
154
|
+
task traceroute: :environment do
|
155
|
+
traceroute = Traceroute.new Rails.application
|
156
|
+
traceroute.load_everything!
|
157
|
+
|
158
|
+
defined_action_methods = traceroute.defined_action_methods
|
159
|
+
|
160
|
+
routed_actions = traceroute.routed_actions
|
161
|
+
|
162
|
+
unused_routes = routed_actions - defined_action_methods
|
163
|
+
unreachable_action_methods = defined_action_methods - routed_actions
|
164
|
+
|
165
|
+
puts "Unused routes (#{unused_routes.count}):"
|
166
|
+
unused_routes.each { |route| puts " #{route}" }
|
167
|
+
|
168
|
+
puts "Unreachable action methods (#{unreachable_action_methods.count}):"
|
169
|
+
unreachable_action_methods.each { |action| puts " #{action}" }
|
170
|
+
end
|
171
|
+
|
172
|
+
desc 'Run ALL linters'
|
173
|
+
task :all do
|
174
|
+
%w[
|
175
|
+
bundler_audit
|
176
|
+
reek
|
177
|
+
rubocop
|
178
|
+
fasterer
|
179
|
+
brakeman
|
180
|
+
traceroute
|
181
|
+
].each do |task|
|
182
|
+
box task
|
183
|
+
|
184
|
+
Rake::Task["vehiculum_audit:#{task}"].invoke
|
185
|
+
|
186
|
+
puts
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def box(text, width: 100, color: :default)
|
191
|
+
char = '#'
|
192
|
+
output = [char * (width + 2)]
|
193
|
+
output << char + ' ' * width + char
|
194
|
+
output << char + text.upcase.center(width) + char
|
195
|
+
output << char + ' ' * width + char
|
196
|
+
output << char * (width + 2)
|
197
|
+
|
198
|
+
puts output.join("\n").colorize(color)
|
199
|
+
|
200
|
+
if block_given?
|
201
|
+
return unless yield.is_a? String
|
202
|
+
|
203
|
+
lines = yield.lines
|
204
|
+
lines.unshift(' ')
|
205
|
+
lines << ' '
|
206
|
+
lines.map! { |line| '# '.colorize(color) + line.delete("\n").ljust(width - 2) + ' #'.colorize(color) }
|
207
|
+
lines << char.colorize(color) * (width + 2)
|
208
|
+
|
209
|
+
puts lines.join("\n")
|
210
|
+
end
|
211
|
+
|
212
|
+
puts
|
213
|
+
end
|
214
|
+
end
|