shopify-cli 2.8.0 → 2.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile.lock +1 -1
- data/RELEASING.md +4 -3
- data/ext/javy/javy.rb +1 -1
- data/lib/project_types/extension/commands/push.rb +2 -2
- data/lib/project_types/extension/messages/messages.rb +1 -1
- data/lib/project_types/extension/models/development_server.rb +2 -4
- data/lib/project_types/rails/gem.rb +1 -2
- data/lib/project_types/script/cli.rb +10 -0
- data/lib/project_types/script/commands/connect.rb +1 -1
- data/lib/project_types/script/commands/create.rb +8 -2
- data/lib/project_types/script/commands/push.rb +35 -12
- data/lib/project_types/script/config/extension_points.yml +12 -0
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/graphql/module_upload_url_generate.graphql +5 -1
- data/lib/project_types/script/layers/application/build_script.rb +6 -3
- data/lib/project_types/script/layers/application/connect_app.rb +11 -5
- data/lib/project_types/script/layers/application/extension_points.rb +50 -26
- data/lib/project_types/script/layers/application/project_dependencies.rb +1 -1
- data/lib/project_types/script/layers/application/push_script.rb +41 -30
- data/lib/project_types/script/layers/domain/errors.rb +10 -3
- data/lib/project_types/script/layers/domain/extension_point.rb +16 -2
- data/lib/project_types/script/layers/domain/push_package.rb +0 -3
- data/lib/project_types/script/layers/domain/script_config.rb +6 -4
- data/lib/project_types/script/layers/domain/script_project.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/errors.rb +47 -23
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +15 -0
- data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +36 -0
- data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +18 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +7 -8
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -54
- data/lib/project_types/script/layers/infrastructure/script_service.rb +35 -12
- data/lib/project_types/script/layers/infrastructure/script_uploader.rb +22 -9
- data/lib/project_types/script/loaders/project.rb +44 -0
- data/lib/project_types/script/loaders/specification_handler.rb +22 -0
- data/lib/project_types/script/messages/messages.rb +38 -19
- data/lib/project_types/script/ui/error_handler.rb +52 -30
- data/lib/project_types/theme/commands/pull.rb +45 -17
- data/lib/project_types/theme/commands/push.rb +62 -27
- data/lib/project_types/theme/commands/serve.rb +5 -0
- data/lib/project_types/theme/messages/messages.rb +33 -18
- data/lib/shopify_cli/constants.rb +7 -2
- data/lib/shopify_cli/context.rb +66 -12
- data/lib/shopify_cli/core/executor.rb +4 -4
- data/lib/shopify_cli/environment.rb +50 -20
- data/lib/shopify_cli/identity_auth.rb +4 -3
- data/lib/shopify_cli/messages/messages.rb +2 -0
- data/lib/shopify_cli/method_object.rb +21 -9
- data/lib/shopify_cli/resources/env_file.rb +5 -1
- data/lib/shopify_cli/result.rb +61 -59
- data/lib/shopify_cli/task.rb +5 -3
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +19 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +18 -2
- data/lib/shopify_cli/theme/dev_server/proxy.rb +1 -0
- data/lib/shopify_cli/theme/dev_server/reload_mode.rb +34 -0
- data/lib/shopify_cli/theme/dev_server.rb +6 -21
- data/lib/shopify_cli/theme/file.rb +2 -2
- data/lib/shopify_cli/theme/filter/path_matcher.rb +38 -0
- data/lib/shopify_cli/theme/ignore_filter.rb +14 -18
- data/lib/shopify_cli/theme/include_filter.rb +43 -0
- data/lib/shopify_cli/theme/syncer.rb +17 -2
- data/lib/shopify_cli/theme/theme.rb +26 -4
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +6 -1
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +10 -5
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +6 -4
- data/vendor/deps/ruby2_keywords/LICENSE +22 -0
- data/vendor/deps/ruby2_keywords/README.md +67 -0
- data/vendor/deps/ruby2_keywords/Rakefile +54 -0
- data/vendor/deps/ruby2_keywords/lib/ruby2_keywords.rb +57 -0
- data/vendor/deps/ruby2_keywords/ruby2_keywords.gemspec +18 -0
- data/vendor/deps/ruby2_keywords/test/test_keyword.rb +41 -0
- metadata +16 -2
@@ -19,7 +19,8 @@ module Script
|
|
19
19
|
metadata:,
|
20
20
|
script_config:,
|
21
21
|
module_upload_url:,
|
22
|
-
library
|
22
|
+
library:,
|
23
|
+
input_query: nil
|
23
24
|
)
|
24
25
|
query_name = "app_script_set"
|
25
26
|
variables = {
|
@@ -34,11 +35,14 @@ module Script
|
|
34
35
|
configurationUi: script_config.configuration_ui,
|
35
36
|
configurationDefinition: script_config.configuration&.to_json,
|
36
37
|
moduleUploadUrl: module_upload_url,
|
37
|
-
|
38
|
-
language: library[:language],
|
39
|
-
version: library[:version],
|
40
|
-
},
|
38
|
+
inputQuery: input_query,
|
41
39
|
}
|
40
|
+
|
41
|
+
variables[:library] = {
|
42
|
+
language: library[:language],
|
43
|
+
version: library[:version],
|
44
|
+
} if library
|
45
|
+
|
42
46
|
resp_hash = make_request(query_name: query_name, variables: variables)
|
43
47
|
user_errors = resp_hash["data"]["appScriptSet"]["userErrors"]
|
44
48
|
|
@@ -46,20 +50,37 @@ module Script
|
|
46
50
|
|
47
51
|
if user_errors.any? { |e| e["tag"] == "already_exists_error" }
|
48
52
|
raise Errors::ScriptRepushError, uuid
|
53
|
+
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_error" })
|
54
|
+
raise Errors::ScriptConfigurationDefinitionError.new(
|
55
|
+
message: e["message"],
|
56
|
+
filename: script_config.filename,
|
57
|
+
)
|
49
58
|
elsif (e = user_errors.any? { |err| err["tag"] == "configuration_definition_syntax_error" })
|
50
|
-
raise Errors::ScriptConfigSyntaxError
|
59
|
+
raise Errors::ScriptConfigSyntaxError, script_config.filename
|
51
60
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_missing_keys_error" })
|
52
|
-
raise Errors::ScriptConfigMissingKeysError
|
61
|
+
raise Errors::ScriptConfigMissingKeysError.new(
|
62
|
+
missing_keys: e["message"],
|
63
|
+
filename: script_config.filename,
|
64
|
+
)
|
53
65
|
elsif (e = user_errors.find { |err| err["tag"] == "configuration_definition_invalid_value_error" })
|
54
|
-
raise Errors::ScriptConfigInvalidValueError
|
66
|
+
raise Errors::ScriptConfigInvalidValueError.new(
|
67
|
+
valid_input_modes: e["message"],
|
68
|
+
filename: script_config.filename,
|
69
|
+
)
|
55
70
|
elsif (e = user_errors.find do |err|
|
56
71
|
err["tag"] == "configuration_definition_schema_field_missing_keys_error"
|
57
72
|
end)
|
58
|
-
raise Errors::ScriptConfigFieldsMissingKeysError
|
73
|
+
raise Errors::ScriptConfigFieldsMissingKeysError.new(
|
74
|
+
missing_keys: e["message"],
|
75
|
+
filename: script_config.filename,
|
76
|
+
)
|
59
77
|
elsif (e = user_errors.find do |err|
|
60
78
|
err["tag"] == "configuration_definition_schema_field_invalid_value_error"
|
61
79
|
end)
|
62
|
-
raise Errors::ScriptConfigFieldsInvalidValueError
|
80
|
+
raise Errors::ScriptConfigFieldsInvalidValueError.new(
|
81
|
+
valid_types: e["message"],
|
82
|
+
filename: script_config.filename,
|
83
|
+
)
|
63
84
|
elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
|
64
85
|
raise Domain::Errors::MetadataValidationError
|
65
86
|
else
|
@@ -74,14 +95,16 @@ module Script
|
|
74
95
|
response["data"]["appScripts"]
|
75
96
|
end
|
76
97
|
|
77
|
-
def
|
98
|
+
def generate_module_upload_details
|
78
99
|
query_name = "module_upload_url_generate"
|
79
100
|
variables = {}
|
80
101
|
response = make_request(query_name: query_name, variables: variables)
|
81
102
|
user_errors = response["data"]["moduleUploadUrlGenerate"]["userErrors"]
|
82
103
|
|
83
104
|
raise Errors::GraphqlError, user_errors if user_errors.any?
|
84
|
-
|
105
|
+
|
106
|
+
data = response["data"]["moduleUploadUrlGenerate"]["details"]
|
107
|
+
{ url: data["url"], headers: data["headers"], max_size: data["humanizedMaxSize"] }
|
85
108
|
end
|
86
109
|
|
87
110
|
private
|
@@ -7,19 +7,32 @@ module Script
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def upload(script_content)
|
10
|
-
@script_service.
|
11
|
-
|
10
|
+
upload_details = @script_service.generate_module_upload_details
|
11
|
+
url = URI(upload_details[:url])
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
https = Net::HTTP.new(url.host, url.port)
|
14
|
+
https.use_ssl = true
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
request.body = script_content
|
16
|
+
request = Net::HTTP::Put.new(url)
|
17
|
+
request["Content-Type"] = "application/wasm"
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
upload_details[:headers].each do |header, value|
|
20
|
+
request[header] = value
|
22
21
|
end
|
22
|
+
|
23
|
+
request.body = script_content
|
24
|
+
|
25
|
+
response = https.request(request)
|
26
|
+
raise Errors::ScriptTooLargeError, upload_details[:max_size] if script_too_large?(response)
|
27
|
+
raise Errors::ScriptUploadError unless response.code == "200"
|
28
|
+
|
29
|
+
upload_details[:url]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def script_too_large?(response)
|
35
|
+
response.code == "400" && response.body.include?("EntityTooLarge")
|
23
36
|
end
|
24
37
|
end
|
25
38
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Loaders
|
5
|
+
module Project
|
6
|
+
def self.load(directory:, api_key:, uuid:, api_secret:, context: ShopifyCLI::Context.new)
|
7
|
+
env_overrides = {
|
8
|
+
"SHOPIFY_API_KEY" => api_key,
|
9
|
+
"SHOPIFY_API_SECRET" => api_secret,
|
10
|
+
"UUID" => uuid,
|
11
|
+
}.compact
|
12
|
+
env_file_present = env_file_exists?(directory)
|
13
|
+
env = if env_file_present
|
14
|
+
ShopifyCLI::Resources::EnvFile.read(directory, overrides: env_overrides)
|
15
|
+
else
|
16
|
+
ShopifyCLI::Resources::EnvFile.from_hash(env_overrides)
|
17
|
+
end
|
18
|
+
|
19
|
+
project = ShopifyCLI::Project.at(directory)
|
20
|
+
project.env = env
|
21
|
+
project
|
22
|
+
rescue SmartProperties::InitializationError, SmartProperties::InvalidValueError => error
|
23
|
+
handle_error(error, context: context, env_file_present: env_file_present)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.handle_error(error, context:, env_file_present:)
|
27
|
+
if env_file_present
|
28
|
+
properties_hash = { api_key: "SHOPIFY_API_KEY", secret: "SHOPIFY_API_SECRET" }
|
29
|
+
missing_env_variables = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
30
|
+
raise ShopifyCLI::Abort,
|
31
|
+
context.message("script.error.missing_env_file_variables", missing_env_variables, ShopifyCLI::TOOL_NAME)
|
32
|
+
else
|
33
|
+
properties_hash = { api_key: "--api-key", secret: "--api-secret" }
|
34
|
+
missing_options = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
35
|
+
raise ShopifyCLI::Abort, context.message("script.error.missing_push_options", missing_options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.env_file_exists?(directory)
|
40
|
+
File.exist?(ShopifyCLI::Resources::EnvFile.path(directory))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Loaders
|
5
|
+
module SpecificationHandler
|
6
|
+
def self.load(project:, context:)
|
7
|
+
identifier = project.specification_identifier
|
8
|
+
Models::LazySpecificationHandler.new(identifier) do
|
9
|
+
specifications = Models::Specifications.new(
|
10
|
+
fetch_specifications: Tasks::FetchSpecifications.new(api_key: project.app.api_key, context: context)
|
11
|
+
)
|
12
|
+
|
13
|
+
unless specifications.valid?(identifier)
|
14
|
+
context.abort(context.message("errors.unknown_type", project.specification_identifier))
|
15
|
+
end
|
16
|
+
|
17
|
+
specifications[identifier]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -47,38 +47,39 @@ module Script
|
|
47
47
|
invalid_language_cause: "Invalid language %s.",
|
48
48
|
invalid_language_help: "Allowed values: %s.",
|
49
49
|
|
50
|
-
|
51
|
-
|
50
|
+
missing_script_config_field_cause: "The %{filename} file is missing the required %{field} field.",
|
51
|
+
missing_script_config_field_help: "Add the field and try again.",
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
script_config_parse_error_cause: "The %{filename} file contains invalid %{serialization_format}.",
|
54
|
+
script_config_parse_error_help: "Fix the errors and try again.",
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
no_script_config_file_cause: "The %{filename} file is missing.",
|
57
|
+
no_script_config_file_help: "Create this file and try again.",
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
app_not_connected_cause: "Script is not connected to an app.",
|
60
|
+
app_not_connected_help: "Run shopify connect or enter fields for api-key and api-secret.",
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
configuration_definition_error_cause: "In the %{filename} file, there was a problem with the "\
|
63
|
+
"configuration. %{message}",
|
64
|
+
configuration_definition_error_help: "Fix the error and try again.",
|
64
65
|
|
65
|
-
configuration_syntax_error_cause: "The
|
66
|
+
configuration_syntax_error_cause: "The %{filename} is not formatted properly.",
|
66
67
|
configuration_syntax_error_help: "Fix the errors and try again.",
|
67
68
|
|
68
|
-
configuration_missing_keys_error_cause: "The
|
69
|
+
configuration_missing_keys_error_cause: "The %{filename} file is missing required keys: "\
|
69
70
|
"%{missing_keys}.",
|
70
71
|
configuration_missing_keys_error_help: "Add the keys and try again.",
|
71
72
|
|
72
|
-
configuration_invalid_value_error_cause: "The
|
73
|
+
configuration_invalid_value_error_cause: "The %{filename} configuration only accepts "\
|
73
74
|
"one of the following types(s): %{valid_input_modes}.",
|
74
75
|
configuration_invalid_value_error_help: "Change the type and try again.",
|
75
76
|
|
76
|
-
configuration_schema_field_missing_keys_error_cause: "A configuration entry in the
|
77
|
+
configuration_schema_field_missing_keys_error_cause: "A configuration entry in the %{filename} file "\
|
77
78
|
"is missing required keys: %{missing_keys}.",
|
78
79
|
configuration_definition_schema_field_missing_keys_error_help: "Add the keys and try again.",
|
79
80
|
|
80
81
|
configuration_schema_field_invalid_value_error_cause: "The configuration entries in the "\
|
81
|
-
"
|
82
|
+
"%{filename} file only accept one of the following "\
|
82
83
|
"type(s): %{valid_types}.",
|
83
84
|
configuration_schema_field_invalid_value_error_help: "Change the types and try again.",
|
84
85
|
|
@@ -128,8 +129,8 @@ module Script
|
|
128
129
|
"\nbuild: npx shopify-scripts-toolchain-as build --src src/shopify_main.ts --binary build/<script_name>.wasm --metadata build/metadata.json -- --lib node_modules --optimize --use Date=",
|
129
130
|
|
130
131
|
web_assembly_binary_not_found: "WebAssembly binary not found.",
|
131
|
-
web_assembly_binary_not_found_suggestion: "No WebAssembly binary found." \
|
132
|
-
"Check that your build
|
132
|
+
web_assembly_binary_not_found_suggestion: "No WebAssembly binary found. " \
|
133
|
+
"Check that your build script outputs the generated binary to the root of the directory. " \
|
133
134
|
"Generated binary should match the script name: <script_name>.wasm",
|
134
135
|
|
135
136
|
project_config_not_found: "Internal error - Script can't be created because the project's config file is missing from the repository.",
|
@@ -139,12 +140,20 @@ module Script
|
|
139
140
|
script_upload_cause: "Fail to upload script.",
|
140
141
|
script_upload_help: "Try again.",
|
141
142
|
|
143
|
+
script_too_large_cause: "The size of your Wasm binary file is too large.",
|
144
|
+
script_too_large_help: "It must be less than %{max_size}.",
|
145
|
+
|
142
146
|
api_library_not_found_cause: "Script can't be created because API library %{library_name} is missing from the dependencies",
|
143
147
|
api_library_not_found_help: "This error can occur because the API library was removed from your system or there is a problem with dependencies in the repository.",
|
144
148
|
|
145
149
|
language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
|
146
150
|
language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
|
147
151
|
no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
|
152
|
+
missing_env_file_variables: "The following variables are missing in the .env file: %s."\
|
153
|
+
" It might happen when the script hasn't been previously connected to an app."\
|
154
|
+
" To connect the script to an app, run {{command:%s script connect}}",
|
155
|
+
missing_push_options: "The following options are required: %s."\
|
156
|
+
" You can obtain them from the .env file generated after connecting the script to an app.",
|
148
157
|
},
|
149
158
|
|
150
159
|
create: {
|
@@ -154,6 +163,7 @@ module Script
|
|
154
163
|
Options:
|
155
164
|
{{command:--name=NAME}} Script project name. Use any string.
|
156
165
|
{{command:--api=TYPE}} Script API name. Allowed values: %2$s.
|
166
|
+
{{command:--language=LANGUAGE}} Programming language. Allowed values: %3$s.
|
157
167
|
HELP
|
158
168
|
|
159
169
|
error: {
|
@@ -163,6 +173,9 @@ module Script
|
|
163
173
|
change_directory_notice: "{{*}} Change directories to {{green:%s}} to run script commands",
|
164
174
|
creating: "Creating script",
|
165
175
|
created: "Created script",
|
176
|
+
preparing_project: "Preparing script project structure",
|
177
|
+
creating_wasm: "Creating configuration files",
|
178
|
+
created_wasm: "Configuration files created",
|
166
179
|
},
|
167
180
|
|
168
181
|
push: {
|
@@ -171,9 +184,13 @@ module Script
|
|
171
184
|
Usage: {{command:%s script push}}
|
172
185
|
Options:
|
173
186
|
{{command:[--force]}} Replaces the existing script on the app with this version.
|
187
|
+
{{command:[--api-key=API_KEY]}} The API key used to register an app with the script. This can be found on the app page on Partners Dashboard. Overrides the value in the .env file, if present.
|
188
|
+
{{command:[--api-secret=API_SECRET]}} The API secret of the app the script is registered with. Overrides the value in the .env file, if present.
|
189
|
+
{{command:[--uuid=UUID]}} The uuid of the script. Overrides the value in the .env file, if present.
|
174
190
|
HELP
|
175
191
|
|
176
192
|
error: {
|
193
|
+
operation_failed_no_uuid: "UUID is required to push in a CI environment.",
|
177
194
|
operation_failed_with_api_key: "Couldn't push script to app (API key: %{api_key}).",
|
178
195
|
operation_failed_no_api_key: "Couldn't push script to app.",
|
179
196
|
},
|
@@ -182,13 +199,14 @@ module Script
|
|
182
199
|
},
|
183
200
|
connect: {
|
184
201
|
connected: "Connected! Your project is now connected to {{green:%s}}",
|
185
|
-
missing_script: "No script has been selected.",
|
186
202
|
help: <<~HELP,
|
187
203
|
{{command:%s script connect}}: Connects an existing script to an app.
|
188
204
|
Usage: {{command:%s script connect}}
|
189
205
|
HELP
|
190
206
|
error: {
|
191
207
|
operation_failed: "Couldn't connect script to app.",
|
208
|
+
missing_env_file_variables: "The following variables are missing in the .env file: %s."\
|
209
|
+
" To connect the script to an app, either enter the value into the .env file or delete the .env file, then run {{command:%s script connect}}",
|
192
210
|
},
|
193
211
|
},
|
194
212
|
javy: {
|
@@ -206,7 +224,7 @@ module Script
|
|
206
224
|
|
207
225
|
project_deps: {
|
208
226
|
none_required: "{{v}} None required",
|
209
|
-
|
227
|
+
checking: "Checking dependencies",
|
210
228
|
installing: "Dependencies installing",
|
211
229
|
installed: "Missing dependencies installed",
|
212
230
|
},
|
@@ -224,6 +242,7 @@ module Script
|
|
224
242
|
building_script: "Building script",
|
225
243
|
built: "Built",
|
226
244
|
pushing: "Pushing",
|
245
|
+
pushing_script: "Pushing script",
|
227
246
|
pushed: "Pushed",
|
228
247
|
ensure_env: {
|
229
248
|
organization: "Partner organization {{green:%s (%s)}}.",
|
@@ -100,54 +100,68 @@ module Script
|
|
100
100
|
}
|
101
101
|
when Layers::Domain::Errors::MetadataNotFoundError
|
102
102
|
{
|
103
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.metadata_not_found_cause"),
|
103
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.metadata_not_found_cause", e.filename),
|
104
104
|
help_suggestion: ShopifyCLI::Context.message("script.error.metadata_not_found_help"),
|
105
105
|
}
|
106
|
+
when Layers::Domain::Errors::MissingScriptConfigFieldError
|
107
|
+
{
|
108
|
+
cause_of_error: ShopifyCLI::Context.message(
|
109
|
+
"script.error.missing_script_config_field_cause",
|
110
|
+
field: e.field,
|
111
|
+
filename: e.filename,
|
112
|
+
),
|
113
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_config_field_help"),
|
114
|
+
}
|
106
115
|
when Layers::Infrastructure::Errors::BuildError
|
107
116
|
{
|
108
117
|
cause_of_error: ShopifyCLI::Context.message("script.error.build_error_cause"),
|
109
118
|
help_suggestion: ShopifyCLI::Context.message("script.error.build_error_help"),
|
110
119
|
}
|
111
|
-
when Layers::Infrastructure::Errors::
|
112
|
-
{
|
113
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_config_yml_definition_cause"),
|
114
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_config_yml_definition_help"),
|
115
|
-
}
|
116
|
-
when Layers::Infrastructure::Errors::InvalidScriptJsonDefinitionError
|
120
|
+
when Layers::Infrastructure::Errors::ScriptConfigParseError
|
117
121
|
{
|
118
|
-
cause_of_error: ShopifyCLI::Context.message(
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_help"),
|
125
|
-
}
|
126
|
-
when Layers::Infrastructure::Errors::MissingScriptConfigYmlFieldError
|
127
|
-
{
|
128
|
-
cause_of_error: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_cause", e.field),
|
129
|
-
help_suggestion: ShopifyCLI::Context.message("script.error.missing_script_config_yml_field_help"),
|
122
|
+
cause_of_error: ShopifyCLI::Context.message(
|
123
|
+
"script.error.script_config_parse_error_cause",
|
124
|
+
filename: e.filename,
|
125
|
+
serialization_format: e.serialization_format,
|
126
|
+
),
|
127
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.script_config_parse_error_help"),
|
130
128
|
}
|
131
|
-
when Layers::Infrastructure::Errors::
|
129
|
+
when Layers::Infrastructure::Errors::NoScriptConfigFileError
|
132
130
|
{
|
133
|
-
cause_of_error: ShopifyCLI::Context.message(
|
134
|
-
|
131
|
+
cause_of_error: ShopifyCLI::Context.message(
|
132
|
+
"script.error.no_script_config_file_cause",
|
133
|
+
filename: e.filename,
|
134
|
+
),
|
135
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.no_script_config_file_help"),
|
135
136
|
}
|
136
|
-
when Layers::Infrastructure::Errors::
|
137
|
+
when Layers::Infrastructure::Errors::ScriptConfigurationDefinitionError
|
137
138
|
{
|
138
|
-
cause_of_error: ShopifyCLI::Context.message(
|
139
|
-
|
139
|
+
cause_of_error: ShopifyCLI::Context.message(
|
140
|
+
"script.error.configuration_definition_error_cause",
|
141
|
+
message: e.message,
|
142
|
+
filename: e.filename,
|
143
|
+
),
|
144
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_definition_error_help"),
|
140
145
|
}
|
141
146
|
when Layers::Infrastructure::Errors::ScriptConfigSyntaxError
|
142
147
|
{
|
143
|
-
cause_of_error: ShopifyCLI::Context.message(
|
148
|
+
cause_of_error: ShopifyCLI::Context.message(
|
149
|
+
"script.error.configuration_syntax_error_cause",
|
150
|
+
filename: e.filename,
|
151
|
+
),
|
144
152
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_syntax_error_help"),
|
145
153
|
}
|
154
|
+
when Layers::Infrastructure::Errors::ScriptEnvAppNotConnectedError
|
155
|
+
{
|
156
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.app_not_connected_cause"),
|
157
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.app_not_connected_help"),
|
158
|
+
}
|
146
159
|
when Layers::Infrastructure::Errors::ScriptConfigMissingKeysError
|
147
160
|
{
|
148
161
|
cause_of_error: ShopifyCLI::Context.message(
|
149
162
|
"script.error.configuration_missing_keys_error_cause",
|
150
|
-
missing_keys: e.missing_keys
|
163
|
+
missing_keys: e.missing_keys,
|
164
|
+
filename: e.filename,
|
151
165
|
),
|
152
166
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_missing_keys_error_help"),
|
153
167
|
}
|
@@ -155,7 +169,8 @@ module Script
|
|
155
169
|
{
|
156
170
|
cause_of_error: ShopifyCLI::Context.message(
|
157
171
|
"script.error.configuration_invalid_value_error_cause",
|
158
|
-
valid_input_modes: e.valid_input_modes
|
172
|
+
valid_input_modes: e.valid_input_modes,
|
173
|
+
filename: e.filename,
|
159
174
|
),
|
160
175
|
help_suggestion: ShopifyCLI::Context.message("script.error.configuration_invalid_value_error_help"),
|
161
176
|
}
|
@@ -163,7 +178,8 @@ module Script
|
|
163
178
|
{
|
164
179
|
cause_of_error: ShopifyCLI::Context.message(
|
165
180
|
"script.error.configuration_schema_field_missing_keys_error_cause",
|
166
|
-
missing_keys: e.missing_keys
|
181
|
+
missing_keys: e.missing_keys,
|
182
|
+
filename: e.filename,
|
167
183
|
),
|
168
184
|
help_suggestion: ShopifyCLI::Context.message(
|
169
185
|
"script.error.configuration_definition_schema_field_missing_keys_error_help"
|
@@ -173,7 +189,8 @@ module Script
|
|
173
189
|
{
|
174
190
|
cause_of_error: ShopifyCLI::Context.message(
|
175
191
|
"script.error.configuration_schema_field_invalid_value_error_cause",
|
176
|
-
valid_types: e.valid_types
|
192
|
+
valid_types: e.valid_types,
|
193
|
+
filename: e.filename,
|
177
194
|
),
|
178
195
|
help_suggestion: ShopifyCLI::Context.message(
|
179
196
|
"script.error.configuration_schema_field_invalid_value_error_help"
|
@@ -234,6 +251,11 @@ module Script
|
|
234
251
|
cause_of_error: ShopifyCLI::Context.message("script.error.script_upload_cause"),
|
235
252
|
help_suggestion: ShopifyCLI::Context.message("script.error.script_upload_help"),
|
236
253
|
}
|
254
|
+
when Layers::Infrastructure::Errors::ScriptTooLargeError
|
255
|
+
{
|
256
|
+
cause_of_error: ShopifyCLI::Context.message("script.error.script_too_large_cause"),
|
257
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.script_too_large_help", max_size: e.max_size),
|
258
|
+
}
|
237
259
|
when Layers::Infrastructure::Errors::APILibraryNotFoundError
|
238
260
|
{
|
239
261
|
cause_of_error: ShopifyCLI::Context
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "shopify_cli/theme/theme"
|
3
3
|
require "shopify_cli/theme/ignore_filter"
|
4
|
+
require "shopify_cli/theme/include_filter"
|
4
5
|
require "shopify_cli/theme/syncer"
|
5
6
|
|
6
7
|
module Theme
|
@@ -9,7 +10,10 @@ module Theme
|
|
9
10
|
options do |parser, flags|
|
10
11
|
parser.on("-n", "--nodelete") { flags[:nodelete] = true }
|
11
12
|
parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
|
13
|
+
parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
|
12
14
|
parser.on("-l", "--live") { flags[:live] = true }
|
15
|
+
parser.on("-d", "--development") { flags[:development] = true }
|
16
|
+
parser.on("-o", "--only=PATTERN") { |pattern| flags[:includes] = pattern }
|
13
17
|
parser.on("-x", "--ignore=PATTERN") do |pattern|
|
14
18
|
flags[:ignores] ||= []
|
15
19
|
flags[:ignores] << pattern
|
@@ -19,26 +23,16 @@ module Theme
|
|
19
23
|
def call(args, _name)
|
20
24
|
root = args.first || "."
|
21
25
|
delete = !options.flags[:nodelete]
|
26
|
+
theme = find_theme(root, **options.flags)
|
27
|
+
return if theme.nil?
|
22
28
|
|
23
|
-
|
24
|
-
ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
|
25
|
-
elsif options.flags[:live]
|
26
|
-
ShopifyCLI::Theme::Theme.live(@ctx, root: root)
|
27
|
-
else
|
28
|
-
form = Forms::Select.ask(
|
29
|
-
@ctx,
|
30
|
-
[],
|
31
|
-
title: @ctx.message("theme.pull.select"),
|
32
|
-
root: root,
|
33
|
-
)
|
34
|
-
return unless form
|
35
|
-
form.theme
|
36
|
-
end
|
37
|
-
|
29
|
+
include_filter = ShopifyCLI::Theme::IncludeFilter.new(options.flags[:includes])
|
38
30
|
ignore_filter = ShopifyCLI::Theme::IgnoreFilter.from_path(root)
|
39
31
|
ignore_filter.add_patterns(options.flags[:ignores]) if options.flags[:ignores]
|
40
32
|
|
41
|
-
syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme,
|
33
|
+
syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme,
|
34
|
+
include_filter: include_filter,
|
35
|
+
ignore_filter: ignore_filter)
|
42
36
|
begin
|
43
37
|
syncer.start_threads
|
44
38
|
CLI::UI::Frame.open(@ctx.message("theme.pull.pulling", theme.name, theme.id, theme.shop)) do
|
@@ -46,7 +40,7 @@ module Theme
|
|
46
40
|
end
|
47
41
|
@ctx.done(@ctx.message("theme.pull.done"))
|
48
42
|
rescue ShopifyCLI::API::APIRequestNotFoundError
|
49
|
-
@ctx.abort(@ctx.message("theme.pull.theme_not_found", theme.id))
|
43
|
+
@ctx.abort(@ctx.message("theme.pull.theme_not_found", "##{theme.id}"))
|
50
44
|
ensure
|
51
45
|
syncer.shutdown
|
52
46
|
end
|
@@ -55,6 +49,40 @@ module Theme
|
|
55
49
|
def self.help
|
56
50
|
ShopifyCLI::Context.message("theme.pull.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
|
57
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def find_theme(root, theme_id: nil, theme: nil, live: nil, development: nil, **_args)
|
56
|
+
if theme_id
|
57
|
+
@ctx.warn(@ctx.message("theme.pull.deprecated_themeid"))
|
58
|
+
return ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
|
59
|
+
end
|
60
|
+
|
61
|
+
if theme
|
62
|
+
selected_theme = ShopifyCLI::Theme::Theme.find_by_identifier(@ctx, root: root, identifier: theme)
|
63
|
+
return selected_theme || @ctx.abort(@ctx.message("theme.pull.theme_not_found", theme))
|
64
|
+
end
|
65
|
+
|
66
|
+
if live
|
67
|
+
return ShopifyCLI::Theme::Theme.live(@ctx, root: root)
|
68
|
+
end
|
69
|
+
|
70
|
+
if development
|
71
|
+
return ShopifyCLI::Theme::Theme.development(@ctx, root: root)
|
72
|
+
end
|
73
|
+
|
74
|
+
select_theme(root)
|
75
|
+
end
|
76
|
+
|
77
|
+
def select_theme(root)
|
78
|
+
form = Forms::Select.ask(
|
79
|
+
@ctx,
|
80
|
+
[],
|
81
|
+
title: @ctx.message("theme.pull.select"),
|
82
|
+
root: root,
|
83
|
+
)
|
84
|
+
form&.theme
|
85
|
+
end
|
58
86
|
end
|
59
87
|
end
|
60
88
|
end
|