gem_bench 2.0.3 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +23 -6
- data/README.md +42 -8
- data/lib/gem_bench/gemfile_line_tokenizer.rb +132 -40
- data/lib/gem_bench/jersey.rb +100 -66
- data/lib/gem_bench/player.rb +2 -0
- data/lib/gem_bench/scout.rb +6 -4
- data/lib/gem_bench/strict_version_gem.rb +3 -1
- data/lib/gem_bench/strict_version_requirement.rb +2 -1
- data/lib/gem_bench/team.rb +16 -6
- data/lib/gem_bench/version.rb +2 -1
- data/lib/gem_bench.rb +34 -21
- data.tar.gz.sig +0 -0
- metadata +50 -44
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47591b1b5f1880cbb2c40be1199aa7fa65a25d2c32ca52131ba54e0e89d8b6b7
|
4
|
+
data.tar.gz: 93aad6d4e020398b93ffdaa2e8fddfce5b5e5cc4fa08854f22850dcccee9f0ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47827b59b13ee527cecfc8db349437c0fc416aa53fa83b4138a6c1884652d857ce9be708ec534e099b8a41f47914b831d8f73e09e430134f4deb050714a1925a
|
7
|
+
data.tar.gz: 9ae3067637e3293209bde40127e55ad42882b075ca71fc65e7b025ec5dd4e160f5669767e6990a8a0db915ff6031f1555e432cc6a110e32b09346a710fd304bf
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -11,6 +11,23 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
|
|
11
11
|
### Fixed
|
12
12
|
### Removed
|
13
13
|
|
14
|
+
## [2.0.4] SEP.20.2024
|
15
|
+
- COVERAGE: 98.19% -- 488/497 lines in 9 files
|
16
|
+
- BRANCH COVERAGE: 88.95% -- 161/181 branches in 9 files
|
17
|
+
- 58.06% documented
|
18
|
+
### Added
|
19
|
+
- More Documentation
|
20
|
+
- Almost 100% test coverage
|
21
|
+
- Thread Safety (removed `GemBench.roster`, which was effectively never used internally)
|
22
|
+
- Performance improvements
|
23
|
+
### Fixed
|
24
|
+
- Can now handle more variations of Ruby syntax in the Gemfile analyzer
|
25
|
+
- `require_relative` > `require` for internal files (except for `spec` => `lib`)
|
26
|
+
- Updated logic for version specified via git with branch, tag, ref (to match fixes to Bundler's behavior)
|
27
|
+
- Ambiguous naming of `GemBench::Jersey#primary_namespace` is split to:
|
28
|
+
- `#doffed_primary_namespace`
|
29
|
+
- `#donned_primary_namespace`
|
30
|
+
|
14
31
|
## [2.0.3] SEP.18.2024
|
15
32
|
### Added
|
16
33
|
- More documentation
|
@@ -19,9 +36,9 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
|
|
19
36
|
- Copyright years
|
20
37
|
|
21
38
|
## [2.0.2] SEP.17.2024
|
22
|
-
COVERAGE: 82.15% -- 382/465 lines in 9 files
|
23
|
-
BRANCH COVERAGE: 58.79% -- 97/165 branches in 9 files
|
24
|
-
51.72% documented
|
39
|
+
- COVERAGE: 82.15% -- 382/465 lines in 9 files
|
40
|
+
- BRANCH COVERAGE: 58.79% -- 97/165 branches in 9 files
|
41
|
+
- 51.72% documented
|
25
42
|
### Added
|
26
43
|
- CI for Ancient Rubies
|
27
44
|
- Ruby 2.3
|
@@ -34,9 +51,9 @@ BRANCH COVERAGE: 58.79% -- 97/165 branches in 9 files
|
|
34
51
|
- Gemspec description & Summary
|
35
52
|
|
36
53
|
## [2.0.1] SEP.17.2024
|
37
|
-
COVERAGE: 82.15% -- 382/465 lines in 9 files
|
38
|
-
BRANCH COVERAGE: 58.08% -- 97/167 branches in 9 files
|
39
|
-
51.72% documented
|
54
|
+
- COVERAGE: 82.15% -- 382/465 lines in 9 files
|
55
|
+
- BRANCH COVERAGE: 58.08% -- 97/167 branches in 9 files
|
56
|
+
- 51.72% documented
|
40
57
|
### Added
|
41
58
|
- Ability to re-namespace and load copy of a gem alongside vanilla version for benchmarking via `GemBench::Jersey`
|
42
59
|
- See: https://github.com/panorama-ed/memo_wise/pull/339
|
data/README.md
CHANGED
@@ -98,14 +98,13 @@ Regex search through all of a project's source code, including installed Bundler
|
|
98
98
|
|
99
99
|
🛟 Trim down app load times, such as on Heroku, by finding and keeping your worst players on the bench.
|
100
100
|
|
101
|
-
|
|
102
|
-
|
103
|
-
| gem name
|
104
|
-
| code triage
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
| `...` 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Follow Me on LinkedIn][🖇linkedin-img]][🖇linkedin] [![Find Me on WellFound:][✌️wellfound-img]][✌️wellfound] [![Find Me on CrunchBase][💲crunchbase-img]][💲crunchbase] [![My LinkTree][🌳linktree-img]][🌳linktree] [![Follow Me on Ruby.Social][🐘ruby-mast-img]][🐘ruby-mast] [![Tweet @ Peter][🐦tweet-img]][🐦tweet] [💻][coderme] [🌏][aboutme] |
|
101
|
+
| Primary Namespace | `GemBench` |
|
102
|
+
|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
103
|
+
| gem name | [gem_bench](https://rubygems.org/gems/gem_bench) |
|
104
|
+
| code triage | [![Open Source Helpers](https://www.codetriage.com/pboling/gem_bench/badges/users.svg)](https://www.codetriage.com/pboling/gem_bench) |
|
105
|
+
| documentation | [on Github.com][homepage], [on Rdoc.info][documentation] |
|
106
|
+
| expert support | [![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github) |
|
107
|
+
| `...` 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Follow Me on LinkedIn][🖇linkedin-img]][🖇linkedin] [![Find Me on WellFound:][✌️wellfound-img]][✌️wellfound] [![Find Me on CrunchBase][💲crunchbase-img]][💲crunchbase] [![My LinkTree][🌳linktree-img]][🌳linktree] [![Follow Me on Ruby.Social][🐘ruby-mast-img]][🐘ruby-mast] [![Tweet @ Peter][🐦tweet-img]][🐦tweet] [💻][coderme] [🌏][aboutme] |
|
109
108
|
|
110
109
|
<!-- 7️⃣ spread 💖 -->
|
111
110
|
[🐦tweet-img]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow%20%40galtzo
|
@@ -163,8 +162,43 @@ NOTE: It is not required by default, so you do need to require the Jersey if you
|
|
163
162
|
require "gem_bench/jersey"
|
164
163
|
```
|
165
164
|
|
165
|
+
#### Usage
|
166
|
+
|
167
|
+
If the original gem defines multiple top-level namespaces,
|
168
|
+
they can all be renamed by providing more key value pairs in `trades`.
|
169
|
+
If the original gem monkey patches other libraries,
|
170
|
+
that behavior can't be isolated, so YMMV.
|
171
|
+
|
172
|
+
NOTE: Non-top-level namespaces do not need to be renamed,
|
173
|
+
as they are isolated within their parent namespace.
|
174
|
+
|
175
|
+
#### Example
|
176
|
+
|
166
177
|
For a real example, see: https://github.com/panorama-ed/memo_wise/pull/339
|
167
178
|
|
179
|
+
#### Naming: Why `doff_and_don`?
|
180
|
+
|
181
|
+
> Wouldn't "copy_gem" make sense?
|
182
|
+
|
183
|
+
Actually copy is an overloaded term, which creates confusion in this use case.
|
184
|
+
This method Generates a temp directory, and creates a copy of a gem within it.
|
185
|
+
Re-namespaces the copy according to the `trades` configuration.
|
186
|
+
Then requires each file of the "copied gem", resulting
|
187
|
+
in a loaded gem that will not have namespace
|
188
|
+
collisions when loaded alongside the original-namespaced gem.
|
189
|
+
Note that "copied gem" in the previous sentence is ambiguous without the supporting context.
|
190
|
+
The "copied gem" can mean either the original, or the "copy", which is why this gem refers to
|
191
|
+
a "doffed gem" (the original) and a "donned gem" (the copy).
|
192
|
+
|
193
|
+
Also because `Jersey`. Duh...
|
194
|
+
|
195
|
+
#### Advanced Usage
|
196
|
+
|
197
|
+
If a block is provided the contents of each file will be yielded to the block,
|
198
|
+
after all namespace substitutions from `trades` are complete, but before the contents
|
199
|
+
are written to the donned (re-namespaced) gem. The return value of the block will be
|
200
|
+
written to the file in this scenario.
|
201
|
+
|
168
202
|
### New for 2.0.0 - Dropped Support for Ruby 2.0, 2.1, 2.2
|
169
203
|
|
170
204
|
- Required Ruby is now 2.3+
|
@@ -1,14 +1,51 @@
|
|
1
1
|
module GemBench
|
2
|
+
# Line by line parser of a Gemfile
|
3
|
+
# Uses regular expressions, which, I know, GROSS, but also meh
|
4
|
+
# You aren't using this as a runtime gem in your app are you?
|
5
|
+
# Let me know how you use it!
|
2
6
|
class GemfileLineTokenizer
|
3
7
|
GEM_REGEX = /\A\s*gem\s+([^#]*).*\Z/.freeze # run against gem lines like: "gem 'aftership', # Ruby SDK of AfterShip API."
|
4
|
-
|
5
|
-
|
8
|
+
# HEREDOC support? (?<op_heredoc><<[~-]?[A-Z0-9_]+\.?[a-z0-9_]+)
|
9
|
+
OP_QUO_REG_PROC = lambda { |idx = nil| /((?<op_quo#{idx}>['"]{1})|(?<op_pct_q#{idx}>%[Qq]?[\(\[\{]{1})|(?<op_heredoc><<[~-]?[A-Z0-9_]+\.?[a-z0-9_]+))/x }
|
10
|
+
# No close for the heredoc, as it will be on a different line...
|
11
|
+
CL_QUO_REG_PROC = lambda { |idx = nil| /((?<cl_quo#{idx}>['"])|(?<cl_pct_q#{idx}>[\)\]\}]{1}))/x }
|
12
|
+
GEM_NAME_REGEX = /\A\s*gem\s+#{OP_QUO_REG_PROC.call.source}(?<name>[^'")]*)#{CL_QUO_REG_PROC.call.source}?.*\Z/.freeze # run against gem lines like: "gem 'aftership', # Ruby SDK of AfterShip API."
|
13
|
+
VERSION_CONSTRAINT = /#{OP_QUO_REG_PROC.call.source}(?<version>[^'")]*)#{CL_QUO_REG_PROC.call.source}/.freeze
|
6
14
|
GEMFILE_HASH_CONFIG_KEY_REGEX_PROC = lambda { |key|
|
7
|
-
|
15
|
+
/
|
16
|
+
\A\s*[^#]*
|
17
|
+
(
|
18
|
+
# when key is "branch" will find: `branch: "main"`
|
19
|
+
(?<key1>#{key}:\s*)
|
20
|
+
#{OP_QUO_REG_PROC.call("k1").source}(?<value1>[^'")]*)?#{CL_QUO_REG_PROC.call("k1").source}
|
21
|
+
)
|
22
|
+
|
|
23
|
+
(
|
24
|
+
# when key is "branch" will find: `"branch" => "main"`
|
25
|
+
(?<key2>#{OP_QUO_REG_PROC.call("k2a").source}#{key}#{CL_QUO_REG_PROC.call("k2a").source}\s*=>\s*)
|
26
|
+
#{OP_QUO_REG_PROC.call("k2b").source}(?<value2>[^'")]*)?#{CL_QUO_REG_PROC.call("k2b").source}
|
27
|
+
)
|
28
|
+
|
|
29
|
+
(
|
30
|
+
# when key is "branch" will find: `:branch => "main"`
|
31
|
+
(?<key3>:#{key}\s*=>\s*)
|
32
|
+
#{OP_QUO_REG_PROC.call("k3").source}(?<value3>[^'")]*)?#{CL_QUO_REG_PROC.call("k3").source}
|
33
|
+
)
|
34
|
+
|
|
35
|
+
(
|
36
|
+
# when key is "branch" will find: `"branch": "main"`
|
37
|
+
(?<key4>#{OP_QUO_REG_PROC.call("k4a").source}#{key}#{CL_QUO_REG_PROC.call("k4a").source}:\s*)
|
38
|
+
#{OP_QUO_REG_PROC.call("k4b").source}(?<value4>[^'")]*)?#{CL_QUO_REG_PROC.call("k4b").source}
|
39
|
+
)
|
40
|
+
/x
|
8
41
|
}
|
9
42
|
VERSION_PATH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("path").freeze
|
10
43
|
VERSION_GIT = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("git").freeze
|
11
44
|
VERSION_GITHUB = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("github").freeze
|
45
|
+
VERSION_GITLAB = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("gitlab").freeze
|
46
|
+
VERSION_BITBUCKET = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("bitbucket").freeze
|
47
|
+
VERSION_CODEBERG = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("codeberg").freeze
|
48
|
+
VERSION_SRCHUT = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("srchut").freeze
|
12
49
|
VERSION_GIT_REF = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("ref").freeze
|
13
50
|
VERSION_GIT_TAG = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("tag").freeze
|
14
51
|
VERSION_GIT_BRANCH = GEMFILE_HASH_CONFIG_KEY_REGEX_PROC.call("branch").freeze
|
@@ -17,13 +54,19 @@ module GemBench
|
|
17
54
|
git_ref
|
18
55
|
git_tag
|
19
56
|
]
|
20
|
-
|
57
|
+
STR_SYNTAX_TYPES = {
|
58
|
+
quoted: true,
|
59
|
+
pct_q: true,
|
60
|
+
# We could try to support HEREDOC via parsing the lines following in all_lines, but... ugh.
|
61
|
+
heredoc: false,
|
62
|
+
unknown: false,
|
63
|
+
}.freeze
|
21
64
|
attr_reader :line
|
22
65
|
attr_reader :relevant_lines, :is_gem, :all_lines, :index, :tokens, :version_type, :name, :parse_success, :valid
|
23
66
|
# version will be a string if it is a normal constraint like '~> 1.2.3'
|
24
67
|
# version will be a hash if it is an alternative constraint like:
|
25
68
|
# git: "blah/blah", ref: "shasha"
|
26
|
-
attr_reader :version
|
69
|
+
attr_reader :version, :str_syntax_type
|
27
70
|
|
28
71
|
def initialize(all_lines, line, index)
|
29
72
|
@line = line.strip
|
@@ -31,9 +74,9 @@ module GemBench
|
|
31
74
|
if is_gem
|
32
75
|
@all_lines = all_lines
|
33
76
|
@index = index
|
34
|
-
@tokens = self.line.split(",")
|
77
|
+
@tokens = self.line.split(",").map(&:strip)
|
35
78
|
determine_name
|
36
|
-
if name
|
79
|
+
if name && STR_SYNTAX_TYPES[str_syntax_type]
|
37
80
|
determine_relevant_lines
|
38
81
|
determine_version
|
39
82
|
@parse_success = true
|
@@ -49,35 +92,61 @@ module GemBench
|
|
49
92
|
private
|
50
93
|
|
51
94
|
# not a gem line. noop.
|
95
|
+
#
|
96
|
+
# @return void
|
52
97
|
def noop
|
53
98
|
@parse_success = false
|
54
99
|
@valid = false
|
100
|
+
|
101
|
+
nil
|
55
102
|
end
|
56
103
|
|
104
|
+
# @return void
|
57
105
|
def determine_name
|
58
106
|
# uses @tokens[0] because the gem name must be before the first comma
|
59
107
|
match_data = @tokens[0].match(GEM_NAME_REGEX)
|
108
|
+
@str_syntax_type =
|
109
|
+
if match_data[:op_quo] && match_data[:cl_quo]
|
110
|
+
:quoted
|
111
|
+
elsif match_data[:op_pct_q] && match_data[:cl_pct_q]
|
112
|
+
:pct_q
|
113
|
+
# Not handling heredoc, aside from not exploding, as it isn't a reasonable use case.
|
114
|
+
# elsif match_data[:op_heredoc]
|
115
|
+
# :heredoc
|
116
|
+
else
|
117
|
+
:unknown
|
118
|
+
end
|
60
119
|
@name = match_data[:name]
|
120
|
+
|
121
|
+
nil
|
61
122
|
end
|
62
123
|
|
124
|
+
# @return void
|
63
125
|
def determine_relevant_lines
|
64
126
|
@relevant_lines = [line, *following_non_gem_lines].compact
|
127
|
+
|
128
|
+
nil
|
65
129
|
end
|
66
130
|
|
131
|
+
# @return void
|
67
132
|
def determine_version
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
)
|
133
|
+
@version = {}
|
134
|
+
return if version_path
|
135
|
+
|
136
|
+
(
|
137
|
+
(version_git || version_provider) && (
|
138
|
+
check_for_version_of_type_git_tag ||
|
139
|
+
check_for_version_of_type_git_branch
|
140
|
+
)
|
141
|
+
) ||
|
76
142
|
# Needs to be the last check because it can only check for a quoted string,
|
77
143
|
# and quoted strings are part of the other types, so they have to be checked first with higher specificity
|
78
144
|
check_for_version_of_type_constraint
|
145
|
+
|
146
|
+
nil
|
79
147
|
end
|
80
148
|
|
149
|
+
# @return [true, false]
|
81
150
|
def check_for_version_of_type_constraint
|
82
151
|
# index 1 of the comma-split tokens will usually be the version constraint, if there is one
|
83
152
|
possible_constraint = @tokens[1]
|
@@ -85,7 +154,7 @@ module GemBench
|
|
85
154
|
|
86
155
|
match_data = possible_constraint.strip.match(VERSION_CONSTRAINT)
|
87
156
|
# the version constraint is in a regex capture group
|
88
|
-
if match_data && (@version = match_data[
|
157
|
+
if match_data && (@version = match_data[:version].strip)
|
89
158
|
@version_type = :constraint
|
90
159
|
true
|
91
160
|
else
|
@@ -93,8 +162,8 @@ module GemBench
|
|
93
162
|
end
|
94
163
|
end
|
95
164
|
|
165
|
+
# @return [true, false]
|
96
166
|
def version_path
|
97
|
-
@version = {}
|
98
167
|
line = relevant_lines.detect { |next_line| next_line.match(VERSION_PATH) }
|
99
168
|
return false unless line
|
100
169
|
|
@@ -105,8 +174,8 @@ module GemBench
|
|
105
174
|
)
|
106
175
|
end
|
107
176
|
|
177
|
+
# @return [true, false]
|
108
178
|
def version_git
|
109
|
-
@version = {}
|
110
179
|
line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT) }
|
111
180
|
return false unless line
|
112
181
|
|
@@ -117,21 +186,40 @@ module GemBench
|
|
117
186
|
)
|
118
187
|
end
|
119
188
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
189
|
+
# @return [true, false]
|
190
|
+
def version_provider
|
191
|
+
matcher = nil
|
192
|
+
line = relevant_lines.detect do |next_line|
|
193
|
+
matcher =
|
194
|
+
case next_line
|
195
|
+
when VERSION_GITHUB
|
196
|
+
VERSION_GITHUB
|
197
|
+
when VERSION_GITLAB
|
198
|
+
VERSION_GITLAB
|
199
|
+
when VERSION_BITBUCKET
|
200
|
+
VERSION_BITBUCKET
|
201
|
+
when VERSION_CODEBERG
|
202
|
+
VERSION_CODEBERG
|
203
|
+
when VERSION_SRCHUT
|
204
|
+
VERSION_SRCHUT
|
205
|
+
end
|
206
|
+
end
|
207
|
+
return false unless line && matcher
|
124
208
|
|
125
209
|
enhance_version(
|
126
|
-
line.match(
|
210
|
+
line.match(matcher),
|
127
211
|
:github,
|
128
212
|
:github,
|
129
213
|
)
|
130
214
|
end
|
131
215
|
|
132
|
-
|
216
|
+
# @return [true, false]
|
217
|
+
def check_for_version_of_type_git_branch
|
218
|
+
return false unless _check_for_version_of_type_git_branch
|
219
|
+
|
133
220
|
line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_REF) }
|
134
|
-
|
221
|
+
# At this point we at least have a branch, though perhaps not a ref.
|
222
|
+
return true unless line
|
135
223
|
|
136
224
|
enhance_version(
|
137
225
|
line.match(VERSION_GIT_REF),
|
@@ -140,6 +228,7 @@ module GemBench
|
|
140
228
|
)
|
141
229
|
end
|
142
230
|
|
231
|
+
# @return [true, false]
|
143
232
|
def check_for_version_of_type_git_tag
|
144
233
|
line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_TAG) }
|
145
234
|
return false unless line
|
@@ -151,7 +240,8 @@ module GemBench
|
|
151
240
|
)
|
152
241
|
end
|
153
242
|
|
154
|
-
|
243
|
+
# @return [true, false]
|
244
|
+
def _check_for_version_of_type_git_branch
|
155
245
|
line = relevant_lines.detect { |next_line| next_line.match(VERSION_GIT_BRANCH) }
|
156
246
|
return false unless line
|
157
247
|
|
@@ -162,7 +252,7 @@ module GemBench
|
|
162
252
|
)
|
163
253
|
end
|
164
254
|
|
165
|
-
#
|
255
|
+
# @return [Array[String]] - each line following the current line, which is not a gem line
|
166
256
|
def following_non_gem_lines
|
167
257
|
all_lines[(index + 1)..-1]
|
168
258
|
.reject { |x| x.strip.empty? || x.match(GemBench::TRASH_REGEX) }
|
@@ -174,23 +264,25 @@ module GemBench
|
|
174
264
|
end
|
175
265
|
end
|
176
266
|
|
177
|
-
#
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
break mem if mem.keys.length >= 2
|
183
|
-
end
|
267
|
+
# @return [String] the name of the named capture which has a value (one of: value1, value2, value3, etc.)
|
268
|
+
def determine_named_capture(match_data)
|
269
|
+
match_data.names
|
270
|
+
.select { |name| name.start_with?("value") }
|
271
|
+
.detect { |capture| !match_data[capture]&.empty? }
|
184
272
|
end
|
185
273
|
|
274
|
+
# @return [true]
|
186
275
|
def enhance_version(match_data, version_key, type)
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
276
|
+
named_capture = determine_named_capture(match_data)
|
277
|
+
value = match_data[named_capture]
|
278
|
+
if value
|
279
|
+
@version[version_key] = value
|
280
|
+
@version_type = type
|
281
|
+
else
|
282
|
+
@version[version_key] = ""
|
283
|
+
@version_type = :invalid
|
284
|
+
end
|
191
285
|
|
192
|
-
@version.merge!({version_key => normalized_capture["value"]})
|
193
|
-
@version_type = type
|
194
286
|
true
|
195
287
|
end
|
196
288
|
end
|
data/lib/gem_bench/jersey.rb
CHANGED
@@ -1,29 +1,32 @@
|
|
1
1
|
# Std Libs Dependencies
|
2
2
|
require "tmpdir"
|
3
3
|
|
4
|
-
# Re-write a gem to a temp directory, re-namespace the primary namespace of that gem module, and load it.
|
5
|
-
# If the original gem defines multiple top-level namespaces, they can all be renamed by providing more key value pairs.
|
6
|
-
# If the original gem monkey patches other libraries, that behavior can't be isolated, so YMMV.
|
7
|
-
#
|
8
|
-
# NOTE: Non-top-level namespaces do not need to be renamed, as they are isolated within their parent namespace.
|
9
|
-
#
|
10
|
-
# Usage
|
11
|
-
#
|
12
|
-
# jersey = GemBench::Jersey.new(
|
13
|
-
# gem_name: "alt_memery"
|
14
|
-
# trades: {
|
15
|
-
# "Memery" => "AltMemery"
|
16
|
-
# },
|
17
|
-
# metadata: {
|
18
|
-
# something: "a value here",
|
19
|
-
# something_else: :obviously,
|
20
|
-
# },
|
21
|
-
# )
|
22
|
-
# jersey.doff_and_don
|
23
|
-
# # The re-namespaced constant is now available!
|
24
|
-
# AltMemery # => AltMemery
|
25
|
-
#
|
26
4
|
module GemBench
|
5
|
+
# Re-write a gem to a temp directory, re-namespace the primary namespace of that gem module, and load it.
|
6
|
+
# If the original gem defines multiple top-level namespaces, they can all be renamed by providing more key value pairs.
|
7
|
+
# If the original gem monkey patches other libraries, that behavior can't be isolated, so YMMV.
|
8
|
+
#
|
9
|
+
# NOTE: Non-top-level namespaces do not need to be renamed, as they are isolated within their parent namespace.
|
10
|
+
#
|
11
|
+
# Usage
|
12
|
+
#
|
13
|
+
# jersey = GemBench::Jersey.new(
|
14
|
+
# gem_name: "alt_memery"
|
15
|
+
# trades: {
|
16
|
+
# "Memery" => "AltMemery"
|
17
|
+
# },
|
18
|
+
# metadata: {
|
19
|
+
# something: "a value here",
|
20
|
+
# something_else: :obviously,
|
21
|
+
# },
|
22
|
+
# )
|
23
|
+
# jersey.doff_and_don
|
24
|
+
# # The re-namespaced constant is now available!
|
25
|
+
# AltMemery # => AltMemery
|
26
|
+
#
|
27
|
+
# Benchmarking Example
|
28
|
+
#
|
29
|
+
# See: https://github.com/panorama-ed/memo_wise/blob/main/benchmarks/benchmarks.rb
|
27
30
|
class Jersey
|
28
31
|
attr_reader :gem_name
|
29
32
|
attr_reader :gem_path
|
@@ -41,110 +44,141 @@ module GemBench
|
|
41
44
|
@verbose = verbose
|
42
45
|
end
|
43
46
|
|
47
|
+
# return [true, false] proxy for whether the copied, re-namespaced gem has been successfully loaded
|
44
48
|
def required?
|
45
49
|
gem_path && trades.values.all? { |new_namespace| Object.const_defined?(new_namespace) }
|
46
50
|
end
|
47
51
|
|
48
|
-
# Generates
|
52
|
+
# Generates a temp directory, and creates a copy of a gem within it.
|
53
|
+
# Re-namespaces the copy according to the `trades` configuration.
|
54
|
+
# Then requires each file of the "copied gem", resulting
|
49
55
|
# in a loaded gem that will not have namespace
|
50
|
-
# collisions when alongside the original-namespaced gem.
|
56
|
+
# collisions when loaded alongside the original-namespaced gem.
|
57
|
+
# Note that "copied gem" in the previous sentence is ambiguous without the supporting context.
|
58
|
+
# The "copied gem" can mean either the original, or the "copy", which is why this gem refers to
|
59
|
+
# a "doffed gem" (the original) and a "donned gem" (the copy).
|
51
60
|
# If a block is provided the contents of each file will be yielded to the block,
|
52
|
-
# after all namespace substitutions are complete, but before the contents
|
61
|
+
# after all namespace substitutions from `trades` are complete, but before the contents
|
53
62
|
# are written to the re-namespaced gem. The return value of the block will be
|
54
63
|
# written to the file in this scenario.
|
55
64
|
#
|
56
65
|
# @return void
|
57
66
|
def doff_and_don(&block)
|
58
|
-
return puts "
|
67
|
+
return puts "[#{gem_name}] Skipped (not loaded on #{RUBY_VERSION})" unless gem_path
|
59
68
|
|
60
|
-
puts "Doffing #{gem_path}" if verbose
|
61
|
-
Dir.mktmpdir do |
|
69
|
+
puts "[#{gem_name}] Doffing #{gem_path}" if verbose
|
70
|
+
Dir.mktmpdir do |tmp_dir|
|
62
71
|
files = []
|
63
72
|
Dir[File.join(gem_path, "lib", "**", "*.rb")].map do |file|
|
64
73
|
if verbose
|
65
|
-
puts
|
66
|
-
puts
|
67
|
-
puts "--------------------------------"
|
74
|
+
puts "[#{gem_name}] --------------------------------"
|
75
|
+
puts "[#{gem_name}] Doffing file #{file}"
|
76
|
+
puts "[#{gem_name}] --------------------------------"
|
68
77
|
end
|
78
|
+
basename = File.basename(file)
|
69
79
|
dirname = File.dirname(file)
|
70
|
-
puts "dirname: #{dirname}" if verbose
|
80
|
+
puts "[#{gem_name}][#{basename}] dirname: #{dirname}" if verbose
|
71
81
|
is_at_gem_root = dirname[(-4)..(-1)] == "/lib"
|
72
|
-
puts "is_at_gem_root: #{is_at_gem_root}" if verbose
|
82
|
+
puts "[#{gem_name}][#{basename}] is_at_gem_root: #{is_at_gem_root}" if verbose
|
73
83
|
lib_split = dirname.split("/lib/")[-1]
|
74
|
-
puts "lib_split: #{lib_split}" if verbose
|
84
|
+
puts "[#{gem_name}][#{basename}] lib_split: #{lib_split}" if verbose
|
75
85
|
# lib_split could be like:
|
76
86
|
# - "ruby/gems/3.2.0/gems/method_source-1.1.0/lib"
|
77
87
|
# - "method_source"
|
78
88
|
# Se we check to make sure it is actually a subdir of the gem's lib directory
|
79
89
|
full_path = File.join(gem_path, "lib", lib_split)
|
80
90
|
relative_path = !is_at_gem_root && Dir.exist?(full_path) && lib_split
|
81
|
-
puts "relative_path: #{relative_path}" if verbose
|
82
|
-
filename = File.basename(file)[0..-4]
|
83
|
-
puts "filename: #{filename}" if verbose
|
91
|
+
puts "[#{gem_name}][#{basename}] relative_path: #{relative_path}" if verbose
|
84
92
|
|
85
93
|
if relative_path
|
86
|
-
dir_path = File.join(
|
94
|
+
dir_path = File.join(tmp_dir, relative_path)
|
87
95
|
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
88
|
-
puts "
|
89
|
-
files << create_tempfile_copy(file,
|
96
|
+
puts "[#{gem_name}][#{basename}] copying file to #{dir_path}" if verbose
|
97
|
+
files << create_tempfile_copy(file, dir_path, basename, :dd1, &block)
|
90
98
|
else
|
91
|
-
puts "directory not relative (#{
|
92
|
-
files << create_tempfile_copy(file,
|
99
|
+
puts "[#{gem_name}][#{basename}] directory not relative (#{tmp_dir})" if verbose
|
100
|
+
files << create_tempfile_copy(file, tmp_dir, basename, :dd2, &block)
|
93
101
|
end
|
94
102
|
end
|
95
|
-
load_gem_copy(files)
|
103
|
+
load_gem_copy(tmp_dir, files)
|
96
104
|
end
|
97
105
|
|
98
106
|
nil
|
99
107
|
end
|
100
108
|
|
101
|
-
|
109
|
+
# @return [String] Namespace of the doffed (original) gem
|
110
|
+
def doffed_primary_namespace
|
111
|
+
trades.keys.first
|
112
|
+
end
|
113
|
+
|
114
|
+
# @return [String] Namespace of the donned gem
|
115
|
+
def donned_primary_namespace
|
102
116
|
trades.values.first
|
103
117
|
end
|
104
118
|
|
105
119
|
# Will raise NameError if called before #doff_and_don
|
120
|
+
# @return [Class, nil]
|
106
121
|
def as_klass
|
107
|
-
Object.const_get(
|
122
|
+
Object.const_get(donned_primary_namespace) if gem_path
|
108
123
|
end
|
109
124
|
|
110
125
|
private
|
111
126
|
|
112
|
-
|
127
|
+
# @param tmp_dir [String] absolute file path of the tmp directory
|
128
|
+
# @param files [Array[String]] absolute file path of each file in the donned gem
|
129
|
+
# @return void
|
130
|
+
def load_gem_copy(tmp_dir, files)
|
131
|
+
if verbose
|
132
|
+
puts "[#{gem_name}] Doffed gem located at #{gem_path}"
|
133
|
+
puts "[#{gem_name}] Donned gem located at #{tmp_dir}"
|
134
|
+
puts "[#{gem_name}] Primary namespace updated: #{doffed_primary_namespace} => #{donned_primary_namespace}"
|
135
|
+
puts "[#{gem_name}] Donned files:\n\t#{files.join("\n\t")}"
|
136
|
+
end
|
113
137
|
files.each do |filepath|
|
114
|
-
#
|
138
|
+
# But files required here may not load their own internal files properly if they are still using `require`.
|
139
|
+
# Since Ruby 2.2, best practice for ruby libraries is to use require_relative for internal files,
|
140
|
+
# and require for external files and dependencies.
|
141
|
+
# Ref: https://github.com/panorama-ed/memo_wise/issues/349
|
142
|
+
# We *can* use `require` *here*, because filepath here is an absolute paths
|
115
143
|
require filepath
|
116
|
-
# rescue LoadError => e
|
117
|
-
# puts file.to_s
|
118
|
-
# puts tempfile.path
|
119
|
-
# puts e.class
|
120
|
-
# puts e.message
|
121
|
-
# end
|
122
144
|
end
|
145
|
+
|
146
|
+
nil
|
123
147
|
end
|
124
148
|
|
149
|
+
# @param orig_file_path [String] absolute file path of the original file
|
150
|
+
# @param tmp_dir [String] absolute file path of the tmp directory
|
151
|
+
# @param basename [String] the basename of the file being copied
|
152
|
+
# @param debug_info [Symbol] for debugging purposes
|
125
153
|
# @return [String] the file path of the new copy of the original file
|
126
|
-
def create_tempfile_copy(
|
127
|
-
|
128
|
-
|
129
|
-
new_jersey(
|
154
|
+
def create_tempfile_copy(orig_file_path, tmp_dir, basename, debug_info, &block)
|
155
|
+
File.open(File.join(tmp_dir, basename), "w") do |donned_file|
|
156
|
+
# Value of block is returned from File.open, and thus from this method
|
157
|
+
new_jersey(orig_file_path, donned_file, basename, debug_info, &block)
|
130
158
|
end
|
131
159
|
end
|
132
160
|
|
133
|
-
#
|
134
|
-
|
135
|
-
|
161
|
+
# New Jersey is not Ohio. Writes donned files to disk.
|
162
|
+
#
|
163
|
+
# @param doffed_file_path [String] absolute file path of the original file
|
164
|
+
# @param donned_file [File] the file which needs to be written to disk
|
165
|
+
# @param basename [String] the basename of the file for verbose logging
|
166
|
+
# @param debug_info [Symbol] for debugging purposes
|
167
|
+
# @return [String] the file path of the donned file
|
168
|
+
def new_jersey(doffed_file_path, donned_file, basename, debug_info = nil)
|
169
|
+
nj = File.read(doffed_file_path)
|
136
170
|
trades.each do |old_namespace, new_namespace|
|
137
171
|
nj.gsub!(old_namespace, new_namespace)
|
138
172
|
end
|
139
173
|
if verbose
|
140
|
-
puts "new_jersey
|
141
|
-
puts "new_jersey
|
142
|
-
puts "new_jersey
|
174
|
+
puts "[#{gem_name}][#{basename}] new_jersey doffed_file_path: #{doffed_file_path}"
|
175
|
+
puts "[#{gem_name}][#{basename}] new_jersey donned_file path: #{donned_file.path}"
|
176
|
+
puts "[#{gem_name}][#{basename}] new_jersey debug_info: #{debug_info}"
|
143
177
|
end
|
144
178
|
nj = yield nj if block_given?
|
145
|
-
|
146
|
-
|
147
|
-
|
179
|
+
donned_file.write(nj)
|
180
|
+
donned_file.close
|
181
|
+
donned_file.path
|
148
182
|
end
|
149
183
|
end
|
150
184
|
end
|
data/lib/gem_bench/player.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
module GemBench
|
2
|
+
# Each gem either needs to be required at boot time or not.
|
3
|
+
# Player helps determine which gems can use `require: false` in the Gemfile to cut down load times.
|
2
4
|
class Player
|
3
5
|
# MAJOR.MINOR split on point length == 2
|
4
6
|
# MAJOR.MINOR.PATCH split on point length == 3
|
data/lib/gem_bench/scout.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# Scout's job is to figure out where gems are hiding
|
2
2
|
#
|
3
3
|
module GemBench
|
4
|
+
# Looks through loaded gems' (RubyGems & Bundler) source code searching for stuff
|
4
5
|
class Scout
|
5
6
|
attr_reader :gem_paths, :gemfile_path, :gemfile_lines, :gemfile_trash, :loaded_gems
|
6
7
|
|
7
|
-
def initialize(check_gemfile: nil)
|
8
|
+
def initialize(check_gemfile: nil, **options)
|
8
9
|
@check_gemfile = check_gemfile.nil? ? true : check_gemfile
|
9
|
-
@gemfile_path = "#{Dir.pwd}/Gemfile"
|
10
|
+
@gemfile_path = options.fetch(:gemfile_path, "#{Dir.pwd}/Gemfile")
|
10
11
|
gem_lookup_paths_from_bundler
|
11
12
|
gem_lines_from_gemfile
|
12
13
|
# Gem.loaded_specs are the gems that have been loaded / required.
|
@@ -27,10 +28,10 @@ module GemBench
|
|
27
28
|
.map { |x| x.to_s }
|
28
29
|
.reject { |p| p.empty? }
|
29
30
|
.map { |x| "#{x}/gems" }
|
30
|
-
@gem_paths <<
|
31
|
+
@gem_paths << Bundler.install_path.to_s # Pathname => String
|
31
32
|
@gem_paths << "#{Bundler.bundle_path}/gems"
|
32
33
|
@gem_paths.uniq!
|
33
|
-
rescue Bundler::GemfileNotFound =>
|
34
|
+
rescue Bundler::GemfileNotFound => _e
|
34
35
|
# Don't fail here, but also don't check the Gemfile.
|
35
36
|
@check_gemfile = false
|
36
37
|
ensure
|
@@ -42,6 +43,7 @@ module GemBench
|
|
42
43
|
file = File.open(gemfile_path)
|
43
44
|
# Get all lines as an array
|
44
45
|
all_lines = file.readlines
|
46
|
+
file.close
|
45
47
|
# Remove all the commented || blank lines
|
46
48
|
@gemfile_trash, @gemfile_lines = all_lines.partition { |x| x =~ GemBench::TRASH_REGEX }
|
47
49
|
@gemfile_trash.reject! { |x| x == "\n" } # remove blank lines
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module GemBench
|
2
|
+
# Helps determine if a gem dependency is "valid" according to the strict rules of:
|
3
|
+
# - every gem must have a version requirement of some sort
|
2
4
|
class StrictVersionGem
|
3
5
|
attr_reader :name, :version, :version_type, :valid, :relevant_lines, :index, :tokenized_line
|
4
6
|
|
5
7
|
class << self
|
6
8
|
def from_line(all_lines, line, index, opts = {})
|
7
9
|
tokenized_line = GemfileLineTokenizer.new(all_lines, line, index)
|
8
|
-
return unless tokenized_line.
|
10
|
+
return unless tokenized_line.parse_success
|
9
11
|
|
10
12
|
new(
|
11
13
|
tokenized_line.name,
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module GemBench
|
2
|
+
# Helps enforce a version requirement for every dependency in a Gemfile
|
2
3
|
class StrictVersionRequirement
|
3
4
|
attr_reader :gemfile_path, :gems, :starters, :benchers, :verbose
|
4
5
|
|
5
6
|
def initialize(options = {})
|
6
|
-
@gemfile_path = "#{Dir.pwd}/Gemfile"
|
7
|
+
@gemfile_path = options.fetch(:gemfile_path, "#{Dir.pwd}/Gemfile")
|
7
8
|
file = File.open(gemfile_path)
|
8
9
|
# Get all lines as an array
|
9
10
|
all_lines = file.readlines
|
data/lib/gem_bench/team.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require "forwardable"
|
2
2
|
|
3
3
|
module GemBench
|
4
|
+
# It doesn't make sense to use Team unless the Gemfile you want to evaluate is currently loaded.
|
5
|
+
# For example:
|
6
|
+
# - if you are in a rails console, and want to evaluate the Gemfile of the Rails app, that's great!
|
7
|
+
# - if you are in a context with no Gemfile loaded, or a different Gemfile loaded than the one you want to evaluate,
|
8
|
+
# this class may not give sensible results. This is because it checks loaded gems via RubyGems and Bundler.
|
4
9
|
class Team
|
5
10
|
EXCLUDE = %w[
|
6
11
|
bundler
|
@@ -19,6 +24,8 @@ module GemBench
|
|
19
24
|
cancan
|
20
25
|
friendly_id
|
21
26
|
faker
|
27
|
+
capistrano3-puma
|
28
|
+
wkhtmltopdf-binary
|
22
29
|
]
|
23
30
|
# A comment preceding the require: false anywhere on the line should not be considered an active require: false
|
24
31
|
extend Forwardable
|
@@ -34,13 +41,16 @@ module GemBench
|
|
34
41
|
:current_gemfile_suggestions,
|
35
42
|
:bad_ideas
|
36
43
|
|
37
|
-
def initialize(options
|
44
|
+
def initialize(**options)
|
38
45
|
@look_for_regex = options[:look_for_regex]
|
39
46
|
# find: Find gems containing specific strings in code
|
40
47
|
# bench: Find gems that can probably be benched (require: false) in the Gemfile
|
41
48
|
@check_type = @look_for_regex ? :find : :bench
|
42
49
|
@benching = @check_type == :bench
|
43
|
-
@scout = GemBench::Scout.new(
|
50
|
+
@scout = GemBench::Scout.new(
|
51
|
+
check_gemfile: options.fetch(:check_gemfile, benching?),
|
52
|
+
gemfile_path: options.fetch(:gemfile_path, "#{Dir.pwd}/Gemfile"),
|
53
|
+
)
|
44
54
|
@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
|
45
55
|
# Among the loaded gems there may be some that did not need to be.
|
46
56
|
@excluded, @all = @scout.loaded_gems.partition { |x| EXCLUDE.include?(x[0]) }
|
@@ -192,13 +202,13 @@ module GemBench
|
|
192
202
|
end
|
193
203
|
|
194
204
|
def check(player)
|
195
|
-
gem_paths.
|
205
|
+
gem_paths.detect do |path|
|
196
206
|
glob_path = "#{path}/#{player.file_path_glob}"
|
197
|
-
file_paths = Dir.glob(
|
207
|
+
file_paths = Dir.glob(glob_path)
|
198
208
|
puts "[GemBench] checking #{player} at #{glob_path} (#{file_paths.length} files)" if extra_verbose?
|
199
|
-
file_paths.
|
209
|
+
file_paths.detect do |file_path|
|
200
210
|
player.set_starter(file_path, line_match: look_for_regex)
|
201
|
-
|
211
|
+
player.starter?
|
202
212
|
end
|
203
213
|
end
|
204
214
|
end
|
data/lib/gem_bench/version.rb
CHANGED
data/lib/gem_bench.rb
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
require "version_gem"
|
3
3
|
require "bundler" # This gem utilizes bundler as a tool.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
# this library
|
6
|
+
require_relative "gem_bench/version"
|
7
|
+
require_relative "gem_bench/scout"
|
8
|
+
require_relative "gem_bench/player"
|
9
|
+
require_relative "gem_bench/team"
|
10
|
+
require_relative "gem_bench/gemfile_line_tokenizer"
|
11
|
+
require_relative "gem_bench/strict_version_gem"
|
12
|
+
require_relative "gem_bench/strict_version_requirement"
|
12
13
|
|
13
14
|
module GemBench
|
14
15
|
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"
|
@@ -25,29 +26,41 @@ module GemBench
|
|
25
26
|
}
|
26
27
|
|
27
28
|
class << self
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def check(verbose: false, gemfile_path: nil)
|
30
|
+
options = {
|
31
|
+
verbose: verbose,
|
32
|
+
}
|
33
|
+
options[:gemfile_path] = gemfile_path if gemfile_path
|
34
|
+
GemBench::Team.new(**options)
|
32
35
|
end
|
33
36
|
|
34
|
-
def versions_present?(verbose: false)
|
35
|
-
|
36
|
-
|
37
|
+
def versions_present?(verbose: false, gemfile_path: nil)
|
38
|
+
options = {
|
39
|
+
verbose: verbose,
|
40
|
+
}
|
41
|
+
options[:gemfile_path] = gemfile_path if gemfile_path
|
42
|
+
GemBench::StrictVersionRequirement.new(**options).versions_present?
|
37
43
|
end
|
38
44
|
|
39
|
-
def list_missing_version_constraints(verbose: false)
|
40
|
-
|
41
|
-
|
45
|
+
def list_missing_version_constraints(verbose: false, gemfile_path: nil)
|
46
|
+
options = {
|
47
|
+
verbose: verbose,
|
48
|
+
}
|
49
|
+
options[:gemfile_path] = gemfile_path if gemfile_path
|
50
|
+
GemBench::StrictVersionRequirement.new(**options).list_missing_version_constraints
|
42
51
|
end
|
43
52
|
|
44
53
|
def find(look_for_regex: GemBench::RAILTIE_REGEX,
|
45
|
-
exclude_file_pattern_regex_proc: GemBench::EXCLUDE_FILE_PATTERN_REGEX_PROC,
|
46
|
-
|
54
|
+
exclude_file_pattern_regex_proc: GemBench::EXCLUDE_FILE_PATTERN_REGEX_PROC,
|
55
|
+
verbose: false,
|
56
|
+
gemfile_path: nil)
|
57
|
+
options = {
|
58
|
+
verbose: verbose,
|
47
59
|
look_for_regex: look_for_regex,
|
48
60
|
exclude_file_pattern_regex_proc: exclude_file_pattern_regex_proc,
|
49
|
-
|
50
|
-
|
61
|
+
}
|
62
|
+
options[:gemfile_path] = gemfile_path if gemfile_path
|
63
|
+
GemBench::Team.new(**options)
|
51
64
|
end
|
52
65
|
end
|
53
66
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem_bench
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
@@ -12,31 +12,31 @@ cert_chain:
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl
|
14
14
|
ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
|
15
|
-
|
15
|
+
A2NvbTAeFw0yNDA5MjAwODU4NDJaFw0yNTA5MjAwODU4NDJaMEMxFTATBgNVBAMM
|
16
16
|
DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
/
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAjrxsKObI
|
18
|
+
rFQjBpzvVfqnT6JlF8/pkpgEEjFh7ex3zIerfuHzZvSrx+sRDGxQ8koWWG0Wjx8s
|
19
|
+
wkBZ5dIqvl0g3sWP5asa28u/09opxkQTC1Ao77iYxcBcwoCe/Dpf1m4Q/m6oH0kL
|
20
|
+
2AZVNJQL3UkqAcLS0tsj/s/jAKnVlsaZZE5gQiIIi8HtkvSsajtx+Cq2AxDvcWvV
|
21
|
+
/CliD+pmzYkTjvjwGm8yeyFGGGgrisJMryiZdZlkTwrQSjCzudIKbLeuG8Se4JTD
|
22
|
+
TAcT+rPubr27v1jwmtIjtiot3rf4nof7LHLb122a/0VR7cC7xPLnXw0Cq1BShvoq
|
23
|
+
/GKRdSwMNinTOGkFTK1gKnjN+3iD4zyXU3XO3CXoTr+Ju8fXPN1x4tpOMgbv8dme
|
24
|
+
WbcQMOH9ZjmA5w0bSVRL1c3NhRRpUzrKTNXBEvqOyWjUnintxWKj+cRXx+z+dUgI
|
25
|
+
dL3kj68fcsiTgl75In3C485pnCMmq1eLuVoiy3jkLNOn2lHeLt9ZK63LAgMBAAGj
|
26
|
+
fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRhfc+2UaVYd74p
|
27
|
+
yJ1JclGiUYN8+jAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG
|
28
28
|
A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
ggGBAA4fLU2+mQ++jBhVM2IeyvQdw1nm+0thkH4Ldv8ZOBm5ZxCPGIMoYliDDzg4
|
30
|
+
4JDFxZR1wR4sdrz/K5tWtEkN23SKzopwbNb1NIQRSLQ7nOoc+4bkuz9xwKinmIvF
|
31
|
+
D+5qsl2S27WLKFreMDtGoh0CREIMBUxU4rGTh0gtzmweGR+fnOShg4Jo0kxrjU5h
|
32
|
+
uYk/uVE+bn/jOEGs43GvKXZLyshpBrZjQ+ArbvxDht5t35zbSxerbUxUPZUbXUCW
|
33
|
+
tTyh38a9UYjAAHvnh6Y4Fi9wd4/pGNsektrzB3z/zlVj4YF2TMLX9XfNJWEGRGpO
|
34
|
+
sSkLYdtEX1WQAmuZtActVW2cL3HdQaRbiv7VbfpA0eSk0ZdZHvBCl516ZZu10uX6
|
35
|
+
82W1mg6fuezdpeBOiXwrEbZSt/oGiF4V511F6nd55p0okwHc/6nS10F/3aKJ4gwC
|
36
|
+
I5o+DRfXQHqKucx1ldFHvI2rE/kSCWqGTHN2eyu1sqCPeOoIMxrltJhaejKPkxqj
|
37
|
+
zaF9Og==
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2024-09-
|
39
|
+
date: 2024-09-20 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
@@ -130,16 +130,16 @@ dependencies:
|
|
130
130
|
name: awesome_print
|
131
131
|
requirement: !ruby/object:Gem::Requirement
|
132
132
|
requirements:
|
133
|
-
- - "
|
133
|
+
- - "~>"
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version: '
|
135
|
+
version: '1.9'
|
136
136
|
type: :development
|
137
137
|
prerelease: false
|
138
138
|
version_requirements: !ruby/object:Gem::Requirement
|
139
139
|
requirements:
|
140
|
-
- - "
|
140
|
+
- - "~>"
|
141
141
|
- !ruby/object:Gem::Version
|
142
|
-
version: '
|
142
|
+
version: '1.9'
|
143
143
|
- !ruby/object:Gem::Dependency
|
144
144
|
name: method_source
|
145
145
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,42 +160,48 @@ dependencies:
|
|
160
160
|
requirements:
|
161
161
|
- - ">="
|
162
162
|
- !ruby/object:Gem::Version
|
163
|
-
version: '
|
163
|
+
version: '10'
|
164
164
|
type: :development
|
165
165
|
prerelease: false
|
166
166
|
version_requirements: !ruby/object:Gem::Requirement
|
167
167
|
requirements:
|
168
168
|
- - ">="
|
169
169
|
- !ruby/object:Gem::Version
|
170
|
-
version: '
|
170
|
+
version: '10'
|
171
171
|
- !ruby/object:Gem::Dependency
|
172
172
|
name: rspec
|
173
173
|
requirement: !ruby/object:Gem::Requirement
|
174
174
|
requirements:
|
175
|
-
- - "
|
175
|
+
- - "~>"
|
176
176
|
- !ruby/object:Gem::Version
|
177
|
-
version: '
|
177
|
+
version: '3.13'
|
178
178
|
type: :development
|
179
179
|
prerelease: false
|
180
180
|
version_requirements: !ruby/object:Gem::Requirement
|
181
181
|
requirements:
|
182
|
-
- - "
|
182
|
+
- - "~>"
|
183
183
|
- !ruby/object:Gem::Version
|
184
|
-
version: '
|
184
|
+
version: '3.13'
|
185
185
|
- !ruby/object:Gem::Dependency
|
186
186
|
name: rspec-block_is_expected
|
187
187
|
requirement: !ruby/object:Gem::Requirement
|
188
188
|
requirements:
|
189
|
+
- - "~>"
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '1.0'
|
189
192
|
- - ">="
|
190
193
|
- !ruby/object:Gem::Version
|
191
|
-
version:
|
194
|
+
version: 1.0.6
|
192
195
|
type: :development
|
193
196
|
prerelease: false
|
194
197
|
version_requirements: !ruby/object:Gem::Requirement
|
195
198
|
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '1.0'
|
196
202
|
- - ">="
|
197
203
|
- !ruby/object:Gem::Version
|
198
|
-
version:
|
204
|
+
version: 1.0.6
|
199
205
|
- !ruby/object:Gem::Dependency
|
200
206
|
name: rubocop-lts
|
201
207
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,28 +240,28 @@ dependencies:
|
|
234
240
|
name: rubocop-rspec
|
235
241
|
requirement: !ruby/object:Gem::Requirement
|
236
242
|
requirements:
|
237
|
-
- - "
|
243
|
+
- - "~>"
|
238
244
|
- !ruby/object:Gem::Version
|
239
|
-
version: '0'
|
245
|
+
version: '3.0'
|
240
246
|
type: :development
|
241
247
|
prerelease: false
|
242
248
|
version_requirements: !ruby/object:Gem::Requirement
|
243
249
|
requirements:
|
244
|
-
- - "
|
250
|
+
- - "~>"
|
245
251
|
- !ruby/object:Gem::Version
|
246
|
-
version: '0'
|
252
|
+
version: '3.0'
|
247
253
|
- !ruby/object:Gem::Dependency
|
248
254
|
name: standard
|
249
255
|
requirement: !ruby/object:Gem::Requirement
|
250
256
|
requirements:
|
251
|
-
- - "
|
257
|
+
- - "~>"
|
252
258
|
- !ruby/object:Gem::Version
|
253
259
|
version: '1.40'
|
254
260
|
type: :development
|
255
261
|
prerelease: false
|
256
262
|
version_requirements: !ruby/object:Gem::Requirement
|
257
263
|
requirements:
|
258
|
-
- - "
|
264
|
+
- - "~>"
|
259
265
|
- !ruby/object:Gem::Version
|
260
266
|
version: '1.40'
|
261
267
|
description: |-
|
@@ -290,10 +296,10 @@ licenses:
|
|
290
296
|
- MIT
|
291
297
|
metadata:
|
292
298
|
homepage_uri: https://railsbling.com/tags/gem_bench/
|
293
|
-
source_code_uri: http://github.com/pboling/gem_bench/tree/v2.0.
|
294
|
-
changelog_uri: http://github.com/pboling/gem_bench/blob/v2.0.
|
299
|
+
source_code_uri: http://github.com/pboling/gem_bench/tree/v2.0.4
|
300
|
+
changelog_uri: http://github.com/pboling/gem_bench/blob/v2.0.4/CHANGELOG.md
|
295
301
|
bug_tracker_uri: http://github.com/pboling/gem_bench/issues
|
296
|
-
documentation_uri: https://www.rubydoc.info/gems/gem_bench/2.0.
|
302
|
+
documentation_uri: https://www.rubydoc.info/gems/gem_bench/2.0.4
|
297
303
|
wiki_uri: http://github.com/pboling/gem_bench/wiki
|
298
304
|
funding_uri: https://liberapay.com/pboling
|
299
305
|
rubygems_mfa_required: 'true'
|
metadata.gz.sig
CHANGED
Binary file
|