dependabot-gradle 0.127.0 → 0.127.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
- data/lib/dependabot/gradle/file_fetcher.rb +38 -6
- data/lib/dependabot/gradle/file_parser.rb +20 -9
- data/lib/dependabot/gradle/file_parser/property_value_finder.rb +86 -7
- data/lib/dependabot/gradle/file_parser/repositories_finder.rb +13 -3
- data/lib/dependabot/gradle/file_updater.rb +12 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a411c5177e1d5fb791abde79c28e1bf3e8f6163f6955b059c7737d3b7487407
|
|
4
|
+
data.tar.gz: c3f5785b9e4ff1cd9a153605200c00117fb03890a006c0571fb70bc579637430
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8af89262dcdaa0cce5fb6790a222a09bb65ec32ccdfcfd2996a570760c15c4250fa627a02b1dcaf8e34ec30b07295c81d16d2c3379918091fe5d21572f5d754e
|
|
7
|
+
data.tar.gz: 9d67cc3cb9332c7df3a0360dd64adc6e5469b9f6cc354b5a62c33bdfe384a33b3b200562b9bac79d99d21ebeb5dd5bab709670c8b91970dd195fbcd1d2ac0a6e
|
|
@@ -8,12 +8,20 @@ module Dependabot
|
|
|
8
8
|
class FileFetcher < Dependabot::FileFetchers::Base
|
|
9
9
|
require_relative "file_fetcher/settings_file_parser"
|
|
10
10
|
|
|
11
|
+
SUPPORTED_BUILD_FILE_NAMES =
|
|
12
|
+
%w(build.gradle build.gradle.kts).freeze
|
|
13
|
+
|
|
14
|
+
SUPPORTED_SETTINGS_FILE_NAMES =
|
|
15
|
+
%w(settings.gradle settings.gradle.kts).freeze
|
|
16
|
+
|
|
11
17
|
def self.required_files_in?(filenames)
|
|
12
|
-
filenames.
|
|
18
|
+
filenames.any? do |filename|
|
|
19
|
+
SUPPORTED_BUILD_FILE_NAMES.include?(filename)
|
|
20
|
+
end
|
|
13
21
|
end
|
|
14
22
|
|
|
15
23
|
def self.required_files_message
|
|
16
|
-
"Repo must contain a build.gradle."
|
|
24
|
+
"Repo must contain a build.gradle / build.gradle.kts file."
|
|
17
25
|
end
|
|
18
26
|
|
|
19
27
|
private
|
|
@@ -27,7 +35,11 @@ module Dependabot
|
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
def buildfile
|
|
30
|
-
@buildfile ||=
|
|
38
|
+
@buildfile ||= begin
|
|
39
|
+
file = supported_build_file
|
|
40
|
+
@buildfile_name ||= file.name if file
|
|
41
|
+
fetch_file_from_host(file.name) if file
|
|
42
|
+
end
|
|
31
43
|
end
|
|
32
44
|
|
|
33
45
|
def subproject_buildfiles
|
|
@@ -39,7 +51,7 @@ module Dependabot
|
|
|
39
51
|
subproject_paths
|
|
40
52
|
|
|
41
53
|
subproject_paths.map do |path|
|
|
42
|
-
fetch_file_from_host(File.join(path,
|
|
54
|
+
fetch_file_from_host(File.join(path, @buildfile_name))
|
|
43
55
|
rescue Dependabot::DependencyFileNotFound
|
|
44
56
|
# Gradle itself doesn't worry about missing subprojects, so we don't
|
|
45
57
|
nil
|
|
@@ -74,8 +86,28 @@ module Dependabot
|
|
|
74
86
|
end
|
|
75
87
|
|
|
76
88
|
def settings_file
|
|
77
|
-
@settings_file ||=
|
|
78
|
-
|
|
89
|
+
@settings_file ||= begin
|
|
90
|
+
file = supported_settings_file
|
|
91
|
+
fetch_file_from_host(file.name) if file
|
|
92
|
+
rescue Dependabot::DependencyFileNotFound
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def supported_build_file
|
|
98
|
+
supported_file(SUPPORTED_BUILD_FILE_NAMES)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def supported_settings_file
|
|
102
|
+
supported_file(SUPPORTED_SETTINGS_FILE_NAMES)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def supported_file(supported_file_names)
|
|
106
|
+
supported_file_names.each do |supported_file_name|
|
|
107
|
+
file = fetch_file_if_present(supported_file_name)
|
|
108
|
+
return file if file
|
|
109
|
+
end
|
|
110
|
+
|
|
79
111
|
nil
|
|
80
112
|
end
|
|
81
113
|
end
|
|
@@ -18,6 +18,8 @@ module Dependabot
|
|
|
18
18
|
require "dependabot/file_parsers/base/dependency_set"
|
|
19
19
|
require_relative "file_parser/property_value_finder"
|
|
20
20
|
|
|
21
|
+
SUPPORTED_BUILD_FILE_NAMES = %w(build.gradle build.gradle.kts).freeze
|
|
22
|
+
|
|
21
23
|
PROPERTY_REGEX =
|
|
22
24
|
/
|
|
23
25
|
(?:\$\{property\((?<property_name>[^:\s]*?)\)\})|
|
|
@@ -36,6 +38,7 @@ module Dependabot
|
|
|
36
38
|
PLUGIN_BLOCK_DECLARATION_REGEX = /(?:^|\s)plugins\s*\{/.freeze
|
|
37
39
|
PLUGIN_BLOCK_ENTRY_REGEX =
|
|
38
40
|
/id\s+"(?<id>#{PART})"\s+version\s+"(?<version>#{VSN_PART})"/.freeze
|
|
41
|
+
PLUGIN_ID_REGEX = /['"](?<id>#{PART})['"]/.freeze
|
|
39
42
|
|
|
40
43
|
def parse
|
|
41
44
|
dependency_set = DependencySet.new
|
|
@@ -51,7 +54,7 @@ module Dependabot
|
|
|
51
54
|
private
|
|
52
55
|
|
|
53
56
|
def map_value_regex(key)
|
|
54
|
-
/(?:^|\s|,|\()#{Regexp.quote(key)}
|
|
57
|
+
/(?:^|\s|,|\()#{Regexp.quote(key)}(\s*=|:)\s*['"](?<value>[^'"]+)['"]/
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
def buildfile_dependencies(buildfile)
|
|
@@ -146,10 +149,11 @@ module Dependabot
|
|
|
146
149
|
|
|
147
150
|
plugin_blocks.each do |blk|
|
|
148
151
|
blk.lines.each do |line|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
name_regex = /id(\s+#{PLUGIN_ID_REGEX}|\(#{PLUGIN_ID_REGEX}\))/
|
|
153
|
+
name = line.match(name_regex)&.named_captures&.fetch("id")
|
|
154
|
+
version_regex = /version\s+['"](?<version>#{VSN_PART})['"]/
|
|
155
|
+
version = line.match(version_regex)&.named_captures&.
|
|
156
|
+
fetch("version")
|
|
153
157
|
next unless name && version
|
|
154
158
|
|
|
155
159
|
details = { name: name, group: "plugins", version: version }
|
|
@@ -286,15 +290,16 @@ module Dependabot
|
|
|
286
290
|
end
|
|
287
291
|
|
|
288
292
|
def buildfiles
|
|
289
|
-
@buildfiles ||=
|
|
290
|
-
|
|
293
|
+
@buildfiles ||= dependency_files.select do |f|
|
|
294
|
+
f.name.end_with?(*SUPPORTED_BUILD_FILE_NAMES)
|
|
295
|
+
end
|
|
291
296
|
end
|
|
292
297
|
|
|
293
298
|
def script_plugin_files
|
|
294
299
|
@script_plugin_files ||=
|
|
295
300
|
buildfiles.flat_map do |buildfile|
|
|
296
301
|
buildfile.content.
|
|
297
|
-
scan(/apply from
|
|
302
|
+
scan(/apply from(\s+=|:)\s+['"]([^'"]+)['"]/).flatten.
|
|
298
303
|
map { |f| dependency_files.find { |bf| bf.name == f } }.
|
|
299
304
|
compact
|
|
300
305
|
end.
|
|
@@ -302,7 +307,13 @@ module Dependabot
|
|
|
302
307
|
end
|
|
303
308
|
|
|
304
309
|
def check_required_files
|
|
305
|
-
raise "No build.gradle
|
|
310
|
+
raise "No build.gradle or build.gradle.kts!" unless original_file
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def original_file
|
|
314
|
+
dependency_files.find do |f|
|
|
315
|
+
SUPPORTED_BUILD_FILE_NAMES.include?(f.name)
|
|
316
|
+
end
|
|
306
317
|
end
|
|
307
318
|
end
|
|
308
319
|
end
|
|
@@ -7,6 +7,8 @@ module Dependabot
|
|
|
7
7
|
class FileParser
|
|
8
8
|
class PropertyValueFinder
|
|
9
9
|
# rubocop:disable Layout/LineLength
|
|
10
|
+
SUPPORTED_BUILD_FILE_NAMES = %w(build.gradle build.gradle.kts).freeze
|
|
11
|
+
|
|
10
12
|
QUOTED_VALUE_REGEX =
|
|
11
13
|
/\s*['"][^\s]+['"]\s*/.freeze
|
|
12
14
|
|
|
@@ -15,20 +17,63 @@ module Dependabot
|
|
|
15
17
|
/\s*project\.findProperty\(#{QUOTED_VALUE_REGEX}\)\s*\?:/.freeze
|
|
16
18
|
|
|
17
19
|
# project.hasProperty('property') ? project.getProperty('property') :
|
|
18
|
-
|
|
20
|
+
GROOVY_HAS_PROPERTY_REGEX =
|
|
19
21
|
/\s*project\.hasProperty\(#{QUOTED_VALUE_REGEX}\)\s*\?\s*project\.getProperty\(#{QUOTED_VALUE_REGEX}\)\s*:/.freeze
|
|
20
22
|
|
|
23
|
+
# if(project.hasProperty("property")) project.getProperty("property") else
|
|
24
|
+
KOTLIN_HAS_PROPERTY_REGEX =
|
|
25
|
+
/\s*if\s*\(project\.hasProperty\(#{QUOTED_VALUE_REGEX}\)\)\s+project\.getProperty\(#{QUOTED_VALUE_REGEX}\)\s+else\s+/.freeze
|
|
26
|
+
|
|
27
|
+
GROOVY_PROPERTY_DECLARATION_AS_DEFAULTS_REGEX =
|
|
28
|
+
/(?:#{FIND_PROPERTY_REGEX}|#{GROOVY_HAS_PROPERTY_REGEX})?/.freeze
|
|
29
|
+
|
|
30
|
+
KOTLIN_PROPERTY_DECLARATION_AS_DEFAULTS_REGEX =
|
|
31
|
+
/(?:#{FIND_PROPERTY_REGEX}|#{KOTLIN_HAS_PROPERTY_REGEX})?/.freeze
|
|
32
|
+
|
|
21
33
|
PROPERTY_DECLARATION_AS_DEFAULTS_REGEX =
|
|
22
|
-
/(
|
|
34
|
+
/(#{GROOVY_PROPERTY_DECLARATION_AS_DEFAULTS_REGEX}|#{KOTLIN_PROPERTY_DECLARATION_AS_DEFAULTS_REGEX})?/.freeze
|
|
35
|
+
|
|
36
|
+
VALUE_REGEX =
|
|
37
|
+
/#{PROPERTY_DECLARATION_AS_DEFAULTS_REGEX}\s*['"](?<value>[^\s]+)['"]/.freeze
|
|
38
|
+
|
|
39
|
+
GROOVY_SINGLE_PROPERTY_DECLARATION_REGEX =
|
|
40
|
+
/(?:^|\s+|ext.)(?<name>[^\s=]+)\s*=#{VALUE_REGEX}/.freeze
|
|
41
|
+
|
|
42
|
+
KOTLIN_SINGLE_PROPERTY_INDEX_DECLARATION_REGEX =
|
|
43
|
+
/\s*extra\[['"](?<name>[^\s=]+)['"]\]\s*=#{VALUE_REGEX}/.freeze
|
|
44
|
+
|
|
45
|
+
KOTLIN_SINGLE_PROPERTY_SET_REGEX =
|
|
46
|
+
/\s*set\(['"](?<name>[^\s=]+)['"]\s*,#{VALUE_REGEX}\)/.freeze
|
|
47
|
+
|
|
48
|
+
KOTLIN_SINGLE_PROPERTY_SET_DECLARATION_REGEX =
|
|
49
|
+
/\s*extra\.#{KOTLIN_SINGLE_PROPERTY_SET_REGEX}/.freeze
|
|
50
|
+
|
|
51
|
+
KOTLIN_SINGLE_PROPERTY_DECLARATION_REGEX =
|
|
52
|
+
/(#{KOTLIN_SINGLE_PROPERTY_INDEX_DECLARATION_REGEX}|#{KOTLIN_SINGLE_PROPERTY_SET_DECLARATION_REGEX})/.freeze
|
|
23
53
|
|
|
24
54
|
SINGLE_PROPERTY_DECLARATION_REGEX =
|
|
25
|
-
/(
|
|
55
|
+
/(#{KOTLIN_SINGLE_PROPERTY_DECLARATION_REGEX}|#{GROOVY_SINGLE_PROPERTY_DECLARATION_REGEX})/.freeze
|
|
26
56
|
|
|
27
|
-
|
|
57
|
+
GROOVY_MULTI_PROPERTY_DECLARATION_REGEX =
|
|
28
58
|
/(?:^|\s+|ext.)(?<namespace>[^\s=]+)\s*=\s*\[(?<values>[^\]]+)\]/m.freeze
|
|
29
59
|
|
|
60
|
+
KOTLIN_BLOCK_PROPERTY_DECLARATION_REGEX =
|
|
61
|
+
/\s*(?<namespace>[^\s=]+)\.apply\s*{(?<values>[^\]]+)}/m.freeze
|
|
62
|
+
|
|
63
|
+
KOTLIN_MULTI_PROPERTY_DECLARATION_REGEX =
|
|
64
|
+
/\s*extra\[['"](?<namespace>[^\s=]+)['"]\]\s*=\s*mapOf\((?<values>[^\]]+)\)/m.freeze
|
|
65
|
+
|
|
66
|
+
MULTI_PROPERTY_DECLARATION_REGEX =
|
|
67
|
+
/(#{KOTLIN_MULTI_PROPERTY_DECLARATION_REGEX}|#{GROOVY_MULTI_PROPERTY_DECLARATION_REGEX})/.freeze
|
|
68
|
+
|
|
69
|
+
KOTLIN_MAP_NAMESPACED_DECLARATION_REGEX =
|
|
70
|
+
/(?:^|\s+)['"](?<name>[^\s:]+)['"]\s*to#{VALUE_REGEX}\s*/.freeze
|
|
71
|
+
|
|
72
|
+
REGULAR_NAMESPACED_DECLARATION_REGEX =
|
|
73
|
+
/(?:^|\s+)(?<name>[^\s:]+)\s*[:=]#{VALUE_REGEX}\s*/.freeze
|
|
74
|
+
|
|
30
75
|
NAMESPACED_DECLARATION_REGEX =
|
|
31
|
-
/(
|
|
76
|
+
/(#{REGULAR_NAMESPACED_DECLARATION_REGEX}|#{KOTLIN_MAP_NAMESPACED_DECLARATION_REGEX})/.freeze
|
|
32
77
|
# rubocop:enable Layout/LineLength
|
|
33
78
|
|
|
34
79
|
def initialize(dependency_files:)
|
|
@@ -78,6 +123,9 @@ module Dependabot
|
|
|
78
123
|
@properties[buildfile.name].
|
|
79
124
|
merge!(fetch_single_property_declarations(buildfile))
|
|
80
125
|
|
|
126
|
+
@properties[buildfile.name].
|
|
127
|
+
merge!(fetch_kotlin_block_property_declarations(buildfile))
|
|
128
|
+
|
|
81
129
|
@properties[buildfile.name].
|
|
82
130
|
merge!(fetch_multi_property_declarations(buildfile))
|
|
83
131
|
|
|
@@ -104,6 +152,36 @@ module Dependabot
|
|
|
104
152
|
properties
|
|
105
153
|
end
|
|
106
154
|
|
|
155
|
+
def fetch_kotlin_block_property_declarations(buildfile)
|
|
156
|
+
properties = {}
|
|
157
|
+
|
|
158
|
+
prepared_content(buildfile).
|
|
159
|
+
scan(KOTLIN_BLOCK_PROPERTY_DECLARATION_REGEX) do
|
|
160
|
+
captures = Regexp.last_match.named_captures
|
|
161
|
+
namespace = captures.fetch("namespace")
|
|
162
|
+
|
|
163
|
+
captures.fetch("values").
|
|
164
|
+
scan(KOTLIN_SINGLE_PROPERTY_SET_REGEX) do
|
|
165
|
+
declaration_string = Regexp.last_match.to_s.strip
|
|
166
|
+
sub_captures = Regexp.last_match.named_captures
|
|
167
|
+
name = sub_captures.fetch("name")
|
|
168
|
+
full_name = if namespace == "extra"
|
|
169
|
+
name
|
|
170
|
+
else
|
|
171
|
+
[namespace, name].join(".")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
properties[full_name] = {
|
|
175
|
+
value: sub_captures.fetch("value"),
|
|
176
|
+
declaration_string: declaration_string,
|
|
177
|
+
file: buildfile.name
|
|
178
|
+
}
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
properties
|
|
183
|
+
end
|
|
184
|
+
|
|
107
185
|
def fetch_multi_property_declarations(buildfile)
|
|
108
186
|
properties = {}
|
|
109
187
|
|
|
@@ -136,8 +214,9 @@ module Dependabot
|
|
|
136
214
|
end
|
|
137
215
|
|
|
138
216
|
def top_level_buildfile
|
|
139
|
-
@top_level_buildfile ||=
|
|
140
|
-
|
|
217
|
+
@top_level_buildfile ||= dependency_files.find do |f|
|
|
218
|
+
SUPPORTED_BUILD_FILE_NAMES.include?(f.name)
|
|
219
|
+
end
|
|
141
220
|
end
|
|
142
221
|
end
|
|
143
222
|
end
|
|
@@ -6,15 +6,24 @@ module Dependabot
|
|
|
6
6
|
module Gradle
|
|
7
7
|
class FileParser
|
|
8
8
|
class RepositoriesFinder
|
|
9
|
+
SUPPORTED_BUILD_FILE_NAMES = %w(build.gradle build.gradle.kts).freeze
|
|
10
|
+
|
|
9
11
|
# The Central Repo doesn't have special status for Gradle, but until
|
|
10
12
|
# we're confident we're selecting repos correctly it's wise to include
|
|
11
13
|
# it as a default.
|
|
12
14
|
CENTRAL_REPO_URL = "https://repo.maven.apache.org/maven2"
|
|
13
15
|
|
|
14
16
|
REPOSITORIES_BLOCK_START = /(?:^|\s)repositories\s*\{/.freeze
|
|
15
|
-
|
|
17
|
+
|
|
18
|
+
GROOVY_MAVEN_REPO_REGEX =
|
|
16
19
|
/maven\s*\{[^\}]*\surl[\s\(]\s*['"](?<url>[^'"]+)['"]/.freeze
|
|
17
20
|
|
|
21
|
+
KOTLIN_MAVEN_REPO_REGEX =
|
|
22
|
+
/maven\(['"](?<url>[^'"]+)['"]\)/.freeze
|
|
23
|
+
|
|
24
|
+
MAVEN_REPO_REGEX =
|
|
25
|
+
/(#{KOTLIN_MAVEN_REPO_REGEX}|#{GROOVY_MAVEN_REPO_REGEX})/.freeze
|
|
26
|
+
|
|
18
27
|
def initialize(dependency_files:, target_dependency_file:)
|
|
19
28
|
@dependency_files = dependency_files
|
|
20
29
|
@target_dependency_file = target_dependency_file
|
|
@@ -130,8 +139,9 @@ module Dependabot
|
|
|
130
139
|
end
|
|
131
140
|
|
|
132
141
|
def top_level_buildfile
|
|
133
|
-
@top_level_buildfile ||=
|
|
134
|
-
|
|
142
|
+
@top_level_buildfile ||= dependency_files.find do |f|
|
|
143
|
+
SUPPORTED_BUILD_FILE_NAMES.include?(f.name)
|
|
144
|
+
end
|
|
135
145
|
end
|
|
136
146
|
end
|
|
137
147
|
end
|
|
@@ -10,8 +10,10 @@ module Dependabot
|
|
|
10
10
|
require_relative "file_updater/dependency_set_updater"
|
|
11
11
|
require_relative "file_updater/property_value_updater"
|
|
12
12
|
|
|
13
|
+
SUPPORTED_BUILD_FILE_NAMES = %w(build.gradle build.gradle.kts).freeze
|
|
14
|
+
|
|
13
15
|
def self.updated_files_regex
|
|
14
|
-
[/^build\.gradle
|
|
16
|
+
[/^build\.gradle(\.kts)?$/, %r{/build\.gradle(\.kts)?$}]
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def updated_dependency_files
|
|
@@ -38,7 +40,13 @@ module Dependabot
|
|
|
38
40
|
private
|
|
39
41
|
|
|
40
42
|
def check_required_files
|
|
41
|
-
raise "No build.gradle
|
|
43
|
+
raise "No build.gradle or build.gradle.kts!" unless original_file
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def original_file
|
|
47
|
+
dependency_files.find do |f|
|
|
48
|
+
SUPPORTED_BUILD_FILE_NAMES.include?(f.name)
|
|
49
|
+
end
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
def update_buildfiles_for_dependency(buildfiles:, dependency:)
|
|
@@ -131,7 +139,8 @@ module Dependabot
|
|
|
131
139
|
next false unless line.include?(dependency.name.split(":").first)
|
|
132
140
|
next false unless line.include?(dependency.name.split(":").last)
|
|
133
141
|
else
|
|
134
|
-
|
|
142
|
+
name_regex_value = /['"]#{Regexp.quote(dependency.name)}['"]/
|
|
143
|
+
name_regex = /id(\s+#{name_regex_value}|\(#{name_regex_value}\))/
|
|
135
144
|
next false unless line.match?(name_regex)
|
|
136
145
|
end
|
|
137
146
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-gradle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.127.
|
|
4
|
+
version: 0.127.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - '='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.127.
|
|
19
|
+
version: 0.127.1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - '='
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.127.
|
|
26
|
+
version: 0.127.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: byebug
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|