shopify-cli 2.20.0 → 2.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/cla.yml +22 -0
- data/.github/workflows/shopify.yml +0 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +1 -1
- data/lib/project_types/theme/commands/pull.rb +5 -1
- data/lib/project_types/theme/commands/push.rb +18 -9
- data/lib/project_types/theme/messages/messages.rb +22 -10
- data/lib/shopify_cli/constants.rb +1 -0
- data/lib/shopify_cli/context.rb +3 -2
- data/lib/shopify_cli/environment.rb +4 -0
- data/lib/shopify_cli/resources/env_file.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +22 -7
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_deleter.rb +62 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +23 -1
- data/lib/shopify_cli/theme/dev_server/proxy.rb +1 -0
- data/lib/shopify_cli/theme/syncer/json_update_handler.rb +6 -2
- data/lib/shopify_cli/theme/syncer.rb +14 -4
- data/lib/shopify_cli/theme/theme.rb +5 -0
- data/lib/shopify_cli/theme/theme_admin_api_throttler/bulk_job.rb +1 -1
- data/lib/shopify_cli/version.rb +1 -1
- metadata +4 -3
- data/.github/probots.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fdf2b1a1c6ff2b21a3adb26654fda425436a5660d27b487dd1473fc2530b02c
|
4
|
+
data.tar.gz: 572fa0ba305ec75391c3aac020f1bb72c0874a8d138c7b05da8aaf0fdba68719
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb78577fab62082d1fb27eacb1865a690c04a8985fea4af5684399e84a942d025e79b36792c1c382704231f8e73c67e71edd9cd055898de0aa48099b2d5dfb2e
|
7
|
+
data.tar.gz: 7e19eb12d7e1cfc5d22002bde244451f21277547180a13617f3211de1b657099e12b85efa46ce8f5649954336cd24c672c98e9ac807af00212f7ea921e57f37f
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Contributor License Agreement (CLA)
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request_target:
|
5
|
+
types: [opened, synchronize]
|
6
|
+
issue_comment:
|
7
|
+
types: [created]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
cla:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
if: |
|
13
|
+
(github.event.issue.pull_request
|
14
|
+
&& !github.event.issue.pull_request.merged_at
|
15
|
+
&& contains(github.event.comment.body, 'signed')
|
16
|
+
)
|
17
|
+
|| (github.event.pull_request && !github.event.pull_request.merged)
|
18
|
+
steps:
|
19
|
+
- uses: Shopify/shopify-cla-action@v1
|
20
|
+
with:
|
21
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
22
|
+
cla-token: ${{ secrets.CLA_TOKEN }}
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,30 @@ From version 2.6.0, the sections in this file adhere to the [keep a changelog](h
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## Version 2.22.0 - 2022-08-08
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
* [#2512](https://github.com/Shopify/shopify-cli/pull/2512): Add the `-t/--theme` parameter to the `shopify theme serve -h` message
|
9
|
+
* [#2505](https://github.com/Shopify/shopify-cli/pull/2505): Show warning messages when `shopify theme push/pull` has errors
|
10
|
+
|
11
|
+
## Version 2.21.0 - 2022-08-03
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
* [#2453](https://github.com/Shopify/shopify-cli/pull/2453): Fix [#2382](https://github.com/Shopify/shopify-cli/issues/2382): Ensure we wait 24 hours to show update message again
|
15
|
+
* [#2463](https://github.com/Shopify/shopify-cli/pull/2463): Fix for "Keep the remote version" deletes files on new development theme
|
16
|
+
* [#2405](https://github.com/Shopify/shopify-cli/pull/2405): Fix `theme serve` to trigger page refresh when a file is deleted
|
17
|
+
* [#2489](https://github.com/Shopify/shopify-cli/pull/2489): Fix `theme serve` to hot reload many occurrences of a stylesheet
|
18
|
+
|
19
|
+
### Added
|
20
|
+
* [#2496](https://github.com/Shopify/shopify-cli/pull/2496): Accept storefront renderer token from ENV variable
|
21
|
+
|
22
|
+
## Version 2.20.1 - 2022-07-18
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
* [#2458](https://github.com/Shopify/shopify-cli/pull/2458): Fix shop URL in unauthorized error message
|
26
|
+
* [#2459](https://github.com/Shopify/shopify-cli/pull/2459): Fix `.json` file ignore issues with `shopify theme push`
|
27
|
+
* [#2460](https://github.com/Shopify/shopify-cli/pull/2460): Fix job retries for .json theme file dependencies and support wider range of asset API errors
|
28
|
+
|
5
29
|
## Version 2.20.0 - 2022-07-11
|
6
30
|
|
7
31
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -52,7 +52,11 @@ module Theme
|
|
52
52
|
CLI::UI::Frame.open(@ctx.message("theme.pull.pulling", theme.name, theme.id, theme.shop)) do
|
53
53
|
UI::SyncProgressBar.new(syncer).progress(:download_theme!, delete: delete)
|
54
54
|
end
|
55
|
-
|
55
|
+
if syncer.has_any_error?
|
56
|
+
@ctx.warn(@ctx.message("theme.pull.done_with_errors"))
|
57
|
+
else
|
58
|
+
@ctx.done(@ctx.message("theme.pull.done"))
|
59
|
+
end
|
56
60
|
rescue ShopifyCLI::API::APIRequestNotFoundError
|
57
61
|
@ctx.abort(@ctx.message("theme.pull.theme_not_found", "##{theme.id}"))
|
58
62
|
ensure
|
@@ -63,20 +63,12 @@ module Theme
|
|
63
63
|
syncer.start_threads
|
64
64
|
if options.flags[:json]
|
65
65
|
syncer.upload_theme!(delete: delete)
|
66
|
-
puts(JSON.generate(theme: theme.to_h))
|
67
66
|
else
|
68
67
|
CLI::UI::Frame.open(@ctx.message("theme.push.info.pushing", theme.name, theme.id, theme.shop)) do
|
69
68
|
UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delete: delete)
|
70
69
|
end
|
71
|
-
|
72
|
-
if options.flags[:publish]
|
73
|
-
theme.publish
|
74
|
-
@ctx.done(@ctx.message("theme.publish.done", theme.preview_url))
|
75
|
-
else
|
76
|
-
@ctx.done(@ctx.message("theme.push.done", theme.preview_url, theme.editor_url))
|
77
|
-
end
|
78
70
|
end
|
79
|
-
|
71
|
+
push_completion_handler(theme, syncer.has_any_error?)
|
80
72
|
ensure
|
81
73
|
syncer.shutdown
|
82
74
|
end
|
@@ -90,6 +82,23 @@ module Theme
|
|
90
82
|
|
91
83
|
private
|
92
84
|
|
85
|
+
def push_completion_handler(theme, has_errors)
|
86
|
+
if options.flags[:json]
|
87
|
+
output = { theme: theme.to_h }
|
88
|
+
output[:warning] = "Theme pushed with errors." if has_errors
|
89
|
+
|
90
|
+
puts(JSON.generate(output))
|
91
|
+
elsif options.flags[:publish]
|
92
|
+
theme.publish
|
93
|
+
return @ctx.done(@ctx.message("theme.publish.done", theme.preview_url)) unless has_errors
|
94
|
+
@ctx.warn(@ctx.message("theme.publish.done_with_errors", theme.preview_url))
|
95
|
+
else
|
96
|
+
return @ctx.done(@ctx.message("theme.push.done", theme.preview_url, theme.editor_url)) unless has_errors
|
97
|
+
@ctx.warn(@ctx.message("theme.push.done_with_errors", theme.preview_url, theme.editor_url))
|
98
|
+
end
|
99
|
+
raise ShopifyCLI::AbortSilent if has_errors
|
100
|
+
end
|
101
|
+
|
93
102
|
def find_theme(root, theme_id: nil, theme: nil, live: nil, development: nil, unpublished: nil, **_args)
|
94
103
|
if theme_id
|
95
104
|
@ctx.warn(@ctx.message("theme.push.deprecated_themeid"))
|
@@ -11,7 +11,7 @@ module Theme
|
|
11
11
|
unauthorized_error: <<~EOD,
|
12
12
|
You can't use Shopify CLI with development stores if you only have Partner staff member access. If you want to use Shopify CLI to work on a development store, then you should be the store owner or create a staff account on the store.
|
13
13
|
|
14
|
-
If you're the store owner, then you need to log in to the store directly using the store URL at least once (for example, using %s
|
14
|
+
If you're the store owner, then you need to log in to the store directly using the store URL at least once (for example, using %s/admin) before you log in using Shopify CLI. Logging in to the Shopify admin directly connects the development store with your Shopify login.
|
15
15
|
EOD
|
16
16
|
ensure_user_try_this: <<~ENSURE_USER,
|
17
17
|
Check if your user is activated, has permission to edit themes at the store, and try to re-login.
|
@@ -43,6 +43,7 @@ module Theme
|
|
43
43
|
Run without arguments to select theme from a list.
|
44
44
|
HELP
|
45
45
|
done: "Your theme is now live at %s",
|
46
|
+
done_with_errors: "{{warning:Your theme was published with errors and is now live at %s.}}",
|
46
47
|
not_found: "Theme #%s does not exist",
|
47
48
|
no_themes_error: "You don't have any theme to be published.",
|
48
49
|
no_themes_resolution: "Try to create an unpublished theme with {{command:theme push -u -t <theme_name>}}.",
|
@@ -102,6 +103,15 @@ module Theme
|
|
102
103
|
{{info:Customize this theme in the Theme Editor:}}
|
103
104
|
{{underline:%s}}
|
104
105
|
DONE
|
106
|
+
done_with_errors: <<~WARN,
|
107
|
+
{{yellow:Your theme was pushed with errors.}}
|
108
|
+
|
109
|
+
{{info:View your theme:}}
|
110
|
+
{{underline:%s}}
|
111
|
+
|
112
|
+
{{info:Customize this theme in the Theme Editor:}}
|
113
|
+
{{underline:%s}}
|
114
|
+
WARN
|
105
115
|
name: "Theme name",
|
106
116
|
},
|
107
117
|
serve: {
|
@@ -112,14 +122,15 @@ module Theme
|
|
112
122
|
Usage: {{command:%s theme serve [ ROOT ]}}
|
113
123
|
|
114
124
|
Options:
|
115
|
-
{{command
|
116
|
-
{{command:--
|
117
|
-
{{command:--
|
118
|
-
{{command:--
|
119
|
-
{{command:--
|
120
|
-
|
121
|
-
|
122
|
-
|
125
|
+
{{command:-t, --theme=NAME_OR_ID}} Theme ID or name of the remote theme.
|
126
|
+
{{command:--port=PORT}} Local port to serve theme preview from.
|
127
|
+
{{command:--poll}} Force polling to detect file changes.
|
128
|
+
{{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
|
129
|
+
{{command:--theme-editor-sync}} Synchronize Theme Editor updates in the local theme files.
|
130
|
+
{{command:--live-reload=MODE}} The live reload mode switches the server behavior when a file is modified:
|
131
|
+
- {{command:hot-reload}} Hot reloads local changes to CSS and sections (default)
|
132
|
+
- {{command:full-page}} Always refreshes the entire page
|
133
|
+
- {{command:off}} Deactivate live reload
|
123
134
|
HELP
|
124
135
|
reload_mode_is_not_valid: "The live reload mode `%s` is not valid.",
|
125
136
|
try_a_valid_reload_mode: "Try a valid live reload mode: %s.",
|
@@ -318,7 +329,8 @@ module Theme
|
|
318
329
|
HELP
|
319
330
|
select: "Select a theme to pull from",
|
320
331
|
pulling: "Pulling theme files from %s (#%s) on %s",
|
321
|
-
done: "Theme pulled successfully",
|
332
|
+
done: "Theme pulled successfully.",
|
333
|
+
done_with_errors: "{{warning:Your theme was pulled with errors.}}",
|
322
334
|
deprecated_themeid: <<~WARN,
|
323
335
|
{{warning:The {{command:-i, --themeid}} flag is deprecated. Use {{command:-t, --theme}} instead.}}
|
324
336
|
WARN
|
@@ -54,6 +54,7 @@ module ShopifyCLI
|
|
54
54
|
# Authentication
|
55
55
|
AUTH_TOKEN = "SHOPIFY_CLI_AUTH_TOKEN"
|
56
56
|
ADMIN_AUTH_TOKEN = "SHOPIFY_CLI_ADMIN_AUTH_TOKEN"
|
57
|
+
STOREFRONT_RENDERER_AUTH_TOKEN = "SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN"
|
57
58
|
|
58
59
|
# Monorail
|
59
60
|
MONORAIL_REAL_EVENTS = "MONORAIL_REAL_EVENTS"
|
data/lib/shopify_cli/context.rb
CHANGED
@@ -628,9 +628,10 @@ module ShopifyCLI
|
|
628
628
|
thread = Thread.new { retrieve_latest_gem_version }
|
629
629
|
at_exit { thread.join }
|
630
630
|
end
|
631
|
+
latest_version =
|
632
|
+
ShopifyCLI::Config.get(VERSION_CHECK_SECTION, LATEST_VERSION_FIELD, default: ShopifyCLI::VERSION)
|
633
|
+
latest_version if ::Semantic::Version.new(latest_version) > ::Semantic::Version.new(ShopifyCLI::VERSION)
|
631
634
|
end
|
632
|
-
latest_version = ShopifyCLI::Config.get(VERSION_CHECK_SECTION, LATEST_VERSION_FIELD, default: ShopifyCLI::VERSION)
|
633
|
-
latest_version if ::Semantic::Version.new(latest_version) > ::Semantic::Version.new(ShopifyCLI::VERSION)
|
634
635
|
end
|
635
636
|
|
636
637
|
# Returns file extension depending on OS
|
@@ -170,6 +170,10 @@ module ShopifyCLI
|
|
170
170
|
env_variables[Constants::EnvironmentVariables::ADMIN_AUTH_TOKEN]
|
171
171
|
end
|
172
172
|
|
173
|
+
def self.storefront_renderer_auth_token(env_variables: ENV)
|
174
|
+
env_variables[Constants::EnvironmentVariables::STOREFRONT_RENDERER_AUTH_TOKEN]
|
175
|
+
end
|
176
|
+
|
173
177
|
def self.store(env_variables: ENV)
|
174
178
|
env_variables[Constants::EnvironmentVariables::STORE]
|
175
179
|
end
|
@@ -30,7 +30,7 @@ module ShopifyCLI
|
|
30
30
|
def parse(directory)
|
31
31
|
File.read(path(directory))
|
32
32
|
.gsub("\r\n", "\n").split("\n").each_with_object({}) do |line, output|
|
33
|
-
match = /\A([A-Za-z_0-9]+)\s*=\s*(.*)\z/.match(line)
|
33
|
+
match = /\A(#*\s*[A-Za-z_0-9]+)\s*=\s*(.*)\z/.match(line)
|
34
34
|
if match
|
35
35
|
key = match[1]
|
36
36
|
output[key] = case match[2]
|
@@ -14,7 +14,7 @@
|
|
14
14
|
function connect() {
|
15
15
|
const eventSource = new EventSource('/hot-reload');
|
16
16
|
|
17
|
-
eventSource.onmessage =
|
17
|
+
eventSource.onmessage = onMessage;
|
18
18
|
|
19
19
|
eventSource.onopen = () => console.log('[HotReload] SSE connected.');
|
20
20
|
|
@@ -97,10 +97,23 @@
|
|
97
97
|
window.location.reload();
|
98
98
|
}
|
99
99
|
|
100
|
-
function
|
101
|
-
|
100
|
+
function onMessage(message) {
|
101
|
+
const data = JSON.parse(message.data);
|
102
|
+
if (data.reload_page) {
|
103
|
+
refreshPage([]);
|
104
|
+
return;
|
105
|
+
}
|
106
|
+
|
107
|
+
handleUpdate(data);
|
108
|
+
}
|
109
|
+
|
110
|
+
function handleUpdate(data) {
|
102
111
|
var modifiedFiles = data.modified;
|
103
112
|
|
113
|
+
if (modifiedFiles === undefined) {
|
114
|
+
return;
|
115
|
+
}
|
116
|
+
|
104
117
|
if (isRefreshRequired(modifiedFiles)) {
|
105
118
|
refreshPage(modifiedFiles);
|
106
119
|
} else {
|
@@ -114,13 +127,15 @@
|
|
114
127
|
|
115
128
|
function reloadCssFile(filename) {
|
116
129
|
// Find a stylesheet link starting with /assets (locally-served only) containing the filename
|
117
|
-
let
|
130
|
+
let links = document.querySelectorAll(`link[href^="/assets"][href*="${filename}"][rel="stylesheet"]`);
|
118
131
|
|
119
|
-
if (!
|
132
|
+
if (!links.length) {
|
120
133
|
console.log(`[HotReload] Could not find link for stylesheet ${filename}`);
|
121
134
|
} else {
|
122
|
-
|
123
|
-
|
135
|
+
links.forEach(link => {
|
136
|
+
link.href = new URL(link.href).pathname + `?v=${Date.now()}`;
|
137
|
+
console.log(`[HotReload] Reloaded stylesheet ${filename}`);
|
138
|
+
})
|
124
139
|
}
|
125
140
|
}
|
126
141
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
module Theme
|
5
|
+
module DevServer
|
6
|
+
class HotReload
|
7
|
+
class RemoteFileDeleter
|
8
|
+
def initialize(ctx, theme:, streams:)
|
9
|
+
@ctx = ctx
|
10
|
+
@theme = theme
|
11
|
+
@streams = streams
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(file)
|
15
|
+
retries = 6
|
16
|
+
|
17
|
+
until retries.zero?
|
18
|
+
retries -= 1
|
19
|
+
|
20
|
+
_status, body = fetch_asset(file)
|
21
|
+
retries = 0 if deleted_file?(body)
|
22
|
+
|
23
|
+
wait
|
24
|
+
end
|
25
|
+
|
26
|
+
notify(file)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def api_client
|
32
|
+
@api_client ||= ThemeAdminAPI.new(@ctx, @theme.shop)
|
33
|
+
end
|
34
|
+
|
35
|
+
def deleted_file?(body)
|
36
|
+
remote_checksum = body.dig("asset", "checksum")
|
37
|
+
|
38
|
+
remote_checksum.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def notify(file)
|
42
|
+
@streams.broadcast(JSON.generate(deleted: [file]))
|
43
|
+
@ctx.debug("[RemoteFileDeleter] Deleted #{file}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def wait
|
47
|
+
sleep(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch_asset(file)
|
51
|
+
api_client.get(
|
52
|
+
path: "themes/#{@theme.id}/assets.json",
|
53
|
+
query: URI.encode_www_form("asset[key]" => file.relative_path),
|
54
|
+
)
|
55
|
+
rescue ShopifyCLI::API::APIRequestNotFoundError
|
56
|
+
[404, {}]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "hot_reload/remote_file_reloader"
|
4
|
+
require_relative "hot_reload/remote_file_deleter"
|
4
5
|
require_relative "hot_reload/sections_index"
|
5
6
|
|
6
7
|
module ShopifyCLI
|
@@ -14,6 +15,7 @@ module ShopifyCLI
|
|
14
15
|
@mode = mode
|
15
16
|
@streams = SSE::Streams.new
|
16
17
|
@remote_file_reloader = RemoteFileReloader.new(ctx, theme: @theme, streams: @streams)
|
18
|
+
@remote_file_deleter = RemoteFileDeleter.new(ctx, theme: @theme, streams: @streams)
|
17
19
|
@sections_index = SectionsIndex.new(@theme)
|
18
20
|
@watcher = watcher
|
19
21
|
@watcher.add_observer(self, :notify_streams_of_file_change)
|
@@ -36,13 +38,20 @@ module ShopifyCLI
|
|
36
38
|
@streams.close
|
37
39
|
end
|
38
40
|
|
39
|
-
def notify_streams_of_file_change(modified, added,
|
41
|
+
def notify_streams_of_file_change(modified, added, removed)
|
40
42
|
files = (modified + added)
|
41
43
|
.reject { |file| @ignore_filter&.ignore?(file) }
|
42
44
|
.map { |file| @theme[file] }
|
43
45
|
|
44
46
|
files -= liquid_css_files = files.select(&:liquid_css?)
|
45
47
|
|
48
|
+
deleted_files = removed
|
49
|
+
.reject { |file| @ignore_filter&.ignore?(file) }
|
50
|
+
.map { |file| @theme[file] }
|
51
|
+
|
52
|
+
remote_delete(deleted_files) unless deleted_files.empty?
|
53
|
+
reload_page(removed) unless deleted_files.empty?
|
54
|
+
|
46
55
|
hot_reload(files) unless files.empty?
|
47
56
|
remote_reload(liquid_css_files)
|
48
57
|
end
|
@@ -55,8 +64,21 @@ module ShopifyCLI
|
|
55
64
|
@ctx.debug("[HotReload] Modified #{paths.join(", ")}")
|
56
65
|
end
|
57
66
|
|
67
|
+
def reload_page(removed)
|
68
|
+
@streams.broadcast(JSON.generate(reload_page: true))
|
69
|
+
@ctx.debug("[ReloadPage] Deleted #{removed.join(", ")}")
|
70
|
+
end
|
71
|
+
|
72
|
+
def remote_delete(files)
|
73
|
+
files.each do |file|
|
74
|
+
@ctx.debug("delete file each -> file.relative_path #{file.relative_path}")
|
75
|
+
@remote_file_deleter.delete(file)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
58
79
|
def remote_reload(files)
|
59
80
|
files.each do |file|
|
81
|
+
@ctx.debug("reload file each -> file.relative_path #{file.relative_path}")
|
60
82
|
@remote_file_reloader.reload(file)
|
61
83
|
end
|
62
84
|
end
|
@@ -10,7 +10,7 @@ module ShopifyCLI
|
|
10
10
|
def enqueue_json_updates(files)
|
11
11
|
# Update remote JSON files and delays `delayed_files` update
|
12
12
|
files = files
|
13
|
-
.select { |file|
|
13
|
+
.select { |file| ready_to_update?(file) }
|
14
14
|
.sort_by { |file| delayed_files.include?(file) ? 1 : 0 }
|
15
15
|
.reject { |file| overwrite_json? && delayed_files.include?(file) }
|
16
16
|
|
@@ -26,7 +26,7 @@ module ShopifyCLI
|
|
26
26
|
return unless overwrite_json?
|
27
27
|
# Update delayed files synchronously
|
28
28
|
delayed_files.each do |file|
|
29
|
-
update(file) if
|
29
|
+
update(file) if ready_to_update?(file)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -86,6 +86,10 @@ module ShopifyCLI
|
|
86
86
|
def ask_update_strategy(file)
|
87
87
|
Forms::SelectUpdateStrategy.ask(@ctx, [], file: file, exists_remotely: file_exist_remotely?(file)).strategy
|
88
88
|
end
|
89
|
+
|
90
|
+
def ready_to_update?(file)
|
91
|
+
!ignore_file?(file) && file.exist? && checksums.file_has_changed?(file)
|
92
|
+
end
|
89
93
|
end
|
90
94
|
end
|
91
95
|
end
|
@@ -366,17 +366,23 @@ module ShopifyCLI
|
|
366
366
|
checksums.reject_duplicated_checksums!
|
367
367
|
end
|
368
368
|
|
369
|
-
def parse_api_errors(exception)
|
369
|
+
def parse_api_errors(operation, exception)
|
370
370
|
parsed_body = if exception&.response&.is_a?(Hash)
|
371
371
|
exception&.response&.[](:body)
|
372
372
|
else
|
373
373
|
JSON.parse(exception&.response&.body)
|
374
374
|
end
|
375
|
-
|
375
|
+
|
376
|
+
errors = parsed_body.dig("errors") # either nil or another type
|
377
|
+
errors = errors.dig("asset") if errors&.is_a?(Hash)
|
378
|
+
|
379
|
+
message = errors || parsed_body["message"] || exception.message
|
376
380
|
# Truncate to first lines
|
377
381
|
[message].flatten.map { |m| m.split("\n", 2).first }
|
378
382
|
rescue JSON::ParserError
|
379
383
|
[exception.message]
|
384
|
+
rescue StandardError => e
|
385
|
+
["The asset #{operation.file} is could not be synced (cause: #{e.message})."]
|
380
386
|
end
|
381
387
|
|
382
388
|
def backoff_if_near_limit!(used, limit)
|
@@ -387,7 +393,11 @@ module ShopifyCLI
|
|
387
393
|
end
|
388
394
|
|
389
395
|
def overwrite_json?
|
390
|
-
@overwrite_json
|
396
|
+
theme_created_at_runtime? || @overwrite_json
|
397
|
+
end
|
398
|
+
|
399
|
+
def theme_created_at_runtime?
|
400
|
+
@theme.created_at_runtime?
|
391
401
|
end
|
392
402
|
|
393
403
|
def backingoff?
|
@@ -400,7 +410,7 @@ module ShopifyCLI
|
|
400
410
|
end
|
401
411
|
|
402
412
|
def handle_operation_error(operation, error)
|
403
|
-
error_suffix = ":\n " + parse_api_errors(error).join("\n ")
|
413
|
+
error_suffix = ":\n " + parse_api_errors(operation, error).join("\n ")
|
404
414
|
report_error(operation, error_suffix)
|
405
415
|
end
|
406
416
|
|
@@ -120,6 +120,7 @@ module ShopifyCLI
|
|
120
120
|
)
|
121
121
|
|
122
122
|
@id = body["theme"]["id"]
|
123
|
+
@created_at_runtime = true
|
123
124
|
end
|
124
125
|
|
125
126
|
def delete
|
@@ -147,6 +148,10 @@ module ShopifyCLI
|
|
147
148
|
development? && id != ShopifyCLI::DB.get(:development_theme_id)
|
148
149
|
end
|
149
150
|
|
151
|
+
def created_at_runtime?
|
152
|
+
@created_at_runtime ||= false
|
153
|
+
end
|
154
|
+
|
150
155
|
def to_h
|
151
156
|
{
|
152
157
|
id: id,
|
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.22.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-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -124,7 +124,7 @@ files:
|
|
124
124
|
- ".github/ISSUE_TEMPLATE/enhancement.yaml"
|
125
125
|
- ".github/ISSUE_TEMPLATE/feature.yaml"
|
126
126
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
127
|
-
- ".github/
|
127
|
+
- ".github/workflows/cla.yml"
|
128
128
|
- ".github/workflows/shopify.yml"
|
129
129
|
- ".github/workflows/stale.yml"
|
130
130
|
- ".github/workflows/triage.yml"
|
@@ -507,6 +507,7 @@ files:
|
|
507
507
|
- lib/shopify_cli/theme/dev_server/hot-reload-no-script.html
|
508
508
|
- lib/shopify_cli/theme/dev_server/hot-reload.js
|
509
509
|
- lib/shopify_cli/theme/dev_server/hot_reload.rb
|
510
|
+
- lib/shopify_cli/theme/dev_server/hot_reload/remote_file_deleter.rb
|
510
511
|
- lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb
|
511
512
|
- lib/shopify_cli/theme/dev_server/hot_reload/sections_index.rb
|
512
513
|
- lib/shopify_cli/theme/dev_server/local_assets.rb
|
data/.github/probots.yml
DELETED