workarea-upgrade 3.0.2
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 +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
|