ten_years_rails 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.travis.yml +1 -0
- data/Gemfile.lock +33 -48
- data/exe/bundle_report +5 -209
- data/exe/deprecations +11 -8
- data/exe/next.sh +13 -1
- data/lib/deprecation_tracker.rb +19 -5
- data/lib/ten_years_rails.rb +2 -0
- data/lib/ten_years_rails/bundle_report.rb +82 -0
- data/lib/ten_years_rails/gem_info.rb +129 -0
- data/lib/ten_years_rails/version.rb +1 -1
- data/ten_years_rails.gemspec +8 -6
- metadata +37 -46
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c7429e7b5f2fa9af11ad43a9a4bd33f98758b78d38f83959d7723627fd1c2c9d
|
|
4
|
+
data.tar.gz: 41924ff861590eb505a50d97591ba8bee373de73aeffbd3d188f0094f278942c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fa4b901671e421a656c5992a1e756027ea281f2459f6d061f2ea90ac1c6009820a97f6b85b4854874137e83375599f0eda58d550d96c6861d385b3f28d31009
|
|
7
|
+
data.tar.gz: 7bdc9d37144c0b9fac45c5ff9a0a1d301d9a40d13cbfb6d0b94a3fd2bfdf51c1df1cd66104685b25371b0a4bba942a695a6ef334f1b261ff9cd73fa5472d8077
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,78 +1,62 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
ten_years_rails (0.1
|
|
5
|
-
actionview
|
|
6
|
-
|
|
7
|
-
colorize (>= 0.8.1)
|
|
8
|
-
rest-client (>= 2.0.2)
|
|
4
|
+
ten_years_rails (1.0.1)
|
|
5
|
+
actionview (~> 5.2.3)
|
|
6
|
+
rainbow (~> 3.0.0)
|
|
9
7
|
|
|
10
8
|
GEM
|
|
11
9
|
remote: https://rubygems.org/
|
|
12
10
|
specs:
|
|
13
|
-
actionview (5.2.
|
|
14
|
-
activesupport (= 5.2.
|
|
11
|
+
actionview (5.2.4)
|
|
12
|
+
activesupport (= 5.2.4)
|
|
15
13
|
builder (~> 3.1)
|
|
16
14
|
erubi (~> 1.4)
|
|
17
15
|
rails-dom-testing (~> 2.0)
|
|
18
16
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
19
|
-
activesupport (5.2.
|
|
17
|
+
activesupport (5.2.4)
|
|
20
18
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
21
19
|
i18n (>= 0.7, < 2)
|
|
22
20
|
minitest (~> 5.1)
|
|
23
21
|
tzinfo (~> 1.1)
|
|
24
22
|
builder (3.2.3)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
crass (1.0.4)
|
|
23
|
+
concurrent-ruby (1.1.5)
|
|
24
|
+
crass (1.0.5)
|
|
28
25
|
diff-lcs (1.3)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
erubi (1.7.1)
|
|
32
|
-
http-cookie (1.0.3)
|
|
33
|
-
domain_name (~> 0.5)
|
|
34
|
-
i18n (1.0.1)
|
|
26
|
+
erubi (1.9.0)
|
|
27
|
+
i18n (1.7.0)
|
|
35
28
|
concurrent-ruby (~> 1.0)
|
|
36
|
-
loofah (2.
|
|
29
|
+
loofah (2.4.0)
|
|
37
30
|
crass (~> 1.0.2)
|
|
38
31
|
nokogiri (>= 1.5.9)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
minitest (5.11.3)
|
|
44
|
-
netrc (0.11.0)
|
|
45
|
-
nokogiri (1.8.2)
|
|
46
|
-
mini_portile2 (~> 2.3.0)
|
|
32
|
+
mini_portile2 (2.4.0)
|
|
33
|
+
minitest (5.13.0)
|
|
34
|
+
nokogiri (1.10.7)
|
|
35
|
+
mini_portile2 (~> 2.4.0)
|
|
47
36
|
rails-dom-testing (2.0.3)
|
|
48
37
|
activesupport (>= 4.2.0)
|
|
49
38
|
nokogiri (>= 1.6)
|
|
50
|
-
rails-html-sanitizer (1.0
|
|
51
|
-
loofah (~> 2.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
rspec-
|
|
60
|
-
|
|
61
|
-
rspec-core (3.7.1)
|
|
62
|
-
rspec-support (~> 3.7.0)
|
|
63
|
-
rspec-expectations (3.7.0)
|
|
39
|
+
rails-html-sanitizer (1.3.0)
|
|
40
|
+
loofah (~> 2.3)
|
|
41
|
+
rainbow (3.0.0)
|
|
42
|
+
rake (10.5.0)
|
|
43
|
+
rspec (3.8.0)
|
|
44
|
+
rspec-core (~> 3.8.0)
|
|
45
|
+
rspec-expectations (~> 3.8.0)
|
|
46
|
+
rspec-mocks (~> 3.8.0)
|
|
47
|
+
rspec-core (3.8.2)
|
|
48
|
+
rspec-support (~> 3.8.0)
|
|
49
|
+
rspec-expectations (3.8.4)
|
|
64
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
65
|
-
rspec-support (~> 3.
|
|
66
|
-
rspec-mocks (3.
|
|
51
|
+
rspec-support (~> 3.8.0)
|
|
52
|
+
rspec-mocks (3.8.1)
|
|
67
53
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
|
-
rspec-support (~> 3.
|
|
69
|
-
rspec-support (3.
|
|
54
|
+
rspec-support (~> 3.8.0)
|
|
55
|
+
rspec-support (3.8.2)
|
|
70
56
|
thread_safe (0.3.6)
|
|
57
|
+
timecop (0.9.1)
|
|
71
58
|
tzinfo (1.2.5)
|
|
72
59
|
thread_safe (~> 0.1)
|
|
73
|
-
unf (0.1.4)
|
|
74
|
-
unf_ext
|
|
75
|
-
unf_ext (0.0.7.5)
|
|
76
60
|
|
|
77
61
|
PLATFORMS
|
|
78
62
|
ruby
|
|
@@ -82,6 +66,7 @@ DEPENDENCIES
|
|
|
82
66
|
rake (~> 10.0)
|
|
83
67
|
rspec (~> 3.0)
|
|
84
68
|
ten_years_rails!
|
|
69
|
+
timecop (~> 0.9.1)
|
|
85
70
|
|
|
86
71
|
BUNDLED WITH
|
|
87
|
-
1.
|
|
72
|
+
1.17.2
|
data/exe/bundle_report
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
#
|
|
6
6
|
at_exit do
|
|
7
7
|
require "optparse"
|
|
8
|
+
require "ten_years_rails"
|
|
8
9
|
|
|
9
10
|
options = {}
|
|
10
11
|
option_parser = OptionParser.new do |opts|
|
|
11
|
-
opts.banner =
|
|
12
|
+
opts.banner = <<-EOS
|
|
12
13
|
Usage: #{$0} [report-type] [options]
|
|
13
14
|
|
|
14
15
|
report-type There are two report types available: `outdated` and `compatibility`
|
|
@@ -38,7 +39,7 @@ at_exit do
|
|
|
38
39
|
begin
|
|
39
40
|
option_parser.parse!
|
|
40
41
|
rescue OptionParser::ParseError => e
|
|
41
|
-
STDERR.puts e.message.red
|
|
42
|
+
STDERR.puts Rainbow(e.message).red
|
|
42
43
|
puts option_parser
|
|
43
44
|
exit 1
|
|
44
45
|
end
|
|
@@ -46,9 +47,9 @@ at_exit do
|
|
|
46
47
|
report_type = ARGV.first
|
|
47
48
|
|
|
48
49
|
case report_type
|
|
49
|
-
when "outdated" then BundleReport.outdated
|
|
50
|
+
when "outdated" then TenYearsRails::BundleReport.outdated
|
|
50
51
|
else
|
|
51
|
-
BundleReport.compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
|
|
52
|
+
TenYearsRails::BundleReport.compatibility(rails_version: options.fetch(:rails_version, "5.0"), include_rails_gems: options.fetch(:include_rails_gems, false))
|
|
52
53
|
end
|
|
53
54
|
end
|
|
54
55
|
|
|
@@ -57,208 +58,3 @@ require "bundler/setup"
|
|
|
57
58
|
|
|
58
59
|
require "action_view"
|
|
59
60
|
require "active_support/core_ext/object/acts_like"
|
|
60
|
-
require "colorize"
|
|
61
|
-
require "cgi"
|
|
62
|
-
require "erb"
|
|
63
|
-
require "json"
|
|
64
|
-
require "rest-client"
|
|
65
|
-
|
|
66
|
-
class BundleReport
|
|
67
|
-
def self.compatibility(rails_version:, include_rails_gems:)
|
|
68
|
-
incompatible_gems = BundleReport::GemInfo.all.reject do |gem|
|
|
69
|
-
gem.compatible_with_rails?(rails_version: rails_version) || (!include_rails_gems && gem.from_rails?)
|
|
70
|
-
end.sort_by do |gem|
|
|
71
|
-
[
|
|
72
|
-
gem.latest_version.compatible_with_rails?(rails_version: rails_version) ? 0 : 1,
|
|
73
|
-
gem.name
|
|
74
|
-
].join("-")
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
incompatible_gems_by_state = incompatible_gems.group_by { |gem| gem.state(rails_version) }
|
|
78
|
-
|
|
79
|
-
template = <<~ERB
|
|
80
|
-
<% if incompatible_gems_by_state[:latest_compatible] -%>
|
|
81
|
-
<%= "=> Incompatible with Rails #{rails_version} (with new versions that are compatible):".white.bold %>
|
|
82
|
-
<%= "These gems will need to be upgraded before upgrading to Rails #{rails_version}.".italic %>
|
|
83
|
-
|
|
84
|
-
<% incompatible_gems_by_state[:latest_compatible].each do |gem| -%>
|
|
85
|
-
<%= gem_header(gem) %> - upgrade to <%= gem.latest_version.version %>
|
|
86
|
-
<% end -%>
|
|
87
|
-
|
|
88
|
-
<% end -%>
|
|
89
|
-
<% if incompatible_gems_by_state[:incompatible] -%>
|
|
90
|
-
<%= "=> Incompatible with Rails #{rails_version} (with no new compatible versions):".white.bold %>
|
|
91
|
-
<%= "These gems will need to be removed or replaced before upgrading to Rails #{rails_version}.".italic %>
|
|
92
|
-
|
|
93
|
-
<% incompatible_gems_by_state[:incompatible].each do |gem| -%>
|
|
94
|
-
<%= gem_header(gem) %> - new version, <%= gem.latest_version.version %>, is not compatible with Rails #{rails_version}
|
|
95
|
-
<% end -%>
|
|
96
|
-
|
|
97
|
-
<% end -%>
|
|
98
|
-
<% if incompatible_gems_by_state[:no_new_version] -%>
|
|
99
|
-
<%= "=> Incompatible with Rails #{rails_version} (with no new versions):".white.bold %>
|
|
100
|
-
<%= "These gems will need to be upgraded by us or removed before upgrading to Rails #{rails_version}.".italic %>
|
|
101
|
-
<%= "This list is likely to contain internal gems, like Cuddlefish.".italic %>
|
|
102
|
-
|
|
103
|
-
<% incompatible_gems_by_state[:no_new_version].each do |gem| -%>
|
|
104
|
-
<%= gem_header(gem) %> - new version not found
|
|
105
|
-
<% end -%>
|
|
106
|
-
|
|
107
|
-
<% end -%>
|
|
108
|
-
<%= incompatible_gems.length.to_s.red %> gems incompatible with Rails <%= rails_version %>
|
|
109
|
-
ERB
|
|
110
|
-
|
|
111
|
-
puts ERB.new(template, nil, "-").result(binding)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def self.gem_header(_gem)
|
|
115
|
-
header = "#{_gem.name} #{_gem.version}".bold
|
|
116
|
-
header << " (loaded from git)".magenta if _gem.sourced_from_git?
|
|
117
|
-
header
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def self.outdated
|
|
121
|
-
gems = BundleReport::GemInfo.all
|
|
122
|
-
out_of_date_gems = gems.reject(&:up_to_date?).sort_by(&:created_at)
|
|
123
|
-
percentage_out_of_date = ((out_of_date_gems.count / gems.count.to_f) * 100).round
|
|
124
|
-
sourced_from_git = gems.select(&:sourced_from_git?)
|
|
125
|
-
|
|
126
|
-
out_of_date_gems.each do |_gem|
|
|
127
|
-
header = "#{_gem.name} #{_gem.version}"
|
|
128
|
-
|
|
129
|
-
puts <<~MESSAGE
|
|
130
|
-
#{header.bold.white}: released #{_gem.age} (latest version, #{_gem.latest_version.version}, released #{_gem.latest_version.age})
|
|
131
|
-
MESSAGE
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
puts ""
|
|
135
|
-
puts <<~MESSAGE
|
|
136
|
-
#{"#{sourced_from_git.count}".yellow} gems are sourced from git
|
|
137
|
-
#{"#{out_of_date_gems.length}".red} of the #{gems.count} gems are out-of-date (#{percentage_out_of_date}%)
|
|
138
|
-
MESSAGE
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
class GemInfo
|
|
142
|
-
include ActionView::Helpers::DateHelper
|
|
143
|
-
|
|
144
|
-
class NullGemInfo < GemInfo
|
|
145
|
-
def initialize; end
|
|
146
|
-
|
|
147
|
-
def age
|
|
148
|
-
"-"
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def time_to_latest_version
|
|
152
|
-
"-"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def created_at
|
|
156
|
-
Time.now
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def up_to_date?
|
|
160
|
-
false
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def version
|
|
164
|
-
"NOT FOUND"
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def unsatisfied_rails_dependencies(*)
|
|
168
|
-
["unknown"]
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def state(_)
|
|
172
|
-
:null
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def self.all
|
|
177
|
-
Gem::Specification.each.map do |gem_specification|
|
|
178
|
-
new(gem_specification)
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
attr_reader :gem_specification, :version, :name
|
|
183
|
-
def initialize(gem_specification)
|
|
184
|
-
@gem_specification = gem_specification
|
|
185
|
-
@version = gem_specification.version
|
|
186
|
-
@name = gem_specification.name
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def age
|
|
190
|
-
"#{time_ago_in_words(created_at)} ago"
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def sourced_from_git?
|
|
194
|
-
!!gem_specification.git_version
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def time_to_latest_version
|
|
198
|
-
distance_of_time_in_words(created_at, latest_version.created_at)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def created_at
|
|
202
|
-
@created_at ||= gem_specification.date
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
def up_to_date?
|
|
206
|
-
version == latest_version.version
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def state(rails_version)
|
|
210
|
-
if compatible_with_rails?(rails_version: rails_version)
|
|
211
|
-
:compatible
|
|
212
|
-
elsif latest_version.compatible_with_rails?(rails_version: rails_version)
|
|
213
|
-
:latest_compatible
|
|
214
|
-
elsif latest_version.version == "NOT FOUND"
|
|
215
|
-
:no_new_version
|
|
216
|
-
else
|
|
217
|
-
:incompatible
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def latest_version
|
|
222
|
-
@latest_version ||= begin
|
|
223
|
-
latest_gem_specification = Gem.latest_spec_for(name)
|
|
224
|
-
if latest_gem_specification
|
|
225
|
-
GemInfo.new(latest_gem_specification)
|
|
226
|
-
else
|
|
227
|
-
NullGemInfo.new
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
def compatible_with_rails?(rails_version: Gem::Version.new("5.0"))
|
|
233
|
-
unsatisfied_rails_dependencies(rails_version: rails_version).empty?
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def unsatisfied_rails_dependencies(rails_version:)
|
|
237
|
-
rails_dependencies = gem_specification.runtime_dependencies.select {|dependency| rails_gems.include?(dependency.name) }
|
|
238
|
-
|
|
239
|
-
rails_dependencies.reject do |rails_dependency|
|
|
240
|
-
rails_dependency.requirement.satisfied_by?(Gem::Version.new(rails_version))
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def from_rails?
|
|
245
|
-
rails_gems.include?(name)
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
private def rails_gems
|
|
249
|
-
[
|
|
250
|
-
"rails",
|
|
251
|
-
"activemodel",
|
|
252
|
-
"activerecord",
|
|
253
|
-
"actionmailer",
|
|
254
|
-
"actioncable",
|
|
255
|
-
"actionpack",
|
|
256
|
-
"actionview",
|
|
257
|
-
"activejob",
|
|
258
|
-
"activestorage",
|
|
259
|
-
"activesupport",
|
|
260
|
-
"railties",
|
|
261
|
-
]
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
end
|
data/exe/deprecations
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
require "json"
|
|
3
|
-
require "
|
|
3
|
+
require "rainbow"
|
|
4
4
|
require "optparse"
|
|
5
5
|
require "set"
|
|
6
6
|
|
|
7
|
-
def run_tests(deprecation_warnings,
|
|
7
|
+
def run_tests(deprecation_warnings, opts = {})
|
|
8
|
+
tracker_mode = opts[:tracker_mode]
|
|
9
|
+
next_mode = opts[:next_mode]
|
|
8
10
|
rspec_command = if next_mode
|
|
9
11
|
"bin/next rspec"
|
|
10
12
|
else
|
|
@@ -16,7 +18,8 @@ def run_tests(deprecation_warnings, tracker_mode:, next_mode:)
|
|
|
16
18
|
exec command
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def print_info(deprecation_warnings,
|
|
21
|
+
def print_info(deprecation_warnings, opts = {})
|
|
22
|
+
verbose = !!opts[:verbose]
|
|
20
23
|
frequency_by_message = deprecation_warnings.each_with_object({}) do |(test_file, messages), hash|
|
|
21
24
|
messages.each do |message|
|
|
22
25
|
hash[message] ||= { test_files: Set.new, occurrences: 0 }
|
|
@@ -27,16 +30,16 @@ def print_info(deprecation_warnings, verbose: false)
|
|
|
27
30
|
|
|
28
31
|
puts "Ten most common deprecation warnings:".underline
|
|
29
32
|
frequency_by_message.take(10).each do |message, data|
|
|
30
|
-
puts "Occurrences: #{data.fetch(:occurrences)}".bold
|
|
33
|
+
puts Rainbow("Occurrences: #{data.fetch(:occurrences)}").bold
|
|
31
34
|
puts "Test files: #{data.fetch(:test_files).to_a.join(" ")}" if verbose
|
|
32
|
-
puts message.red
|
|
35
|
+
puts Rainbow(message).red
|
|
33
36
|
puts "----------"
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
options = {}
|
|
38
41
|
option_parser = OptionParser.new do |opts|
|
|
39
|
-
opts.banner =
|
|
42
|
+
opts.banner = <<-MESSAGE
|
|
40
43
|
Usage: #{__FILE__.to_s} [options] [mode]
|
|
41
44
|
|
|
42
45
|
Parses the deprecation warning shitlist and show info or run tests.
|
|
@@ -101,10 +104,10 @@ case options.fetch(:mode, "info")
|
|
|
101
104
|
when "run" then run_tests(deprecation_warnings, next_mode: options[:next], tracker_mode: options[:tracker_mode])
|
|
102
105
|
when "info" then print_info(deprecation_warnings, verbose: options[:verbose])
|
|
103
106
|
when nil
|
|
104
|
-
STDERR.puts "Must pass a mode: run or info".red
|
|
107
|
+
STDERR.puts Rainbow("Must pass a mode: run or info").red
|
|
105
108
|
puts option_parser
|
|
106
109
|
exit 1
|
|
107
110
|
else
|
|
108
|
-
STDERR.puts "Unknown mode: #{options[:mode]}".red
|
|
111
|
+
STDERR.puts Rainbow("Unknown mode: #{options[:mode]}").red
|
|
109
112
|
exit 1
|
|
110
113
|
end
|
data/exe/next.sh
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
if [[ "${@}" == "--init" ]]; then
|
|
3
|
-
echo "doing a thing"
|
|
4
3
|
# Add next? top of Gemfile
|
|
5
4
|
cat <<-STRING > Gemfile.tmp
|
|
6
5
|
def next?
|
|
@@ -11,6 +10,19 @@ STRING
|
|
|
11
10
|
mv Gemfile.tmp Gemfile
|
|
12
11
|
|
|
13
12
|
ln -s Gemfile Gemfile.next
|
|
13
|
+
echo <<-MESSAGE
|
|
14
|
+
Created Gemfile.next (a symlink to your Gemfile). Your Gemfile has been modified to support dual-booting!
|
|
15
|
+
|
|
16
|
+
There's just one more step: modify your Gemfile to use a newer version of Rails using the \`next?\` helper method.
|
|
17
|
+
|
|
18
|
+
For example, here's how to go from 5.2.3 to 6.0:
|
|
19
|
+
|
|
20
|
+
if next?
|
|
21
|
+
gem "rails", "6.0.0"
|
|
22
|
+
else
|
|
23
|
+
gem "rails", "5.2.3"
|
|
24
|
+
end
|
|
25
|
+
MESSAGE
|
|
14
26
|
exit $?
|
|
15
27
|
fi
|
|
16
28
|
|
data/lib/deprecation_tracker.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "rainbow"
|
|
1
2
|
require "json"
|
|
2
3
|
|
|
3
4
|
# A shitlist for deprecation warnings during test runs. It has two modes: "save" and "compare"
|
|
@@ -28,11 +29,24 @@ class DeprecationTracker
|
|
|
28
29
|
|
|
29
30
|
# There are two forms of the `warn` method: one for class Kernel and one for instances of Kernel (i.e., every Object)
|
|
30
31
|
Object.prepend(KernelWarnTracker)
|
|
31
|
-
Kernel.singleton_class.prepend(KernelWarnTracker)
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
# Ruby 2.2 and lower doesn't appear to allow overriding of Kernel.warn using `singleton_class.prepend`.
|
|
34
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
|
|
35
|
+
Kernel.singleton_class.prepend(KernelWarnTracker)
|
|
36
|
+
else
|
|
37
|
+
def Kernel.warn(*args, &block)
|
|
38
|
+
Object.warn(*args, &block)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.track_rspec(rspec_config, opts = {})
|
|
43
|
+
shitlist_path = opts[:shitlist_path]
|
|
44
|
+
mode = opts[:mode]
|
|
45
|
+
transform_message = opts[:transform_message]
|
|
34
46
|
deprecation_tracker = DeprecationTracker.new(shitlist_path, transform_message)
|
|
35
|
-
|
|
47
|
+
if defined?(ActiveSupport)
|
|
48
|
+
ActiveSupport::Deprecation.behavior << -> (message, _callstack, _deprecation_horizon, _gem_name) { deprecation_tracker.add(message) }
|
|
49
|
+
end
|
|
36
50
|
KernelWarnTracker.callbacks << -> (message) { deprecation_tracker.add(message) }
|
|
37
51
|
|
|
38
52
|
rspec_config.around do |example|
|
|
@@ -85,7 +99,7 @@ class DeprecationTracker
|
|
|
85
99
|
end
|
|
86
100
|
|
|
87
101
|
if changed_buckets.length > 0
|
|
88
|
-
message =
|
|
102
|
+
message = Rainbow(<<-MESSAGE).red
|
|
89
103
|
⚠️ Deprecation warnings have changed!
|
|
90
104
|
|
|
91
105
|
Code called by the following spec files is now generating different deprecation warnings:
|
|
@@ -118,7 +132,7 @@ class DeprecationTracker
|
|
|
118
132
|
new_shitlist = create_temp_shitlist
|
|
119
133
|
FileUtils.cp(new_shitlist.path, shitlist_path)
|
|
120
134
|
ensure
|
|
121
|
-
new_shitlist
|
|
135
|
+
new_shitlist.delete if new_shitlist
|
|
122
136
|
end
|
|
123
137
|
|
|
124
138
|
def create_temp_shitlist
|
data/lib/ten_years_rails.rb
CHANGED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require "rainbow"
|
|
2
|
+
require "cgi"
|
|
3
|
+
require "erb"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module TenYearsRails
|
|
7
|
+
class BundleReport
|
|
8
|
+
def self.compatibility(rails_version:, include_rails_gems:)
|
|
9
|
+
incompatible_gems = TenYearsRails::GemInfo.all.reject do |gem|
|
|
10
|
+
gem.compatible_with_rails?(rails_version: rails_version) || (!include_rails_gems && gem.from_rails?)
|
|
11
|
+
end.sort_by do |gem|
|
|
12
|
+
[
|
|
13
|
+
gem.latest_version.compatible_with_rails?(rails_version: rails_version) ? 0 : 1,
|
|
14
|
+
gem.name
|
|
15
|
+
].join("-")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
incompatible_gems_by_state = incompatible_gems.group_by { |gem| gem.state(rails_version) }
|
|
19
|
+
|
|
20
|
+
template = <<~ERB
|
|
21
|
+
<% if incompatible_gems_by_state[:latest_compatible] -%>
|
|
22
|
+
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with new versions that are compatible):").white.bold %>
|
|
23
|
+
<%= Rainbow("These gems will need to be upgraded before upgrading to Rails #{rails_version}.").italic %>
|
|
24
|
+
|
|
25
|
+
<% incompatible_gems_by_state[:latest_compatible].each do |gem| -%>
|
|
26
|
+
<%= gem_header(gem) %> - upgrade to <%= gem.latest_version.version %>
|
|
27
|
+
<% end -%>
|
|
28
|
+
|
|
29
|
+
<% end -%>
|
|
30
|
+
<% if incompatible_gems_by_state[:incompatible] -%>
|
|
31
|
+
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new compatible versions):").white.bold %>
|
|
32
|
+
<%= Rainbow("These gems will need to be removed or replaced before upgrading to Rails #{rails_version}.").italic %>
|
|
33
|
+
|
|
34
|
+
<% incompatible_gems_by_state[:incompatible].each do |gem| -%>
|
|
35
|
+
<%= gem_header(gem) %> - new version, <%= gem.latest_version.version %>, is not compatible with Rails #{rails_version}
|
|
36
|
+
<% end -%>
|
|
37
|
+
|
|
38
|
+
<% end -%>
|
|
39
|
+
<% if incompatible_gems_by_state[:no_new_version] -%>
|
|
40
|
+
<%= Rainbow("=> Incompatible with Rails #{rails_version} (with no new versions):").white.bold %>
|
|
41
|
+
<%= Rainbow("These gems will need to be upgraded by us or removed before upgrading to Rails #{rails_version}.").italic %>
|
|
42
|
+
<%= Rainbow("This list is likely to contain internal gems, like Cuddlefish.").italic %>
|
|
43
|
+
|
|
44
|
+
<% incompatible_gems_by_state[:no_new_version].each do |gem| -%>
|
|
45
|
+
<%= gem_header(gem) %> - new version not found
|
|
46
|
+
<% end -%>
|
|
47
|
+
|
|
48
|
+
<% end -%>
|
|
49
|
+
<%= Rainbow(incompatible_gems.length.to_s).red %> gems incompatible with Rails <%= rails_version %>
|
|
50
|
+
ERB
|
|
51
|
+
|
|
52
|
+
puts ERB.new(template, nil, "-").result(binding)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.gem_header(_gem)
|
|
56
|
+
header = "#{_gem.name} #{_gem.version}".bold
|
|
57
|
+
header << " (loaded from git)".magenta if _gem.sourced_from_git?
|
|
58
|
+
header
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.outdated
|
|
62
|
+
gems = TenYearsRails::GemInfo.all
|
|
63
|
+
out_of_date_gems = gems.reject(&:up_to_date?).sort_by(&:created_at)
|
|
64
|
+
percentage_out_of_date = ((out_of_date_gems.count / gems.count.to_f) * 100).round
|
|
65
|
+
sourced_from_git = gems.select(&:sourced_from_git?)
|
|
66
|
+
|
|
67
|
+
out_of_date_gems.each do |_gem|
|
|
68
|
+
header = "#{_gem.name} #{_gem.version}"
|
|
69
|
+
|
|
70
|
+
puts <<~MESSAGE
|
|
71
|
+
#{Rainbow(header).bold.white}: released #{_gem.age} (latest version, #{_gem.latest_version.version}, released #{_gem.latest_version.age})
|
|
72
|
+
MESSAGE
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
puts ""
|
|
76
|
+
puts <<~MESSAGE
|
|
77
|
+
#{Rainbow(sourced_from_git.count.to_s).yellow} gems are sourced from git
|
|
78
|
+
#{Rainbow(out_of_date_gems.length.to_s).red} of the #{gems.count} gems are out-of-date (#{percentage_out_of_date}%)
|
|
79
|
+
MESSAGE
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "action_view"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts "ActionView not available"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module TenYearsRails
|
|
8
|
+
class GemInfo
|
|
9
|
+
if defined?(ActionView)
|
|
10
|
+
include ActionView::Helpers::DateHelper
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class NullGemInfo < GemInfo
|
|
14
|
+
def initialize; end
|
|
15
|
+
|
|
16
|
+
def age
|
|
17
|
+
"-"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def created_at
|
|
21
|
+
Time.now
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def up_to_date?
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def version
|
|
29
|
+
"NOT FOUND"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def unsatisfied_rails_dependencies(*)
|
|
33
|
+
["unknown"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def state(_)
|
|
37
|
+
:null
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.all
|
|
42
|
+
Gem::Specification.each.map do |gem_specification|
|
|
43
|
+
new(gem_specification)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attr_reader :gem_specification, :version, :name
|
|
48
|
+
def initialize(gem_specification)
|
|
49
|
+
@gem_specification = gem_specification
|
|
50
|
+
@version = gem_specification.version
|
|
51
|
+
@name = gem_specification.name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def age
|
|
55
|
+
if respond_to?(:time_ago_in_words)
|
|
56
|
+
"#{time_ago_in_words(created_at)} ago"
|
|
57
|
+
else
|
|
58
|
+
created_at.strftime("%b %e, %Y")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def sourced_from_git?
|
|
63
|
+
!!gem_specification.git_version
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def created_at
|
|
67
|
+
@created_at ||= gem_specification.date
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def up_to_date?
|
|
71
|
+
version == latest_version.version
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def state(rails_version)
|
|
75
|
+
if compatible_with_rails?(rails_version: rails_version)
|
|
76
|
+
:compatible
|
|
77
|
+
elsif latest_version.compatible_with_rails?(rails_version: rails_version)
|
|
78
|
+
:latest_compatible
|
|
79
|
+
elsif latest_version.version == "NOT FOUND"
|
|
80
|
+
:no_new_version
|
|
81
|
+
else
|
|
82
|
+
:incompatible
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def latest_version
|
|
87
|
+
@latest_version ||= begin
|
|
88
|
+
latest_gem_specification = Gem.latest_spec_for(name)
|
|
89
|
+
if latest_gem_specification
|
|
90
|
+
GemInfo.new(latest_gem_specification)
|
|
91
|
+
else
|
|
92
|
+
NullGemInfo.new
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def compatible_with_rails?(rails_version: Gem::Version.new("5.0"))
|
|
98
|
+
unsatisfied_rails_dependencies(rails_version: rails_version).empty?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def unsatisfied_rails_dependencies(rails_version:)
|
|
102
|
+
rails_dependencies = gem_specification.runtime_dependencies.select {|dependency| rails_gems.include?(dependency.name) }
|
|
103
|
+
|
|
104
|
+
rails_dependencies.reject do |rails_dependency|
|
|
105
|
+
rails_dependency.requirement.satisfied_by?(Gem::Version.new(rails_version))
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def from_rails?
|
|
110
|
+
rails_gems.include?(name)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private def rails_gems
|
|
114
|
+
[
|
|
115
|
+
"rails",
|
|
116
|
+
"activemodel",
|
|
117
|
+
"activerecord",
|
|
118
|
+
"actionmailer",
|
|
119
|
+
"actioncable",
|
|
120
|
+
"actionpack",
|
|
121
|
+
"actionview",
|
|
122
|
+
"activejob",
|
|
123
|
+
"activestorage",
|
|
124
|
+
"activesupport",
|
|
125
|
+
"railties",
|
|
126
|
+
]
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
data/ten_years_rails.gemspec
CHANGED
|
@@ -6,13 +6,16 @@ require "ten_years_rails/version"
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "ten_years_rails"
|
|
8
8
|
spec.version = TenYearsRails::VERSION
|
|
9
|
-
spec.authors = ["Jordan Raine"]
|
|
10
|
-
spec.email = ["jnraine@gmail.com"]
|
|
9
|
+
spec.authors = ["Jordan Raine", "Ernesto Tagwerker"]
|
|
10
|
+
spec.email = ["jnraine@gmail.com", "ernesto@ombulabs.com"]
|
|
11
11
|
|
|
12
12
|
spec.summary = %q{Companion code to Ten Years of Rails Upgrades}
|
|
13
|
+
spec.description = %q{A set of handy tools to upgrade your Rails application and keep it up to date}
|
|
13
14
|
spec.homepage = "https://github.com/clio/ten_years_rails"
|
|
14
15
|
spec.license = "MIT"
|
|
15
16
|
|
|
17
|
+
spec.required_ruby_version = ">= 2.3.0"
|
|
18
|
+
|
|
16
19
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
17
20
|
f.match(%r{^(test|spec|features)/})
|
|
18
21
|
end
|
|
@@ -20,11 +23,10 @@ Gem::Specification.new do |spec|
|
|
|
20
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
24
|
spec.require_paths = ["lib"]
|
|
22
25
|
|
|
23
|
-
spec.add_dependency "
|
|
24
|
-
spec.add_dependency "activesupport"
|
|
25
|
-
spec.add_dependency "colorize", ">= 0.8.1"
|
|
26
|
-
spec.add_dependency "rest-client", ">= 2.0.2"
|
|
26
|
+
spec.add_dependency "rainbow", "~> 3.0.0"
|
|
27
27
|
spec.add_development_dependency "bundler", "~> 1.16"
|
|
28
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
29
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
30
|
+
spec.add_development_dependency "timecop", "~> 0.9.1"
|
|
31
|
+
spec.add_runtime_dependency "actionview", "~> 5.2.3"
|
|
30
32
|
end
|
metadata
CHANGED
|
@@ -1,116 +1,105 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ten_years_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jordan Raine
|
|
8
|
+
- Ernesto Tagwerker
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: exe
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2019-12-13 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
15
|
+
name: rainbow
|
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
|
16
17
|
requirements:
|
|
17
|
-
- - "
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: activesupport
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
18
|
+
- - "~>"
|
|
32
19
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
20
|
+
version: 3.0.0
|
|
34
21
|
type: :runtime
|
|
35
22
|
prerelease: false
|
|
36
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
24
|
requirements:
|
|
38
|
-
- - "
|
|
25
|
+
- - "~>"
|
|
39
26
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
27
|
+
version: 3.0.0
|
|
41
28
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
29
|
+
name: bundler
|
|
43
30
|
requirement: !ruby/object:Gem::Requirement
|
|
44
31
|
requirements:
|
|
45
|
-
- - "
|
|
32
|
+
- - "~>"
|
|
46
33
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
48
|
-
type: :
|
|
34
|
+
version: '1.16'
|
|
35
|
+
type: :development
|
|
49
36
|
prerelease: false
|
|
50
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
38
|
requirements:
|
|
52
|
-
- - "
|
|
39
|
+
- - "~>"
|
|
53
40
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
41
|
+
version: '1.16'
|
|
55
42
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
43
|
+
name: rake
|
|
57
44
|
requirement: !ruby/object:Gem::Requirement
|
|
58
45
|
requirements:
|
|
59
|
-
- - "
|
|
46
|
+
- - "~>"
|
|
60
47
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
62
|
-
type: :
|
|
48
|
+
version: '10.0'
|
|
49
|
+
type: :development
|
|
63
50
|
prerelease: false
|
|
64
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
52
|
requirements:
|
|
66
|
-
- - "
|
|
53
|
+
- - "~>"
|
|
67
54
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
55
|
+
version: '10.0'
|
|
69
56
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
57
|
+
name: rspec
|
|
71
58
|
requirement: !ruby/object:Gem::Requirement
|
|
72
59
|
requirements:
|
|
73
60
|
- - "~>"
|
|
74
61
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
62
|
+
version: '3.0'
|
|
76
63
|
type: :development
|
|
77
64
|
prerelease: false
|
|
78
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
66
|
requirements:
|
|
80
67
|
- - "~>"
|
|
81
68
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
69
|
+
version: '3.0'
|
|
83
70
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
71
|
+
name: timecop
|
|
85
72
|
requirement: !ruby/object:Gem::Requirement
|
|
86
73
|
requirements:
|
|
87
74
|
- - "~>"
|
|
88
75
|
- !ruby/object:Gem::Version
|
|
89
|
-
version:
|
|
76
|
+
version: 0.9.1
|
|
90
77
|
type: :development
|
|
91
78
|
prerelease: false
|
|
92
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
80
|
requirements:
|
|
94
81
|
- - "~>"
|
|
95
82
|
- !ruby/object:Gem::Version
|
|
96
|
-
version:
|
|
83
|
+
version: 0.9.1
|
|
97
84
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
85
|
+
name: actionview
|
|
99
86
|
requirement: !ruby/object:Gem::Requirement
|
|
100
87
|
requirements:
|
|
101
88
|
- - "~>"
|
|
102
89
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
104
|
-
type: :
|
|
90
|
+
version: 5.2.3
|
|
91
|
+
type: :runtime
|
|
105
92
|
prerelease: false
|
|
106
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
94
|
requirements:
|
|
108
95
|
- - "~>"
|
|
109
96
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
111
|
-
description:
|
|
97
|
+
version: 5.2.3
|
|
98
|
+
description: A set of handy tools to upgrade your Rails application and keep it up
|
|
99
|
+
to date
|
|
112
100
|
email:
|
|
113
101
|
- jnraine@gmail.com
|
|
102
|
+
- ernesto@ombulabs.com
|
|
114
103
|
executables:
|
|
115
104
|
- bundle_report
|
|
116
105
|
- deprecations
|
|
@@ -138,6 +127,8 @@ files:
|
|
|
138
127
|
- exe/next.sh
|
|
139
128
|
- lib/deprecation_tracker.rb
|
|
140
129
|
- lib/ten_years_rails.rb
|
|
130
|
+
- lib/ten_years_rails/bundle_report.rb
|
|
131
|
+
- lib/ten_years_rails/gem_info.rb
|
|
141
132
|
- lib/ten_years_rails/version.rb
|
|
142
133
|
- ten_years_rails.gemspec
|
|
143
134
|
homepage: https://github.com/clio/ten_years_rails
|
|
@@ -152,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
152
143
|
requirements:
|
|
153
144
|
- - ">="
|
|
154
145
|
- !ruby/object:Gem::Version
|
|
155
|
-
version:
|
|
146
|
+
version: 2.3.0
|
|
156
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
148
|
requirements:
|
|
158
149
|
- - ">="
|
|
@@ -160,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
160
151
|
version: '0'
|
|
161
152
|
requirements: []
|
|
162
153
|
rubyforge_project:
|
|
163
|
-
rubygems_version: 2.
|
|
154
|
+
rubygems_version: 2.7.9
|
|
164
155
|
signing_key:
|
|
165
156
|
specification_version: 4
|
|
166
157
|
summary: Companion code to Ten Years of Rails Upgrades
|