shopify-cli 2.29.0 → 2.30.0
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 +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
|