shopify-cli 2.29.0 → 2.30.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/lib/project_types/theme/commands/package.rb +20 -5
- data/lib/project_types/theme/messages/messages.rb +4 -2
- data/lib/shopify_cli/packager.rb +5 -14
- data/lib/shopify_cli/theme/backoff_helper.rb +47 -0
- data/lib/shopify_cli/theme/ignore_helper.rb +7 -1
- data/lib/shopify_cli/theme/syncer/downloader.rb +63 -0
- data/lib/shopify_cli/theme/syncer/uploader/bulk.rb +133 -0
- data/lib/shopify_cli/theme/syncer/uploader/bulk_item.rb +64 -0
- data/lib/shopify_cli/theme/syncer/uploader/bulk_job.rb +139 -0
- data/lib/shopify_cli/theme/syncer/uploader/bulk_request.rb +30 -0
- data/lib/shopify_cli/theme/syncer/uploader/forms/apply_to_all.rb +41 -0
- data/lib/shopify_cli/theme/syncer/uploader/forms/apply_to_all_form.rb +37 -0
- data/lib/shopify_cli/theme/syncer/uploader/forms/base_strategy_form.rb +64 -0
- data/lib/shopify_cli/theme/syncer/uploader/forms/select_delete_strategy.rb +29 -0
- data/lib/shopify_cli/theme/syncer/uploader/forms/select_update_strategy.rb +30 -0
- data/lib/shopify_cli/theme/syncer/uploader/json_delete_handler.rb +49 -0
- data/lib/shopify_cli/theme/syncer/uploader/json_update_handler.rb +71 -0
- data/lib/shopify_cli/theme/syncer/uploader.rb +227 -0
- data/lib/shopify_cli/theme/syncer.rb +91 -144
- data/lib/shopify_cli/version.rb +1 -1
- metadata +16 -16
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all.rb +0 -39
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all_form.rb +0 -35
- data/lib/shopify_cli/theme/syncer/forms/base_strategy_form.rb +0 -62
- data/lib/shopify_cli/theme/syncer/forms/select_delete_strategy.rb +0 -27
- data/lib/shopify_cli/theme/syncer/forms/select_update_strategy.rb +0 -28
- data/lib/shopify_cli/theme/syncer/json_delete_handler.rb +0 -51
- data/lib/shopify_cli/theme/syncer/json_update_handler.rb +0 -96
- data/lib/shopify_cli/theme/theme_admin_api_throttler/bulk.rb +0 -102
- data/lib/shopify_cli/theme/theme_admin_api_throttler/bulk_job.rb +0 -75
- data/lib/shopify_cli/theme/theme_admin_api_throttler/errors.rb +0 -7
- data/lib/shopify_cli/theme/theme_admin_api_throttler/put_request.rb +0 -52
- data/lib/shopify_cli/theme/theme_admin_api_throttler/request_parser.rb +0 -39
- data/lib/shopify_cli/theme/theme_admin_api_throttler/response_parser.rb +0 -21
- data/lib/shopify_cli/theme/theme_admin_api_throttler.rb +0 -62
@@ -5,17 +5,18 @@ require "json"
|
|
5
5
|
require "base64"
|
6
6
|
require "forwardable"
|
7
7
|
|
8
|
+
require_relative "backoff_helper"
|
9
|
+
require_relative "ignore_helper"
|
10
|
+
require_relative "theme_admin_api"
|
11
|
+
|
8
12
|
require_relative "syncer/checksums"
|
13
|
+
require_relative "syncer/downloader"
|
9
14
|
require_relative "syncer/error_reporter"
|
10
|
-
require_relative "syncer/json_delete_handler"
|
11
|
-
require_relative "syncer/json_update_handler"
|
12
15
|
require_relative "syncer/merger"
|
13
16
|
require_relative "syncer/operation"
|
14
17
|
require_relative "syncer/standard_reporter"
|
15
18
|
require_relative "syncer/unsupported_script_warning"
|
16
|
-
require_relative "
|
17
|
-
require_relative "ignore_helper"
|
18
|
-
require_relative "theme_admin_api_throttler"
|
19
|
+
require_relative "syncer/uploader"
|
19
20
|
|
20
21
|
module ShopifyCLI
|
21
22
|
module Theme
|
@@ -23,8 +24,7 @@ module ShopifyCLI
|
|
23
24
|
extend Forwardable
|
24
25
|
|
25
26
|
include ShopifyCLI::Theme::IgnoreHelper
|
26
|
-
include
|
27
|
-
include JsonUpdateHandler
|
27
|
+
include ShopifyCLI::Theme::BackoffHelper
|
28
28
|
|
29
29
|
QUEUEABLE_METHODS = [
|
30
30
|
:get, # - Updates the local file with the remote file content
|
@@ -33,7 +33,7 @@ module ShopifyCLI
|
|
33
33
|
:union_merge, # - Union merges the local file content with the remote file content
|
34
34
|
]
|
35
35
|
|
36
|
-
attr_reader :theme, :checksums, :error_checksums, :api_client
|
36
|
+
attr_reader :ctx, :theme, :checksums, :error_checksums, :api_client, :pending
|
37
37
|
attr_accessor :include_filter, :ignore_filter
|
38
38
|
|
39
39
|
def_delegators :@error_reporter, :has_any_error?
|
@@ -57,12 +57,6 @@ module ShopifyCLI
|
|
57
57
|
# Thread making the API requests.
|
58
58
|
@threads = []
|
59
59
|
|
60
|
-
# Mutex used to pause all threads when backing-off when hitting API rate limits
|
61
|
-
@backoff_mutex = Mutex.new
|
62
|
-
|
63
|
-
# Mutex used to coordinate changes in the `pending` list
|
64
|
-
@pending_mutex = Mutex.new
|
65
|
-
|
66
60
|
# Latest theme assets checksums. Updated on each upload.
|
67
61
|
@checksums = Checksums.new(theme)
|
68
62
|
|
@@ -71,14 +65,14 @@ module ShopifyCLI
|
|
71
65
|
|
72
66
|
# Do not use the throttler when --stable is passed or a Theme Access password is set
|
73
67
|
# (Theme Access API is not compatible yet with bulks)
|
74
|
-
|
68
|
+
@bulk_updates_activated = !stable && !Environment.theme_access_password?
|
75
69
|
|
76
70
|
# Initialize `api_client` on main thread
|
77
|
-
@api_client =
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
@api_client = ThemeAdminAPI.new(ctx, theme.shop)
|
72
|
+
|
73
|
+
# Initialize backoff helper on main thread to pause all threads when the
|
74
|
+
# requests are reaching API rate limits.
|
75
|
+
initialize_backoff_helper!
|
82
76
|
end
|
83
77
|
|
84
78
|
def lock_io!
|
@@ -146,7 +140,6 @@ module ShopifyCLI
|
|
146
140
|
end
|
147
141
|
|
148
142
|
def shutdown
|
149
|
-
api_client.shutdown
|
150
143
|
@queue.close unless @queue.closed?
|
151
144
|
ensure
|
152
145
|
@threads.each { |thread| thread.join if thread.alive? }
|
@@ -169,64 +162,70 @@ module ShopifyCLI
|
|
169
162
|
end
|
170
163
|
|
171
164
|
def upload_theme!(delay_low_priority_files: false, delete: true, &block)
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
removed_json_files, removed_files = checksums
|
176
|
-
.keys
|
177
|
-
.-(@theme.theme_files.map(&:relative_path))
|
178
|
-
.map { |file| @theme[file] }
|
179
|
-
.partition(&:json?)
|
165
|
+
uploader = Uploader.new(self, delete, delay_low_priority_files, &block)
|
166
|
+
uploader.upload!
|
167
|
+
end
|
180
168
|
|
181
|
-
|
182
|
-
|
183
|
-
|
169
|
+
def download_theme!(delete: true, &block)
|
170
|
+
downloader = Downloader.new(self, delete, &block)
|
171
|
+
downloader.download!
|
172
|
+
end
|
184
173
|
|
185
|
-
|
186
|
-
|
174
|
+
def bulk_updates_activated?
|
175
|
+
@bulk_updates_activated
|
176
|
+
end
|
187
177
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
end
|
178
|
+
def enqueueable?(operation)
|
179
|
+
file = operation.file
|
180
|
+
method = operation.method
|
192
181
|
|
193
|
-
#
|
182
|
+
# Already enqueued or ignored
|
183
|
+
return false if @pending.include?(operation) || ignore_operation?(operation)
|
194
184
|
|
195
|
-
|
196
|
-
|
185
|
+
if [:update, :get].include?(method) && file.exist?
|
186
|
+
# File is fixed (and it has been never updated)
|
187
|
+
if !!@error_checksums.delete(file.checksum)
|
188
|
+
@standard_reporter.report(operation.as_fix_message)
|
189
|
+
end
|
197
190
|
|
198
|
-
|
199
|
-
wait!(&block)
|
191
|
+
return checksums.file_has_changed?(file)
|
200
192
|
end
|
201
193
|
|
202
|
-
|
203
|
-
enqueue_delayed_files_updates
|
194
|
+
true
|
204
195
|
end
|
205
196
|
|
206
|
-
def
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
197
|
+
def handle_operation_error(operation, error)
|
198
|
+
error_suffix = ":\n " + parse_api_errors(operation, error).join("\n ")
|
199
|
+
report_error(operation, error_suffix)
|
200
|
+
end
|
201
|
+
|
202
|
+
def overwrite_json?
|
203
|
+
theme_created_at_runtime? || @overwrite_json
|
204
|
+
end
|
205
|
+
|
206
|
+
def update_checksums(api_response)
|
207
|
+
api_response.values.flatten.each do |asset|
|
208
|
+
next unless asset["key"]
|
209
|
+
checksums[asset["key"]] = asset["checksum"]
|
218
210
|
end
|
219
211
|
|
220
|
-
|
212
|
+
checksums.reject_duplicated_checksums!
|
213
|
+
end
|
214
|
+
|
215
|
+
def report_file_error(file, error_message = "")
|
216
|
+
path = file.relative_path
|
221
217
|
|
222
|
-
|
218
|
+
@error_checksums << checksums[path]
|
219
|
+
@error_reporter.report(error_message)
|
223
220
|
end
|
224
221
|
|
225
222
|
private
|
226
223
|
|
227
224
|
def report_error(operation, error_suffix = "")
|
228
|
-
|
229
|
-
|
225
|
+
file = operation.file
|
226
|
+
error_message = "#{operation.as_error_message}#{error_suffix}"
|
227
|
+
|
228
|
+
report_file_error(file, error_message)
|
230
229
|
end
|
231
230
|
|
232
231
|
def enqueue(method, file)
|
@@ -235,22 +234,24 @@ module ShopifyCLI
|
|
235
234
|
|
236
235
|
operation = Operation.new(@ctx, method, @theme[file])
|
237
236
|
|
238
|
-
|
239
|
-
return if @pending.include?(operation)
|
237
|
+
return unless enqueueable?(operation)
|
240
238
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
end
|
239
|
+
@pending << operation
|
240
|
+
@queue << operation unless @queue.closed?
|
241
|
+
end
|
245
242
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
243
|
+
def report_performed_operation(operation)
|
244
|
+
file = operation.file
|
245
|
+
|
246
|
+
if file.warnings.any?
|
247
|
+
warning_message =
|
248
|
+
operation.as_synced_message(color: :yellow) +
|
249
|
+
UnsupportedScriptWarning.new(@ctx, file).to_s
|
250
|
+
|
251
|
+
return @error_reporter.report(warning_message)
|
250
252
|
end
|
251
253
|
|
252
|
-
@
|
253
|
-
@queue << operation unless @queue.closed?
|
254
|
+
@standard_reporter.report(operation.as_synced_message)
|
254
255
|
end
|
255
256
|
|
256
257
|
def perform(operation)
|
@@ -258,36 +259,15 @@ module ShopifyCLI
|
|
258
259
|
wait_for_backoff!
|
259
260
|
@ctx.debug(operation.to_s)
|
260
261
|
|
261
|
-
send(operation.method, operation.file)
|
262
|
-
raise response if response.is_a?(StandardError)
|
263
|
-
|
264
|
-
file = operation.file
|
262
|
+
response = send(operation.method, operation.file)
|
265
263
|
|
266
|
-
|
267
|
-
|
268
|
-
operation.as_synced_message(color: :yellow) +
|
269
|
-
UnsupportedScriptWarning.new(@ctx, file).to_s
|
270
|
-
@error_reporter.report(warning_message)
|
271
|
-
else
|
272
|
-
@standard_reporter.report(operation.as_synced_message)
|
273
|
-
end
|
264
|
+
report_performed_operation(operation)
|
265
|
+
backoff_if_near_limit!(response)
|
274
266
|
|
275
|
-
# Check if the API told us we're near the rate limit
|
276
|
-
if !backingoff? && (limit = response["x-shopify-shop-api-call-limit"])
|
277
|
-
used, total = limit.split("/").map(&:to_i)
|
278
|
-
backoff_if_near_limit!(used, total)
|
279
|
-
end
|
280
|
-
rescue StandardError => error
|
281
|
-
handle_operation_error(operation, error)
|
282
|
-
ensure
|
283
|
-
@pending_mutex.synchronize do
|
284
|
-
# Avoid abrupt jumps in the progress bar
|
285
|
-
wait(0.05)
|
286
|
-
@pending.delete(operation)
|
287
|
-
end
|
288
|
-
end
|
289
267
|
rescue StandardError => error
|
290
268
|
handle_operation_error(operation, error)
|
269
|
+
ensure
|
270
|
+
@pending.delete(operation)
|
291
271
|
end
|
292
272
|
|
293
273
|
def update(file)
|
@@ -300,15 +280,16 @@ module ShopifyCLI
|
|
300
280
|
end
|
301
281
|
|
302
282
|
path = "themes/#{@theme.id}/assets.json"
|
303
|
-
req_body = JSON.generate(asset: asset)
|
304
283
|
|
305
|
-
|
306
|
-
|
284
|
+
_status, body, response = api_client.put(
|
285
|
+
path: path,
|
286
|
+
body: JSON.generate(asset: asset)
|
287
|
+
)
|
288
|
+
file.warnings = body.dig("asset", "warnings")
|
307
289
|
|
308
|
-
|
290
|
+
update_checksums(body)
|
309
291
|
|
310
|
-
|
311
|
-
end
|
292
|
+
response
|
312
293
|
end
|
313
294
|
|
314
295
|
def get(file)
|
@@ -326,7 +307,7 @@ module ShopifyCLI
|
|
326
307
|
file.write(body.dig("asset", "value"))
|
327
308
|
end
|
328
309
|
|
329
|
-
|
310
|
+
response
|
330
311
|
end
|
331
312
|
|
332
313
|
def delete(file)
|
@@ -337,7 +318,7 @@ module ShopifyCLI
|
|
337
318
|
})
|
338
319
|
)
|
339
320
|
|
340
|
-
|
321
|
+
response
|
341
322
|
end
|
342
323
|
|
343
324
|
def union_merge(file)
|
@@ -346,11 +327,11 @@ module ShopifyCLI
|
|
346
327
|
query: URI.encode_www_form("asset[key]" => file.relative_path),
|
347
328
|
)
|
348
329
|
|
349
|
-
return
|
330
|
+
return response unless file.text?
|
350
331
|
|
351
332
|
remote_content = body.dig("asset", "value")
|
352
333
|
|
353
|
-
return
|
334
|
+
return response if remote_content.nil?
|
354
335
|
|
355
336
|
content = Merger.union_merge(file, remote_content)
|
356
337
|
|
@@ -358,16 +339,7 @@ module ShopifyCLI
|
|
358
339
|
|
359
340
|
enqueue(:update, file)
|
360
341
|
|
361
|
-
|
362
|
-
end
|
363
|
-
|
364
|
-
def update_checksums(api_response)
|
365
|
-
api_response.values.flatten.each do |asset|
|
366
|
-
next unless asset["key"]
|
367
|
-
checksums[asset["key"]] = asset["checksum"]
|
368
|
-
end
|
369
|
-
|
370
|
-
checksums.reject_duplicated_checksums!
|
342
|
+
response
|
371
343
|
end
|
372
344
|
|
373
345
|
def parse_api_errors(operation, exception)
|
@@ -397,35 +369,10 @@ module ShopifyCLI
|
|
397
369
|
["The asset #{operation.file} could not be synced #{cause} #{backtrace}"]
|
398
370
|
end
|
399
371
|
|
400
|
-
def backoff_if_near_limit!(used, limit)
|
401
|
-
if used > limit - @threads.size
|
402
|
-
@ctx.debug("Near API call limit, waiting 2 sec…")
|
403
|
-
@backoff_mutex.synchronize { wait(2) }
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
def overwrite_json?
|
408
|
-
theme_created_at_runtime? || @overwrite_json
|
409
|
-
end
|
410
|
-
|
411
372
|
def theme_created_at_runtime?
|
412
373
|
@theme.created_at_runtime?
|
413
374
|
end
|
414
375
|
|
415
|
-
def backingoff?
|
416
|
-
@backoff_mutex.locked?
|
417
|
-
end
|
418
|
-
|
419
|
-
def wait_for_backoff!
|
420
|
-
# Sleeping in the mutex in another thread. Wait for unlock
|
421
|
-
@backoff_mutex.synchronize {} if backingoff?
|
422
|
-
end
|
423
|
-
|
424
|
-
def handle_operation_error(operation, error)
|
425
|
-
error_suffix = ":\n " + parse_api_errors(operation, error).join("\n ")
|
426
|
-
report_error(operation, error_suffix)
|
427
|
-
end
|
428
|
-
|
429
376
|
def wait(duration)
|
430
377
|
sleep(duration)
|
431
378
|
end
|
data/lib/shopify_cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -456,6 +456,7 @@ files:
|
|
456
456
|
- lib/shopify_cli/tasks/ensure_project_type.rb
|
457
457
|
- lib/shopify_cli/tasks/select_org_and_shop.rb
|
458
458
|
- lib/shopify_cli/tasks/update_dashboard_urls.rb
|
459
|
+
- lib/shopify_cli/theme/backoff_helper.rb
|
459
460
|
- lib/shopify_cli/theme/dev_server.rb
|
460
461
|
- lib/shopify_cli/theme/dev_server/cdn_fonts.rb
|
461
462
|
- lib/shopify_cli/theme/dev_server/certificate_manager.rb
|
@@ -504,28 +505,27 @@ files:
|
|
504
505
|
- lib/shopify_cli/theme/root.rb
|
505
506
|
- lib/shopify_cli/theme/syncer.rb
|
506
507
|
- lib/shopify_cli/theme/syncer/checksums.rb
|
508
|
+
- lib/shopify_cli/theme/syncer/downloader.rb
|
507
509
|
- lib/shopify_cli/theme/syncer/error_reporter.rb
|
508
|
-
- lib/shopify_cli/theme/syncer/forms/apply_to_all.rb
|
509
|
-
- lib/shopify_cli/theme/syncer/forms/apply_to_all_form.rb
|
510
|
-
- lib/shopify_cli/theme/syncer/forms/base_strategy_form.rb
|
511
|
-
- lib/shopify_cli/theme/syncer/forms/select_delete_strategy.rb
|
512
|
-
- lib/shopify_cli/theme/syncer/forms/select_update_strategy.rb
|
513
|
-
- lib/shopify_cli/theme/syncer/json_delete_handler.rb
|
514
|
-
- lib/shopify_cli/theme/syncer/json_update_handler.rb
|
515
510
|
- lib/shopify_cli/theme/syncer/merger.rb
|
516
511
|
- lib/shopify_cli/theme/syncer/operation.rb
|
517
512
|
- lib/shopify_cli/theme/syncer/standard_reporter.rb
|
518
513
|
- lib/shopify_cli/theme/syncer/unsupported_script_warning.rb
|
514
|
+
- lib/shopify_cli/theme/syncer/uploader.rb
|
515
|
+
- lib/shopify_cli/theme/syncer/uploader/bulk.rb
|
516
|
+
- lib/shopify_cli/theme/syncer/uploader/bulk_item.rb
|
517
|
+
- lib/shopify_cli/theme/syncer/uploader/bulk_job.rb
|
518
|
+
- lib/shopify_cli/theme/syncer/uploader/bulk_request.rb
|
519
|
+
- lib/shopify_cli/theme/syncer/uploader/forms/apply_to_all.rb
|
520
|
+
- lib/shopify_cli/theme/syncer/uploader/forms/apply_to_all_form.rb
|
521
|
+
- lib/shopify_cli/theme/syncer/uploader/forms/base_strategy_form.rb
|
522
|
+
- lib/shopify_cli/theme/syncer/uploader/forms/select_delete_strategy.rb
|
523
|
+
- lib/shopify_cli/theme/syncer/uploader/forms/select_update_strategy.rb
|
524
|
+
- lib/shopify_cli/theme/syncer/uploader/json_delete_handler.rb
|
525
|
+
- lib/shopify_cli/theme/syncer/uploader/json_update_handler.rb
|
519
526
|
- lib/shopify_cli/theme/theme.rb
|
520
527
|
- lib/shopify_cli/theme/theme_access_api.rb
|
521
528
|
- lib/shopify_cli/theme/theme_admin_api.rb
|
522
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler.rb
|
523
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/bulk.rb
|
524
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/bulk_job.rb
|
525
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/errors.rb
|
526
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/put_request.rb
|
527
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/request_parser.rb
|
528
|
-
- lib/shopify_cli/theme/theme_admin_api_throttler/response_parser.rb
|
529
529
|
- lib/shopify_cli/thread_pool.rb
|
530
530
|
- lib/shopify_cli/thread_pool/job.rb
|
531
531
|
- lib/shopify_cli/transform_data_structure.rb
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "apply_to_all_form"
|
4
|
-
|
5
|
-
module ShopifyCLI
|
6
|
-
module Theme
|
7
|
-
class Syncer
|
8
|
-
module Forms
|
9
|
-
class ApplyToAll
|
10
|
-
attr_reader :value
|
11
|
-
|
12
|
-
def initialize(ctx, number_of_files)
|
13
|
-
@ctx = ctx
|
14
|
-
@number_of_files = number_of_files
|
15
|
-
@value = nil
|
16
|
-
@apply = nil
|
17
|
-
end
|
18
|
-
|
19
|
-
def apply?(value)
|
20
|
-
return unless @number_of_files > 1
|
21
|
-
|
22
|
-
if @apply.nil?
|
23
|
-
@apply = ask.apply?
|
24
|
-
@value = value if @apply
|
25
|
-
end
|
26
|
-
|
27
|
-
@apply
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def ask
|
33
|
-
ApplyToAllForm.ask(@ctx, [], number_of_files: @number_of_files)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ShopifyCLI
|
4
|
-
module Theme
|
5
|
-
class Syncer
|
6
|
-
module Forms
|
7
|
-
class ApplyToAllForm < ShopifyCLI::Form
|
8
|
-
attr_accessor :apply
|
9
|
-
flag_arguments :number_of_files
|
10
|
-
|
11
|
-
def ask
|
12
|
-
title = message("title", number_of_files - 1)
|
13
|
-
|
14
|
-
self.apply = CLI::UI::Prompt.ask(title, allow_empty: false) do |handler|
|
15
|
-
handler.option(message("yes")) { true }
|
16
|
-
handler.option(message("no")) { false }
|
17
|
-
end
|
18
|
-
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
def apply?
|
23
|
-
apply
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def message(key, *params)
|
29
|
-
ctx.message("theme.serve.syncer.forms.apply_to_all.#{key}", *params)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ShopifyCLI
|
4
|
-
module Theme
|
5
|
-
class Syncer
|
6
|
-
module Forms
|
7
|
-
class BaseStrategyForm < ShopifyCLI::Form
|
8
|
-
attr_accessor :strategy
|
9
|
-
|
10
|
-
def ask
|
11
|
-
ctx.puts(title_context(file))
|
12
|
-
|
13
|
-
self.strategy = CLI::UI::Prompt.ask(title_question, allow_empty: false) do |handler|
|
14
|
-
strategies.each do |strategy|
|
15
|
-
handler.option(as_text(strategy)) { strategy }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
exit_cli if self.strategy == :exit
|
20
|
-
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
##
|
27
|
-
# List of strategies that populate the form options
|
28
|
-
#
|
29
|
-
def strategies
|
30
|
-
raise "`#{self.class.name}#strategies' must be defined"
|
31
|
-
end
|
32
|
-
|
33
|
-
##
|
34
|
-
# Message prefix for the form title and options (strategies).
|
35
|
-
# See the methods `title` and `as_text`
|
36
|
-
#
|
37
|
-
def prefix
|
38
|
-
raise "`#{self.class.name}#prefix' must be defined"
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def exit_cli
|
44
|
-
exit(0)
|
45
|
-
end
|
46
|
-
|
47
|
-
def title_context(file)
|
48
|
-
ctx.message("#{prefix}.title_context", file.relative_path)
|
49
|
-
end
|
50
|
-
|
51
|
-
def title_question
|
52
|
-
ctx.message("#{prefix}.title_question")
|
53
|
-
end
|
54
|
-
|
55
|
-
def as_text(strategy)
|
56
|
-
ctx.message("#{prefix}.#{strategy}")
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "base_strategy_form"
|
4
|
-
|
5
|
-
module ShopifyCLI
|
6
|
-
module Theme
|
7
|
-
class Syncer
|
8
|
-
module Forms
|
9
|
-
class SelectDeleteStrategy < BaseStrategyForm
|
10
|
-
flag_arguments :file
|
11
|
-
|
12
|
-
def strategies
|
13
|
-
%i[
|
14
|
-
delete
|
15
|
-
restore
|
16
|
-
exit
|
17
|
-
]
|
18
|
-
end
|
19
|
-
|
20
|
-
def prefix
|
21
|
-
"theme.serve.syncer.forms.delete_strategy"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "base_strategy_form"
|
4
|
-
|
5
|
-
module ShopifyCLI
|
6
|
-
module Theme
|
7
|
-
class Syncer
|
8
|
-
module Forms
|
9
|
-
class SelectUpdateStrategy < BaseStrategyForm
|
10
|
-
flag_arguments :file, :exists_remotely
|
11
|
-
|
12
|
-
def strategies
|
13
|
-
%i[
|
14
|
-
keep_remote
|
15
|
-
keep_local
|
16
|
-
union_merge
|
17
|
-
exit
|
18
|
-
]
|
19
|
-
end
|
20
|
-
|
21
|
-
def prefix
|
22
|
-
"theme.serve.syncer.forms.#{exists_remotely ? "update_strategy" : "update_remote_deleted_strategy"}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|