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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cb75bc7f573b543ca6491b72f0289b4f107b93b8
4
- data.tar.gz: ede4f3a2877aee2dbb3d0034b6b99d3b570b0cc4
2
+ SHA256:
3
+ metadata.gz: c7429e7b5f2fa9af11ad43a9a4bd33f98758b78d38f83959d7723627fd1c2c9d
4
+ data.tar.gz: 41924ff861590eb505a50d97591ba8bee373de73aeffbd3d188f0094f278942c
5
5
  SHA512:
6
- metadata.gz: 0d98fba5b66b37ad5ba174f234ae2670c5908687c97db16339a61364a8b3ab343dfb698d90b25c9d75a8e5faec2d7eeab1fcea9045ee716b6b85c24ff9ca9625
7
- data.tar.gz: 1c230f4d09bd81f2fb89e346f32304b05c26be4a4c715a8d93e5d7b83135156ef3ec5cfce648805fc6c1bab91409d4eb91ae5b8b95bca8a0b1ce5c9c0ac41f6c
6
+ metadata.gz: 4fa4b901671e421a656c5992a1e756027ea281f2459f6d061f2ea90ac1c6009820a97f6b85b4854874137e83375599f0eda58d550d96c6861d385b3f28d31009
7
+ data.tar.gz: 7bdc9d37144c0b9fac45c5ff9a0a1d301d9a40d13cbfb6d0b94a3fd2bfdf51c1df1cd66104685b25371b0a4bba942a695a6ef334f1b261ff9cd73fa5472d8077
data/.gitignore CHANGED
@@ -7,5 +7,9 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ .byebug_history
11
+
10
12
  # rspec failure tracking
11
13
  .rspec_status
14
+
15
+ .ruby-version
@@ -1,5 +1,6 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
+ - 2.2.10
4
5
  - 2.3.3
5
6
  before_install: gem install bundler -v 1.16.1
@@ -1,78 +1,62 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ten_years_rails (0.1.0)
5
- actionview
6
- activesupport
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.0)
14
- activesupport (= 5.2.0)
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.0)
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
- colorize (0.8.1)
26
- concurrent-ruby (1.0.5)
27
- crass (1.0.4)
23
+ concurrent-ruby (1.1.5)
24
+ crass (1.0.5)
28
25
  diff-lcs (1.3)
29
- domain_name (0.5.20180417)
30
- unf (>= 0.0.5, < 1.0.0)
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.2.2)
29
+ loofah (2.4.0)
37
30
  crass (~> 1.0.2)
38
31
  nokogiri (>= 1.5.9)
39
- mime-types (3.1)
40
- mime-types-data (~> 3.2015)
41
- mime-types-data (3.2016.0521)
42
- mini_portile2 (2.3.0)
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.4)
51
- loofah (~> 2.2, >= 2.2.2)
52
- rake (10.4.2)
53
- rest-client (2.0.2)
54
- http-cookie (>= 1.0.2, < 2.0)
55
- mime-types (>= 1.16, < 4.0)
56
- netrc (~> 0.8)
57
- rspec (3.7.0)
58
- rspec-core (~> 3.7.0)
59
- rspec-expectations (~> 3.7.0)
60
- rspec-mocks (~> 3.7.0)
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.7.0)
66
- rspec-mocks (3.7.0)
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.7.0)
69
- rspec-support (3.7.1)
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.16.1
72
+ 1.17.2
@@ -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 = <<~EOS
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
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "json"
3
- require "colorize"
3
+ require "rainbow"
4
4
  require "optparse"
5
5
  require "set"
6
6
 
7
- def run_tests(deprecation_warnings, tracker_mode:, next_mode:)
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, verbose: false)
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 = <<~MESSAGE
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
@@ -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
 
@@ -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
- def self.track_rspec(rspec_config, shitlist_path:, mode:, transform_message: nil)
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
- ActiveSupport::Deprecation.behavior << -> (message, _callstack) { deprecation_tracker.add(message) }
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 = <<~MESSAGE.red
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&.delete
135
+ new_shitlist.delete if new_shitlist
122
136
  end
123
137
 
124
138
  def create_temp_shitlist
@@ -1,4 +1,6 @@
1
+ require "ten_years_rails/gem_info"
1
2
  require "ten_years_rails/version"
3
+ require "ten_years_rails/bundle_report"
2
4
  require "deprecation_tracker"
3
5
 
4
6
  module TenYearsRails
@@ -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
@@ -1,3 +1,3 @@
1
1
  module TenYearsRails
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -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 "actionview"
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.2.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: 2018-10-21 00:00:00.000000000 Z
12
+ date: 2019-12-13 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: actionview
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: '0'
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: '0'
27
+ version: 3.0.0
41
28
  - !ruby/object:Gem::Dependency
42
- name: colorize
29
+ name: bundler
43
30
  requirement: !ruby/object:Gem::Requirement
44
31
  requirements:
45
- - - ">="
32
+ - - "~>"
46
33
  - !ruby/object:Gem::Version
47
- version: 0.8.1
48
- type: :runtime
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: 0.8.1
41
+ version: '1.16'
55
42
  - !ruby/object:Gem::Dependency
56
- name: rest-client
43
+ name: rake
57
44
  requirement: !ruby/object:Gem::Requirement
58
45
  requirements:
59
- - - ">="
46
+ - - "~>"
60
47
  - !ruby/object:Gem::Version
61
- version: 2.0.2
62
- type: :runtime
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: 2.0.2
55
+ version: '10.0'
69
56
  - !ruby/object:Gem::Dependency
70
- name: bundler
57
+ name: rspec
71
58
  requirement: !ruby/object:Gem::Requirement
72
59
  requirements:
73
60
  - - "~>"
74
61
  - !ruby/object:Gem::Version
75
- version: '1.16'
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: '1.16'
69
+ version: '3.0'
83
70
  - !ruby/object:Gem::Dependency
84
- name: rake
71
+ name: timecop
85
72
  requirement: !ruby/object:Gem::Requirement
86
73
  requirements:
87
74
  - - "~>"
88
75
  - !ruby/object:Gem::Version
89
- version: '10.0'
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: '10.0'
83
+ version: 0.9.1
97
84
  - !ruby/object:Gem::Dependency
98
- name: rspec
85
+ name: actionview
99
86
  requirement: !ruby/object:Gem::Requirement
100
87
  requirements:
101
88
  - - "~>"
102
89
  - !ruby/object:Gem::Version
103
- version: '3.0'
104
- type: :development
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: '3.0'
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: '0'
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.6.14
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