workarea-upgrade 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +327 -0
- data/CHANGELOG.md +285 -0
- data/Gemfile +17 -0
- data/README.md +210 -0
- data/Rakefile +30 -0
- data/bin/rails +18 -0
- data/exe/workarea_upgrade +7 -0
- data/lib/workarea/upgrade.rb +26 -0
- data/lib/workarea/upgrade/cli.rb +289 -0
- data/lib/workarea/upgrade/diff.rb +87 -0
- data/lib/workarea/upgrade/diff/current_app.rb +15 -0
- data/lib/workarea/upgrade/diff/gem_diff.rb +99 -0
- data/lib/workarea/upgrade/diff/workarea_file.rb +43 -0
- data/lib/workarea/upgrade/engine.rb +12 -0
- data/lib/workarea/upgrade/gemfile.rb +102 -0
- data/lib/workarea/upgrade/report.rb +176 -0
- data/lib/workarea/upgrade/report_card.rb +94 -0
- data/lib/workarea/upgrade/version.rb +5 -0
- data/workarea-upgrade.gemspec +25 -0
- metadata +112 -0
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'date'
|
8
|
+
require 'tempfile'
|
9
|
+
|
10
|
+
load 'workarea/changelog.rake'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
13
|
+
require 'workarea/upgrade/version'
|
14
|
+
|
15
|
+
desc "Release version #{Workarea::Upgrade::VERSION} of the gem"
|
16
|
+
task :release do
|
17
|
+
host = "https://#{ENV['BUNDLE_GEMS__WEBLINC__COM']}@gems.weblinc.com"
|
18
|
+
|
19
|
+
Rake::Task['workarea:changelog'].execute
|
20
|
+
system 'git add CHANGELOG.md'
|
21
|
+
system 'git commit -m "Update CHANGELOG"'
|
22
|
+
|
23
|
+
system "git tag -a v#{Workarea::Upgrade::VERSION} -m 'Tagging #{Workarea::Upgrade::VERSION}'"
|
24
|
+
system 'git push origin HEAD --follow-tags'
|
25
|
+
|
26
|
+
system "gem build workarea-upgrade.gemspec"
|
27
|
+
system "gem push workarea-upgrade-#{Workarea::Upgrade::VERSION}.gem #{host}"
|
28
|
+
system "gem push workarea-upgrade-#{Workarea::Upgrade::VERSION}.gem --host #{host}"
|
29
|
+
system "rm workarea-upgrade-#{Workarea::Upgrade::VERSION}.gem"
|
30
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
6
|
+
ENGINE_PATH = File.expand_path('../../lib/workarea/upgrade/engine', __FILE__)
|
7
|
+
|
8
|
+
# Set up gems listed in the Gemfile.
|
9
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
10
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
11
|
+
|
12
|
+
require "action_controller/railtie"
|
13
|
+
require "action_view/railtie"
|
14
|
+
require "action_mailer/railtie"
|
15
|
+
require "rails/test_unit/railtie"
|
16
|
+
require "sprockets/railtie"
|
17
|
+
|
18
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
|
3
|
+
require 'workarea'
|
4
|
+
require 'workarea/storefront'
|
5
|
+
require 'workarea/admin'
|
6
|
+
|
7
|
+
require 'thor'
|
8
|
+
require 'diffy'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'bundler'
|
11
|
+
require 'rake'
|
12
|
+
|
13
|
+
require 'workarea/upgrade/engine'
|
14
|
+
|
15
|
+
module Workarea
|
16
|
+
module Upgrade
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'workarea/upgrade/diff'
|
21
|
+
require 'workarea/upgrade/diff/gem_diff'
|
22
|
+
require 'workarea/upgrade/diff/workarea_file'
|
23
|
+
require 'workarea/upgrade/diff/current_app'
|
24
|
+
|
25
|
+
require 'workarea/upgrade/gemfile'
|
26
|
+
require 'workarea/upgrade/report'
|
@@ -0,0 +1,289 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Upgrade
|
3
|
+
class CLI < Thor
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
def self.source_root
|
7
|
+
Dir.pwd
|
8
|
+
end
|
9
|
+
|
10
|
+
default_task :prepare
|
11
|
+
|
12
|
+
desc 'prepare', 'Create a Gemfile.next'
|
13
|
+
long_desc <<~LONG_DESC
|
14
|
+
This plugin uses a special file, that must be present in your
|
15
|
+
application's root directory, called Gemfile.next. This file is like
|
16
|
+
a regular Gemfile but it contains a list of only the Workarea gems you
|
17
|
+
wish to upgrade your application to.
|
18
|
+
|
19
|
+
You can craft an artisanal Gemfile.next file yourself or use this
|
20
|
+
command to walk you through the creation process. If you choose to
|
21
|
+
handcraft your own bespoke Gemfile.next you can immediately use any of
|
22
|
+
the other commands offered, such as "report" or "diff".
|
23
|
+
|
24
|
+
If you want to walk through each of the versions available to you and
|
25
|
+
customize which to include you can use this "prepare" command to
|
26
|
+
generate or regenerate a Gemfile.next file.
|
27
|
+
LONG_DESC
|
28
|
+
option :latest,
|
29
|
+
aliases: :l, type: :boolean,
|
30
|
+
desc: 'Just use the latest Workarea gems for the upgrade'
|
31
|
+
def prepare
|
32
|
+
if gemfile_next.exist?
|
33
|
+
say "\nGemfile.next already exists in #{Dir.pwd}.", :green
|
34
|
+
|
35
|
+
if ask("\nWould you like to regenerate the file? [Yn]").casecmp?('n')
|
36
|
+
say "\nLooks like you're ready to upgrade!", :green
|
37
|
+
say 'Try running another command, like "diff" or "report":'
|
38
|
+
puts
|
39
|
+
invoke :help, [], {}
|
40
|
+
exit(0)
|
41
|
+
else
|
42
|
+
remove_file 'Gemfile.next'
|
43
|
+
remove_file 'Gemfile.next.lock'
|
44
|
+
invoke :prepare, [], {}
|
45
|
+
end
|
46
|
+
elsif gemfile_next.lockfile_exist?
|
47
|
+
remove_file 'Gemfile.next.lock'
|
48
|
+
end
|
49
|
+
|
50
|
+
say "\nPlease be patient; we're hacking The Gibson...", :yellow
|
51
|
+
|
52
|
+
unless gemfile.outdated.any?
|
53
|
+
say "\nYour application is already up to date!", :green
|
54
|
+
exit(0)
|
55
|
+
end
|
56
|
+
|
57
|
+
say "\nAvailable updates:", :yellow
|
58
|
+
gemfile.outdated.each { |g| say(" * #{g.first} (#{g.last})") }
|
59
|
+
|
60
|
+
chosen_gems = options[:latest] ? gemfile.outdated : choose_gems
|
61
|
+
|
62
|
+
copy_file 'Gemfile', 'Gemfile.next'
|
63
|
+
|
64
|
+
chosen_gems.each do |gem|
|
65
|
+
current_version = gemfile.installed.to_h[gem.first]
|
66
|
+
gsub_file 'Gemfile.next',
|
67
|
+
/#{gem.first}(['"].*)#{current_version}/,
|
68
|
+
"#{gem.first}\\1#{gem.last}"
|
69
|
+
end
|
70
|
+
|
71
|
+
if gemfile_next.check_install
|
72
|
+
invoke :report, [], {}
|
73
|
+
else
|
74
|
+
say "\nOh noes! Your Gemfile.next failed to install!", :red
|
75
|
+
|
76
|
+
puts
|
77
|
+
say <<~MESSAGE
|
78
|
+
This usually happens when you try to upgrade your project to a new
|
79
|
+
minor version. Workarea may be depending on different versions of
|
80
|
+
gems than you currently have listed in your Gemfile.
|
81
|
+
|
82
|
+
All this means is that we'll need a bit of human intervention for
|
83
|
+
this next part.
|
84
|
+
|
85
|
+
What you should do is manually edit the Gemfile.next that we've just
|
86
|
+
created in your project. After you've made some edits you can test
|
87
|
+
the Gemfile.next by running:
|
88
|
+
|
89
|
+
$ bundle install --gemfile Gemfile.next
|
90
|
+
|
91
|
+
Once you've resolved the dependency issues in your Gemfile.next you
|
92
|
+
can pick up where you left off by running:
|
93
|
+
|
94
|
+
$ bundle exec workarea_upgrade report
|
95
|
+
MESSAGE
|
96
|
+
|
97
|
+
say "\nGood luck!", :green
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'report', 'Display an overview of the complexity of the upgrade'
|
102
|
+
def report
|
103
|
+
prepared?
|
104
|
+
|
105
|
+
gems_to_ignore = Gemfile.diff(gemfile, gemfile_next).to_h.keys
|
106
|
+
|
107
|
+
diff = Diff.new(
|
108
|
+
gemfile_next.workarea_version,
|
109
|
+
options.merge(plugins: gemfile_next.plugins(gems_to_ignore).to_h)
|
110
|
+
)
|
111
|
+
|
112
|
+
report = Report.new(diff)
|
113
|
+
|
114
|
+
puts
|
115
|
+
puts '###############'
|
116
|
+
say 'Diff Statistics', :green
|
117
|
+
puts '###############'
|
118
|
+
|
119
|
+
display_report(report.diff_stats)
|
120
|
+
|
121
|
+
puts
|
122
|
+
puts '###############'
|
123
|
+
say ' Report Card', :green
|
124
|
+
puts '###############'
|
125
|
+
|
126
|
+
display_report(report.report_card_stats)
|
127
|
+
|
128
|
+
puts
|
129
|
+
puts '###############'
|
130
|
+
say ' Breakdown', :green
|
131
|
+
puts '###############'
|
132
|
+
|
133
|
+
display_report(report.breakdown_customized_stats)
|
134
|
+
display_report(report.breakdown_worst_files_stats)
|
135
|
+
|
136
|
+
puts
|
137
|
+
puts '###############'
|
138
|
+
say ' Next Steps', :green
|
139
|
+
puts '###############'
|
140
|
+
|
141
|
+
puts
|
142
|
+
puts "* View a full diff of all files that will be impacted by this upgrade:"
|
143
|
+
puts " $ bundle exec workarea_upgrade diff"
|
144
|
+
|
145
|
+
puts
|
146
|
+
puts "* Replace your Gemfile and Gemfile.lock with the new versions:"
|
147
|
+
puts " $ mv Gemfile.next Gemfile"
|
148
|
+
puts " $ mv Gemfile.next.lock Gemfile.lock"
|
149
|
+
|
150
|
+
puts
|
151
|
+
puts "* Compare release notes between your version and #{gemfile_next.workarea_version}:"
|
152
|
+
puts " https://developer.workarea.com/release-notes.html"
|
153
|
+
|
154
|
+
puts
|
155
|
+
puts "* If you're upgrading to a new minor be sure to read the appropriate Upgrade Guide:"
|
156
|
+
puts " https://developer.workarea.com/upgrade-guides.html"
|
157
|
+
end
|
158
|
+
|
159
|
+
desc 'diff', 'Output a diff of changes that will affect your project'
|
160
|
+
long_desc <<~LONG_DESC
|
161
|
+
The default diff displayed will be based on changes made to the Workarea
|
162
|
+
platform that will have an impact on the overridden or decorated files
|
163
|
+
found in your project.
|
164
|
+
|
165
|
+
It's purpose is to allow you to see what has changed in the underlying
|
166
|
+
platform and to make decisions based on whether or not a given change
|
167
|
+
should be incorporated into your app.
|
168
|
+
|
169
|
+
To see a full log of change between versions, not just the changes that
|
170
|
+
may or may not be relevant to your specific application, pass the
|
171
|
+
`--full` option to this command.
|
172
|
+
LONG_DESC
|
173
|
+
option :format,
|
174
|
+
aliases: :f,
|
175
|
+
type: :string,
|
176
|
+
default: 'color',
|
177
|
+
enum: %w[color html]
|
178
|
+
option :context,
|
179
|
+
alias: :c,
|
180
|
+
type: :numeric,
|
181
|
+
desc: 'The number of lines displayed around each change in the diff'
|
182
|
+
option :full,
|
183
|
+
type: :boolean,
|
184
|
+
desc: 'Display every change to Workarea, not just the impactful ones'
|
185
|
+
option :added,
|
186
|
+
type: :boolean,
|
187
|
+
desc: 'View a list of files that were added to Workarea'
|
188
|
+
option :removed,
|
189
|
+
type: :boolean,
|
190
|
+
desc: 'View a list of files that were removed from Workarea'
|
191
|
+
def diff
|
192
|
+
prepared?
|
193
|
+
|
194
|
+
gems_to_ignore = Gemfile.diff(gemfile, gemfile_next).to_h.keys
|
195
|
+
|
196
|
+
diff = Diff.new(
|
197
|
+
gemfile_next.workarea_version,
|
198
|
+
options.merge(plugins: gemfile_next.plugins(gems_to_ignore).to_h)
|
199
|
+
)
|
200
|
+
|
201
|
+
if options[:added]
|
202
|
+
puts diff.added.join("\n")
|
203
|
+
exit(0)
|
204
|
+
end
|
205
|
+
|
206
|
+
if options[:removed]
|
207
|
+
puts diff.removed.join("\n")
|
208
|
+
exit(0)
|
209
|
+
end
|
210
|
+
|
211
|
+
if options[:full]
|
212
|
+
handle_diff_output(diff.all.join, options[:format])
|
213
|
+
else
|
214
|
+
handle_diff_output(diff.for_current_app.join, options[:format])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
def gemfile
|
221
|
+
@gemfile ||= Gemfile.new
|
222
|
+
end
|
223
|
+
|
224
|
+
def gemfile_next
|
225
|
+
@gemfile_next ||= Gemfile.new('Gemfile.next')
|
226
|
+
end
|
227
|
+
|
228
|
+
def prepared?
|
229
|
+
unless gemfile_next.exist?
|
230
|
+
say "\nGemfile.next was not found in #{Dir.pwd}", :red
|
231
|
+
say 'Preparing your application for upgrade...'
|
232
|
+
invoke :prepare, [], {}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def choose_gems
|
237
|
+
done = 'n'
|
238
|
+
|
239
|
+
while done.casecmp?('n')
|
240
|
+
say "\nYou can [C]ontinue, [s]kip, or enter a new version number:"
|
241
|
+
|
242
|
+
gems = gemfile.outdated.each_with_object([]) do |gem, memo|
|
243
|
+
choice = ask(" * #{gem.first} (#{gem.last})", :yellow)
|
244
|
+
|
245
|
+
next if choice.casecmp?('s')
|
246
|
+
|
247
|
+
if choice.casecmp?('c') || choice.empty?
|
248
|
+
memo << gem
|
249
|
+
else
|
250
|
+
memo << [gem.first, choice]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
if gems.nil?
|
255
|
+
say('You must choose at least one gem to upgrade.', :red)
|
256
|
+
else
|
257
|
+
say("\nHere's what you chose:")
|
258
|
+
gems.each { |gem| say(" * #{gem.first} (#{gem.last})", :green) }
|
259
|
+
|
260
|
+
done = ask("\nWrite these gems to the Gemfile.next? [Ynq]")
|
261
|
+
exit(0) if done.casecmp?('q')
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
gems
|
266
|
+
end
|
267
|
+
|
268
|
+
def handle_diff_output(result, format)
|
269
|
+
if format.to_s == 'html'
|
270
|
+
puts <<-eos
|
271
|
+
<!doctype html>
|
272
|
+
<html>
|
273
|
+
<head><style>#{Diff::CSS}</style></head>
|
274
|
+
<body>#{result}</body>
|
275
|
+
</html>
|
276
|
+
eos
|
277
|
+
else
|
278
|
+
puts result
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def display_report(stats)
|
283
|
+
stats.each do |stat|
|
284
|
+
say_status stat[:status], stat[:message], stat[:color]
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Upgrade
|
3
|
+
class Diff
|
4
|
+
CSS = <<-STYLE
|
5
|
+
.diff{overflow:auto;}
|
6
|
+
.diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;}
|
7
|
+
.diff del, .diff ins{display:block;text-decoration:none;}
|
8
|
+
.diff li{padding:0; display:table-row;margin: 0;height:1em;}
|
9
|
+
.diff li.ins{background:#dfd; color:#080}
|
10
|
+
.diff li.del{background:#fee; color:#b00}
|
11
|
+
.diff li:hover{background:#ffc}
|
12
|
+
/* try 'whitespace:pre;' if you don't want lines to wrap */
|
13
|
+
.diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;}
|
14
|
+
.diff del strong{font-weight:normal;background:#fcc;}
|
15
|
+
.diff ins strong{font-weight:normal;background:#9f9;}
|
16
|
+
.diff li.diff-comment { background: none repeat scroll 0 0 gray; }
|
17
|
+
.diff li.diff-block-info { background: none repeat scroll 0 0 gray; }
|
18
|
+
STYLE
|
19
|
+
|
20
|
+
def initialize(core_to_version, options)
|
21
|
+
@core_to_version = core_to_version
|
22
|
+
@options = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def plugins
|
26
|
+
@options[:plugins].presence || {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def gem_diffs
|
30
|
+
@gem_diffs ||= gems.map do |gem, to_version|
|
31
|
+
from_path = find_from_path!(gem)
|
32
|
+
to_path = find_to_path!(gem, to_version)
|
33
|
+
|
34
|
+
GemDiff.new(
|
35
|
+
from_path,
|
36
|
+
to_path,
|
37
|
+
@options
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
%w(
|
43
|
+
all
|
44
|
+
for_current_app
|
45
|
+
added
|
46
|
+
removed
|
47
|
+
overridden
|
48
|
+
decorated
|
49
|
+
customized_files
|
50
|
+
).each do |method|
|
51
|
+
define_method method do
|
52
|
+
gem_diffs.map(&method.to_sym).reduce(&:+)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def gems
|
57
|
+
%w(workarea-core workarea-storefront workarea-admin)
|
58
|
+
.each_with_object({}) { |gem, memo| memo[gem] = @core_to_version }
|
59
|
+
.merge(plugins)
|
60
|
+
.select { |gem, _version| find_from_path!(gem).present? }
|
61
|
+
end
|
62
|
+
|
63
|
+
def find_from_path!(gem)
|
64
|
+
Bundler.load.specs.find { |s| s.name == "#{gem}" }&.full_gem_path
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_to_path!(gem, version)
|
68
|
+
unless version.to_s =~ /^(\d+\.)(\d+\.)(\d+)/
|
69
|
+
raise "#{version} is not a valid version number. Example format: 3.0.5"
|
70
|
+
end
|
71
|
+
|
72
|
+
result = "#{Gem.dir}/gems/#{gem}-#{version}"
|
73
|
+
|
74
|
+
if !File.directory?(result)
|
75
|
+
raise <<-eos.strip_heredoc
|
76
|
+
|
77
|
+
Couldn't find #{gem} v#{version} in installed gems!
|
78
|
+
Looked in #{result}
|
79
|
+
Try `gem install #{gem} -v #{version}`.
|
80
|
+
eos
|
81
|
+
end
|
82
|
+
|
83
|
+
result
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|