gem_bench 1.0.5 → 2.0.1
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +111 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +62 -0
- data/README.md +190 -42
- data/SECURITY.md +14 -0
- data/lib/gem_bench/gemfile_line_tokenizer.rb +59 -55
- data/lib/gem_bench/jersey.rb +150 -0
- data/lib/gem_bench/player.rb +43 -36
- data/lib/gem_bench/scout.rb +19 -20
- data/lib/gem_bench/strict_version_gem.rb +16 -21
- data/lib/gem_bench/strict_version_requirement.rb +26 -30
- data/lib/gem_bench/team.rb +120 -81
- data/lib/gem_bench/version.rb +3 -1
- data/lib/gem_bench.rb +21 -8
- data.tar.gz.sig +0 -0
- metadata +226 -32
- metadata.gz.sig +1 -0
- data/.byebug_history +0 -44
- data/.gitignore +0 -16
- data/.rspec +0 -2
- data/.travis.yml +0 -9
- data/CHANGELOG +0 -64
- data/Gemfile +0 -12
- data/Rakefile +0 -6
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/gem_bench.gemspec +0 -36
data/lib/gem_bench/team.rb
CHANGED
@@ -2,14 +2,37 @@ require "forwardable"
|
|
2
2
|
|
3
3
|
module GemBench
|
4
4
|
class Team
|
5
|
-
EXCLUDE = [
|
6
|
-
|
7
|
-
|
5
|
+
EXCLUDE = %w[
|
6
|
+
bundler
|
7
|
+
gem_bench
|
8
|
+
i18n-airbrake
|
9
|
+
devise-async
|
10
|
+
km
|
11
|
+
vestal_versions
|
12
|
+
omniauth-facebook
|
13
|
+
flag_shih_tzu
|
14
|
+
pry-remote
|
15
|
+
koala
|
16
|
+
simple_form
|
17
|
+
thumbs_up
|
18
|
+
memoist
|
19
|
+
cancan
|
20
|
+
friendly_id
|
21
|
+
faker
|
22
|
+
]
|
8
23
|
# A comment preceding the require: false anywhere on the line should not be considered an active require: false
|
9
24
|
extend Forwardable
|
10
25
|
def_delegators :@scout, :gem_paths, :gemfile_path, :check_gemfile?, :loaded_gems
|
11
26
|
attr_reader :scout, :look_for_regex
|
12
|
-
attr_accessor :all,
|
27
|
+
attr_accessor :all,
|
28
|
+
:excluded,
|
29
|
+
:starters,
|
30
|
+
:benchers,
|
31
|
+
:verbose,
|
32
|
+
:gemfile_lines,
|
33
|
+
:trash_lines,
|
34
|
+
:current_gemfile_suggestions,
|
35
|
+
:bad_ideas
|
13
36
|
|
14
37
|
def initialize(options = {})
|
15
38
|
@look_for_regex = options[:look_for_regex]
|
@@ -20,94 +43,104 @@ module GemBench
|
|
20
43
|
@scout = GemBench::Scout.new(check_gemfile: options[:check_gemfile] || benching?)
|
21
44
|
@exclude_file_pattern_regex_proc = options[:exclude_file_pattern_regex_proc].respond_to?(:call) ? options[:exclude_file_pattern_regex_proc] : GemBench::EXCLUDE_FILE_PATTERN_REGEX_PROC
|
22
45
|
# Among the loaded gems there may be some that did not need to be.
|
23
|
-
@excluded, @all = @scout.loaded_gems.partition {|x| EXCLUDE.include?(x[0]) }
|
24
|
-
exclusions = " + #{
|
46
|
+
@excluded, @all = @scout.loaded_gems.partition { |x| EXCLUDE.include?(x[0]) }
|
47
|
+
exclusions = " + #{excluded.length} loaded gems which GemBench is configured to ignore.\n" if @excluded.length > 0
|
25
48
|
@starters = []
|
26
49
|
@benchers = []
|
27
50
|
@current_gemfile_suggestions = []
|
28
51
|
@verbose = options[:verbose]
|
29
|
-
|
52
|
+
check_all
|
30
53
|
@bad_ideas = if benching?
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
54
|
+
if options[:bad_ideas]
|
55
|
+
true
|
56
|
+
else
|
57
|
+
check_gemfile? ? false : !(options[:bad_ideas] == false)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
62
|
+
puts "[GemBench] Will search for gems in #{gem_paths.inspect}\n#{if benching?
|
63
|
+
@scout.check_gemfile? ? "[GemBench] Will check Gemfile at #{gemfile_path}.\n" : "[GemBench] No Gemfile found.\n"
|
64
|
+
else
|
65
|
+
""
|
66
|
+
end}#{bad_ideas ? "[GemBench] Will show bad ideas. Be Careful.\n" : ""}[GemBench] Detected #{all.length} loaded gems#{exclusions}"
|
67
|
+
compare_gemfile if benching? && @scout.check_gemfile?
|
68
|
+
self.print if verbose
|
38
69
|
end
|
39
70
|
|
40
71
|
def list_starters(format: :name)
|
41
|
-
starters.map {|starter| starter.to_s(format)}
|
72
|
+
starters.map { |starter| starter.to_s(format) }
|
42
73
|
end
|
43
74
|
|
44
75
|
def print
|
45
|
-
string =
|
46
|
-
if
|
76
|
+
string = ""
|
77
|
+
if all.empty?
|
47
78
|
string << nothing
|
48
|
-
elsif
|
79
|
+
elsif starters.empty?
|
49
80
|
string << if benching?
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
string << "\t\t#{stat[0]}:#{stat[1]}\n"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
string << "[GemBench] If you want to check for false positives, the files to check for Railties and Engines are listed above.\n" if benching?
|
69
|
-
string << if benching?
|
70
|
-
"[GemBench] #{self.starters.length} out of #{self.all.length} evaluated gems actually need to be loaded at boot time. They are:\n"
|
71
|
-
else
|
72
|
-
"[GemBench] #{self.starters.length} out of #{self.all.length} evaluated gems contain #{look_for_regex}. They are:\n"
|
73
|
-
end
|
74
|
-
self.starters.each_with_index do |starter, index|
|
75
|
-
string << "#{starter.info(index + 1)}\n"
|
76
|
-
end
|
77
|
-
if extra_verbose? && !benching? && self.benchers.length > 0
|
78
|
-
string << "[GemBench] #{self.benchers.length} out of #{self.all.length} evaluated gems did not contain #{look_for_regex}. They are:\n"
|
79
|
-
self.benchers.each_with_index do |bencher, index|
|
80
|
-
string << "#{bencher.info(index + 1)}\n"
|
81
|
-
end
|
81
|
+
"[GemBench] Found no gems that need to load at boot time.\n"
|
82
|
+
else
|
83
|
+
"[GemBench] Found no gems containing #{look_for_regex} in Ruby code.\n"
|
84
|
+
end
|
85
|
+
elsif starters.length > 0
|
86
|
+
string << "\n#{GemBench::USAGE}" unless check_gemfile?
|
87
|
+
string << if benching?
|
88
|
+
"[GemBench] We found a Rails::Railtie or Rails::Engine in the following files. However, it is possible that there are false positives, so you may want to verify that this is the case.\n\n"
|
89
|
+
else
|
90
|
+
"[GemBench] We found #{look_for_regex} in the following files.\n\n"
|
91
|
+
end
|
92
|
+
starters.each do |starter|
|
93
|
+
string << "\t#{starter}:\n"
|
94
|
+
starter.stats.each do |stat|
|
95
|
+
string << "\t\t#{stat[0]}:#{stat[1]}\n"
|
82
96
|
end
|
97
|
+
end
|
98
|
+
if benching?
|
99
|
+
string << "[GemBench] If you want to check for false positives, the files to check for Railties and Engines are listed above.\n"
|
100
|
+
end
|
101
|
+
string << if benching?
|
102
|
+
"[GemBench] #{starters.length} out of #{all.length} evaluated gems actually need to be loaded at boot time. They are:\n"
|
83
103
|
else
|
84
|
-
|
85
|
-
|
104
|
+
"[GemBench] #{starters.length} out of #{all.length} evaluated gems contain #{look_for_regex}. They are:\n"
|
105
|
+
end
|
106
|
+
starters.each_with_index do |starter, index|
|
107
|
+
string << "#{starter.info(index + 1)}\n"
|
86
108
|
end
|
109
|
+
if extra_verbose? && !benching? && benchers.length > 0
|
110
|
+
string << "[GemBench] #{benchers.length} out of #{all.length} evaluated gems did not contain #{look_for_regex}. They are:\n"
|
111
|
+
benchers.each_with_index do |bencher, index|
|
112
|
+
string << "#{bencher.info(index + 1)}\n"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
else
|
116
|
+
string << "[GemBench] Congrats! All gems appear clean.\n"
|
117
|
+
string << "\n#{GemBench::USAGE}" unless check_gemfile?
|
87
118
|
end
|
88
119
|
if check_gemfile? && benching?
|
89
|
-
if
|
90
|
-
string << "[GemBench] Evaluated #{
|
91
|
-
|
120
|
+
if current_gemfile_suggestions.length > 0
|
121
|
+
string << "[GemBench] Evaluated #{all.length} gems and Gemfile at #{gemfile_path}.\n[GemBench] Here are #{current_gemfile_suggestions.length} suggestions for improvement:\n"
|
122
|
+
current_gemfile_suggestions.each_with_index do |player, index|
|
92
123
|
string << "#{player.suggest(index + 1)}\n"
|
93
124
|
end
|
94
125
|
else
|
95
|
-
string <<
|
126
|
+
string << strike_out
|
96
127
|
end
|
97
128
|
end
|
98
129
|
|
99
|
-
if benching? &&
|
130
|
+
if benching? && bad_ideas
|
100
131
|
# Only bad ideas if you are evaluating an actual Gemfile. If just evaluating loaded gems, then info is fine.
|
101
|
-
string <<
|
132
|
+
string << prepare_bad_ideas
|
102
133
|
end
|
103
134
|
|
104
135
|
puts string
|
105
136
|
end
|
106
137
|
|
107
138
|
def strike_out
|
108
|
-
check_gemfile?
|
109
|
-
"[GemBench] Evaluated #{
|
110
|
-
|
139
|
+
if check_gemfile?
|
140
|
+
"[GemBench] Evaluated #{all.length} gems against your Gemfile but found no primary dependencies which can safely skip require on boot (require: false).\n"
|
141
|
+
else
|
142
|
+
"[GemBench] Evaluated #{all.length} gems but found none which can safely skip require on boot (require: false).\n"
|
143
|
+
end
|
111
144
|
end
|
112
145
|
|
113
146
|
def nothing
|
@@ -115,40 +148,46 @@ module GemBench
|
|
115
148
|
end
|
116
149
|
|
117
150
|
def prepare_bad_ideas
|
118
|
-
string =
|
119
|
-
if
|
120
|
-
gemfile_instruction = check_gemfile? ?
|
121
|
-
string << "[GemBench] Evaluated #{
|
122
|
-
|
151
|
+
string = ""
|
152
|
+
if benchers.length > 0
|
153
|
+
gemfile_instruction = check_gemfile? ? "" : "To safely evaluate a Gemfile:\n\t1. Make sure you are in the root of a project with a Gemfile\n\t2. Make sure the gem is actually a dependency in the Gemfile\n"
|
154
|
+
string << "[GemBench] Evaluated #{all.length} loaded gems and found #{benchers.length} which may be able to skip boot loading (require: false).\n*** => WARNING <= ***: Be careful adding non-primary dependencies to your Gemfile as it is generally a bad idea.\n#{gemfile_instruction}"
|
155
|
+
benchers.each_with_index do |player, index|
|
123
156
|
string << "#{player.careful(index + 1)}\n"
|
124
157
|
end
|
125
158
|
else
|
126
|
-
string <<
|
159
|
+
string << strike_out
|
127
160
|
end
|
128
161
|
string
|
129
162
|
end
|
130
163
|
|
131
164
|
def compare_gemfile
|
132
|
-
|
165
|
+
benchers.each do |player|
|
133
166
|
scout.gemfile_lines.each do |line|
|
134
167
|
found = (line =~ player.gemfile_regex)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
168
|
+
next unless found
|
169
|
+
|
170
|
+
# remove the found line from the array, because no sane person has more than one gem dependency per line... right?
|
171
|
+
line = scout.gemfile_lines.delete_at(scout.gemfile_lines.index(line))
|
172
|
+
# does the line already have require: false?
|
173
|
+
unless line =~ GemBench::REQUIRE_FALSE_REGEX
|
174
|
+
current_gemfile_suggestions << benchers.delete_at(benchers.index(player))
|
141
175
|
end
|
176
|
+
break # outside of the inner loop
|
142
177
|
end
|
143
178
|
end
|
144
179
|
end
|
145
180
|
|
146
181
|
def check_all
|
147
|
-
|
182
|
+
all.each do |player_data|
|
148
183
|
exclude_file_pattern = @exclude_file_pattern_regex_proc.call(player_data[0])
|
149
|
-
player = GemBench::Player.new({
|
150
|
-
|
151
|
-
|
184
|
+
player = GemBench::Player.new({
|
185
|
+
name: player_data[0],
|
186
|
+
version: player_data[1],
|
187
|
+
exclude_file_pattern: exclude_file_pattern,
|
188
|
+
})
|
189
|
+
check(player)
|
190
|
+
add_to_roster(player)
|
152
191
|
end
|
153
192
|
end
|
154
193
|
|
@@ -166,16 +205,16 @@ module GemBench
|
|
166
205
|
|
167
206
|
def add_to_roster(player)
|
168
207
|
if player.starter?
|
169
|
-
|
208
|
+
starters << player
|
170
209
|
else
|
171
|
-
|
210
|
+
benchers << player
|
172
211
|
end
|
173
212
|
end
|
174
213
|
|
175
214
|
private
|
176
215
|
|
177
216
|
def extra_verbose?
|
178
|
-
|
217
|
+
verbose == "extra"
|
179
218
|
end
|
180
219
|
|
181
220
|
def benching?
|
data/lib/gem_bench/version.rb
CHANGED
data/lib/gem_bench.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
# external gems
|
2
|
+
require "version_gem"
|
2
3
|
require "bundler" # This gem utilizes bundler as a tool.
|
4
|
+
|
5
|
+
require "gem_bench/version"
|
3
6
|
require "gem_bench/scout"
|
4
7
|
require "gem_bench/player"
|
5
8
|
require "gem_bench/team"
|
@@ -10,19 +13,20 @@ require "gem_bench/strict_version_requirement"
|
|
10
13
|
module GemBench
|
11
14
|
USAGE = "[GemBench] Usage: Require another gem in this session to evaluate it.\n\tExample:\n\t\trequire 'rails'\n\t\tGemBench.check({verbose: true})\n"
|
12
15
|
RAILTIE_REGEX = /Rails::Engine|Rails::Railtie/
|
13
|
-
TRASH_REGEX = /^(\s*)(
|
14
|
-
REQUIRE_FALSE_REGEX = /^[^#]+require((
|
16
|
+
TRASH_REGEX = /^(\s*)(\#+.*)?$/
|
17
|
+
REQUIRE_FALSE_REGEX = /^[^#]+require((:\s*)|(\s*=>\s*))false.*/
|
15
18
|
DEPENDENCY_REGEX_PROC = ->(name) { /^\s*[^#]*\s*gem\s+['"]{1}#{name}['"]{1}/ }
|
16
19
|
PATH_GLOB = ->(name) { "#{name}*/lib/**/*.rb" }
|
17
|
-
EXCLUDE_FILE_PATTERN_REGEX_PROC = ->(name) {
|
20
|
+
EXCLUDE_FILE_PATTERN_REGEX_PROC = ->(name) { %r{#{name}/test|features|spec|bin|exe} }
|
18
21
|
DO_NOT_SCAN = []
|
19
22
|
PLAYER_STATES = {
|
20
|
-
starter:
|
21
|
-
bench:
|
23
|
+
starter: :starter,
|
24
|
+
bench: :bench,
|
22
25
|
}
|
23
26
|
|
24
27
|
class << self
|
25
28
|
attr_accessor :roster
|
29
|
+
|
26
30
|
def check(verbose: false)
|
27
31
|
@roster = GemBench::Team.new({verbose: verbose})
|
28
32
|
end
|
@@ -37,8 +41,17 @@ module GemBench
|
|
37
41
|
@roster.list_missing_version_constraints
|
38
42
|
end
|
39
43
|
|
40
|
-
def find(look_for_regex: GemBench::RAILTIE_REGEX,
|
41
|
-
|
44
|
+
def find(look_for_regex: GemBench::RAILTIE_REGEX,
|
45
|
+
exclude_file_pattern_regex_proc: GemBench::EXCLUDE_FILE_PATTERN_REGEX_PROC, verbose: false)
|
46
|
+
@roster = GemBench::Team.new({
|
47
|
+
look_for_regex: look_for_regex,
|
48
|
+
exclude_file_pattern_regex_proc: exclude_file_pattern_regex_proc,
|
49
|
+
verbose: verbose,
|
50
|
+
})
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
54
|
+
|
55
|
+
GemBench::Version.class_eval do
|
56
|
+
extend VersionGem::Basic
|
57
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|