gem_bench 2.0.3 → 2.0.4
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 +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 | [](https://www.codetriage.com/pboling/gem_bench) |
|
105
|
+
| documentation | [on Github.com][homepage], [on Rdoc.info][documentation] |
|
106
|
+
| expert support | [](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
|