shopify-cli 2.15.0 → 2.15.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/stale.yml +7 -2
- data/.vscode/settings.json +1 -2
- data/CHANGELOG.md +70 -19
- data/Gemfile +1 -0
- data/Gemfile.lock +39 -7
- data/Rakefile +48 -0
- data/ext/javy/hashes/javy-arm-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/ext/shopify-extensions/version +1 -1
- data/lib/project_types/extension/commands/check.rb +6 -1
- data/lib/project_types/extension/forms/questions/ask_template.rb +5 -8
- data/lib/project_types/extension/messages/messages.rb +11 -3
- data/lib/project_types/extension/models/development_server_requirements.rb +14 -7
- data/lib/project_types/extension/models/server_config/root.rb +2 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension.rb +57 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config.rb +33 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config_repository.rb +75 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +16 -1
- data/lib/project_types/extension/tasks/configure_options.rb +2 -1
- data/lib/project_types/extension/tasks/convert_server_config.rb +13 -2
- data/lib/project_types/extension/tasks/merge_server_config.rb +5 -2
- data/lib/project_types/script/cli.rb +1 -0
- data/lib/project_types/script/config/extension_points.yml +18 -0
- data/lib/project_types/script/layers/application/create_script.rb +14 -6
- data/lib/project_types/script/layers/infrastructure/errors.rb +17 -0
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +6 -21
- data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
- data/lib/project_types/script/layers/infrastructure/sparse_checkout_details.rb +35 -0
- data/lib/project_types/script/messages/messages.rb +3 -0
- data/lib/project_types/script/ui/error_handler.rb +11 -0
- data/lib/project_types/theme/cli.rb +1 -0
- data/lib/project_types/theme/commands/check.rb +4 -1
- data/lib/project_types/theme/commands/open.rb +2 -2
- data/lib/project_types/theme/commands/push.rb +1 -3
- data/lib/project_types/theme/commands/serve.rb +1 -0
- data/lib/project_types/theme/commands/share.rb +56 -0
- data/lib/project_types/theme/messages/messages.rb +71 -11
- data/lib/shopify_cli/changelog.rb +148 -0
- data/lib/shopify_cli/command.rb +7 -0
- data/lib/shopify_cli/command_options/command_serve_options.rb +10 -0
- data/lib/shopify_cli/commands/app/serve.rb +7 -7
- data/lib/shopify_cli/commands/login.rb +5 -2
- data/lib/shopify_cli/context.rb +13 -0
- data/lib/shopify_cli/git.rb +36 -0
- data/lib/shopify_cli/identity_auth.rb +24 -4
- data/lib/shopify_cli/messages/messages.rb +26 -5
- data/lib/shopify_cli/release.rb +194 -0
- data/lib/shopify_cli/sed.rb +19 -0
- data/lib/shopify_cli/services/app/create/rails_service.rb +10 -2
- data/lib/shopify_cli/services/app/serve/node_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/php_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/rails_service.rb +8 -28
- data/lib/shopify_cli/services/app/serve/serve_service.rb +57 -0
- data/lib/shopify_cli/services.rb +1 -0
- data/lib/shopify_cli/tasks/update_dashboard_urls.rb +7 -9
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +40 -13
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload/sections_index.rb +51 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +6 -1
- data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/remote_watcher/json_files_update_job.rb +35 -0
- data/lib/shopify_cli/theme/dev_server/remote_watcher.rb +44 -0
- data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -8
- data/lib/shopify_cli/theme/dev_server.rb +18 -5
- data/lib/shopify_cli/theme/file.rb +15 -4
- data/lib/shopify_cli/theme/syncer/checksums.rb +60 -0
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all.rb +39 -0
- data/lib/shopify_cli/theme/syncer/forms/apply_to_all_form.rb +35 -0
- data/lib/shopify_cli/theme/syncer/forms/base_strategy_form.rb +62 -0
- data/lib/shopify_cli/theme/syncer/forms/select_delete_strategy.rb +27 -0
- data/lib/shopify_cli/theme/syncer/forms/select_update_strategy.rb +28 -0
- data/lib/shopify_cli/theme/syncer/ignore_helper.rb +33 -0
- data/lib/shopify_cli/theme/syncer/json_delete_handler.rb +51 -0
- data/lib/shopify_cli/theme/syncer/json_update_handler.rb +82 -0
- data/lib/shopify_cli/theme/syncer/merger.rb +53 -0
- data/lib/shopify_cli/theme/syncer/operation.rb +1 -1
- data/lib/shopify_cli/theme/syncer.rb +79 -63
- data/lib/shopify_cli/theme/theme.rb +26 -4
- data/lib/shopify_cli/theme/theme_admin_api.rb +23 -8
- data/lib/shopify_cli/thread_pool/job.rb +10 -2
- data/lib/shopify_cli/thread_pool.rb +15 -3
- data/lib/shopify_cli/tunnel.rb +9 -0
- data/lib/shopify_cli/version.rb +1 -1
- data/shopify-cli.gemspec +3 -1
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +8 -0
- metadata +30 -3
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative "script_config"
|
2
|
+
module Extension
|
3
|
+
module Models
|
4
|
+
module SpecificationHandlers
|
5
|
+
module BeaconExtensionUtils
|
6
|
+
class ScriptConfigRepository
|
7
|
+
include SmartProperties
|
8
|
+
property! :ctx, accepts: ShopifyCLI::Context
|
9
|
+
|
10
|
+
def active?
|
11
|
+
ctx.file_exist?(filename)
|
12
|
+
end
|
13
|
+
|
14
|
+
def get!
|
15
|
+
raise RuntimeError.new("NoScriptConfigFile"), filename unless active?
|
16
|
+
|
17
|
+
content = ctx.read(filename)
|
18
|
+
hash = file_content_to_hash(content)
|
19
|
+
|
20
|
+
from_h(hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
def filename
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def from_h(hash)
|
30
|
+
Extension::Models::SpecificationHandlers::BeaconExtensionUtils::ScriptConfig.new(content: hash,
|
31
|
+
filename: filename)
|
32
|
+
end
|
33
|
+
|
34
|
+
def file_content_to_hash(file_content)
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
def hash_to_file_content(hash)
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class ScriptConfigYmlRepository < ScriptConfigRepository
|
44
|
+
def self.filename
|
45
|
+
"extension.config.yml"
|
46
|
+
end
|
47
|
+
|
48
|
+
def filename
|
49
|
+
ScriptConfigYmlRepository.filename
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def file_content_to_hash(file_content)
|
55
|
+
begin
|
56
|
+
hash = YAML.load(file_content)
|
57
|
+
rescue Psych::SyntaxError
|
58
|
+
raise parse_error
|
59
|
+
end
|
60
|
+
raise parse_error unless hash.is_a?(Hash)
|
61
|
+
hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def hash_to_file_content(hash)
|
65
|
+
YAML.dump(hash)
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_error
|
69
|
+
RuntimeError.new("ScriptConfigParseError #{filename}, serialization_format: \"YAML\" ")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -49,7 +49,7 @@ module Extension
|
|
49
49
|
|
50
50
|
locale_filenames.map do |filename|
|
51
51
|
locale = basename_for_locale_filename(filename)
|
52
|
-
[locale.to_sym,
|
52
|
+
[locale.to_sym, read_locale_file(filename)]
|
53
53
|
end
|
54
54
|
.yield_self do |encoded_files_by_locale|
|
55
55
|
{
|
@@ -62,6 +62,14 @@ module Extension
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
def read_locale_file(filename)
|
66
|
+
content = File.read(filename, mode: "rt", encoding: "bom|utf-8").strip
|
67
|
+
raise_invalid_encoding_error(filename) unless content.valid_encoding?
|
68
|
+
Base64.strict_encode64(content)
|
69
|
+
rescue ArgumentError
|
70
|
+
raise_invalid_encoding_error(filename)
|
71
|
+
end
|
72
|
+
|
65
73
|
def validate_no_duplicate_locale(locale_filenames)
|
66
74
|
duplicate_locale = locale_filenames
|
67
75
|
.map { |filename| basename_for_locale_filename(filename.downcase) }
|
@@ -149,6 +157,13 @@ module Extension
|
|
149
157
|
def basename_for_locale_filename(filename)
|
150
158
|
File.basename(File.basename(filename, ".json"), ".default")
|
151
159
|
end
|
160
|
+
|
161
|
+
def raise_invalid_encoding_error(filename)
|
162
|
+
raise(
|
163
|
+
ShopifyCLI::Abort,
|
164
|
+
ShopifyCLI::Context.message("#{L10N_ERROR_PREFIX}.invalid_file_encoding", filename)
|
165
|
+
)
|
166
|
+
end
|
152
167
|
end
|
153
168
|
end
|
154
169
|
end
|
@@ -13,7 +13,8 @@ module Extension
|
|
13
13
|
private
|
14
14
|
|
15
15
|
def configure_skip_build(attributes)
|
16
|
-
attributes[:options].merge!(skip_build: attributes[:identifier] == "theme_app_extension"
|
16
|
+
attributes[:options].merge!(skip_build: attributes[:identifier] == "theme_app_extension" ||
|
17
|
+
attributes[:identifier] == "beacon_extension")
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -18,7 +18,6 @@ module Extension
|
|
18
18
|
property! :type, accepts: String
|
19
19
|
|
20
20
|
DEFAULT_BUILD_DIR = "build"
|
21
|
-
DEFAULT_MAIN = Dir["src/*"].lazy.grep(/index.[jt]sx?/).first
|
22
21
|
|
23
22
|
def self.call(*args)
|
24
23
|
new(*args).call
|
@@ -37,7 +36,7 @@ module Extension
|
|
37
36
|
build_dir: hash.dig("development", "build_dir") || DEFAULT_BUILD_DIR,
|
38
37
|
renderer: renderer,
|
39
38
|
entries: Models::ServerConfig::DevelopmentEntries.new(
|
40
|
-
main: hash.dig("development", "entries", "main") ||
|
39
|
+
main: hash.dig("development", "entries", "main") || determine_default_entry_main(project_directory),
|
41
40
|
)
|
42
41
|
),
|
43
42
|
extension_points: hash.dig("extension_points"),
|
@@ -65,6 +64,18 @@ module Extension
|
|
65
64
|
def version(renderer, context)
|
66
65
|
Tasks::FindPackageFromJson.call(renderer, context: context).version
|
67
66
|
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def determine_default_entry_main(project_directory)
|
71
|
+
Dir.chdir(project_directory) do
|
72
|
+
Dir["src/*"].lazy.grep(/index.[jt]sx?/).first
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def project_directory
|
77
|
+
ExtensionProject.current.directory
|
78
|
+
end
|
68
79
|
end
|
69
80
|
end
|
70
81
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "shopify_cli"
|
3
3
|
require "yaml"
|
4
|
+
require "pathname"
|
4
5
|
|
5
6
|
module Extension
|
6
7
|
module Tasks
|
@@ -8,7 +9,7 @@ module Extension
|
|
8
9
|
include SmartProperties
|
9
10
|
|
10
11
|
property! :context, accepts: ShopifyCLI::Context
|
11
|
-
property! :file_path, accepts: ->(path) { Pathname(path).yield_self
|
12
|
+
property! :file_path, accepts: ->(path) { Pathname(path).yield_self(&:absolute?) }
|
12
13
|
property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
|
13
14
|
property :resource_url, accepts: String
|
14
15
|
property :tunnel_url, accepts: String
|
@@ -19,7 +20,9 @@ module Extension
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def call
|
22
|
-
config = YAML.load_file(file_path)
|
23
|
+
config = YAML.load_file(file_path) if File.file?(file_path)
|
24
|
+
config ||= {}
|
25
|
+
|
23
26
|
project = ExtensionProject.current
|
24
27
|
Tasks::ConvertServerConfig.call(
|
25
28
|
api_key: project.env.api_key,
|
@@ -62,6 +62,7 @@ module Script
|
|
62
62
|
autoload :ScriptService, Project.project_filepath("layers/infrastructure/script_service")
|
63
63
|
autoload :ScriptUploader, Project.project_filepath("layers/infrastructure/script_uploader")
|
64
64
|
autoload :ServiceLocator, Project.project_filepath("layers/infrastructure/service_locator")
|
65
|
+
autoload :SparseCheckoutDetails, Project.project_filepath("layers/infrastructure/sparse_checkout_details")
|
65
66
|
|
66
67
|
module Languages
|
67
68
|
autoload :ProjectCreator, Project.project_filepath("layers/infrastructure/languages/project_creator")
|
@@ -36,3 +36,21 @@ delivery_discount_types:
|
|
36
36
|
repo: "https://github.com/Shopify/scripts-apis-examples"
|
37
37
|
wasm:
|
38
38
|
repo: "https://github.com/Shopify/scripts-apis-examples"
|
39
|
+
product_discount_type:
|
40
|
+
beta: true
|
41
|
+
domain: 'discounts'
|
42
|
+
libraries:
|
43
|
+
wasm:
|
44
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
45
|
+
order_discount_type:
|
46
|
+
beta: true
|
47
|
+
domain: 'discounts'
|
48
|
+
libraries:
|
49
|
+
wasm:
|
50
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
51
|
+
shipping_discount_type:
|
52
|
+
beta: true
|
53
|
+
domain: 'discounts'
|
54
|
+
libraries:
|
55
|
+
wasm:
|
56
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
@@ -23,19 +23,23 @@ module Script
|
|
23
23
|
)
|
24
24
|
|
25
25
|
# remove the need to pass the whole extension-point object to the infra layer
|
26
|
-
sparse_checkout_repo = extension_point.libraries.for(language).repo
|
27
26
|
type = extension_point.dasherize_type
|
28
27
|
domain = extension_point.domain
|
29
28
|
|
29
|
+
sparse_checkout_details = Infrastructure::SparseCheckoutDetails.new(
|
30
|
+
repo: extension_point.libraries.for(language).repo,
|
31
|
+
branch: sparse_checkout_branch,
|
32
|
+
path: "#{domain}/#{language}/#{type}/default",
|
33
|
+
input_queries_enabled: input_queries_enabled?,
|
34
|
+
)
|
35
|
+
|
30
36
|
project_creator = Infrastructure::Languages::ProjectCreator.for(
|
31
37
|
ctx: ctx,
|
32
38
|
language: language,
|
33
39
|
type: type,
|
34
40
|
project_name: title,
|
35
41
|
path_to_project: project.id,
|
36
|
-
|
37
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
38
|
-
sparse_checkout_set_path: "#{domain}/#{language}/#{type}/default"
|
42
|
+
sparse_checkout_details: sparse_checkout_details,
|
39
43
|
)
|
40
44
|
|
41
45
|
install_dependencies(ctx, language, title, project_creator)
|
@@ -49,12 +53,12 @@ module Script
|
|
49
53
|
task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language)
|
50
54
|
CLI::UI::Frame.open(ctx.message(
|
51
55
|
"core.git.pulling_from_to",
|
52
|
-
project_creator.
|
56
|
+
project_creator.sparse_checkout_details.repo,
|
53
57
|
title,
|
54
58
|
)) do
|
55
59
|
UI::StrictSpinner.spin(ctx.message(
|
56
60
|
"core.git.pulling",
|
57
|
-
project_creator.
|
61
|
+
project_creator.sparse_checkout_details.repo,
|
58
62
|
title,
|
59
63
|
)) do |spinner|
|
60
64
|
project_creator.setup_dependencies
|
@@ -75,6 +79,10 @@ module Script
|
|
75
79
|
ensure
|
76
80
|
script_project_repo.change_to_initial_directory
|
77
81
|
end
|
82
|
+
|
83
|
+
def input_queries_enabled?
|
84
|
+
ShopifyCLI::Feature.enabled?(:scripts_beta_input_queries)
|
85
|
+
end
|
78
86
|
end
|
79
87
|
end
|
80
88
|
end
|
@@ -180,6 +180,23 @@ module Script
|
|
180
180
|
@max_size = max_size
|
181
181
|
end
|
182
182
|
end
|
183
|
+
|
184
|
+
class InvalidInputQueryErrors < ScriptProjectError
|
185
|
+
attr_reader :messages
|
186
|
+
|
187
|
+
def initialize(messages)
|
188
|
+
@messages = messages
|
189
|
+
super()
|
190
|
+
end
|
191
|
+
|
192
|
+
def input_query_path
|
193
|
+
ScriptProjectRepository::INPUT_QUERY_PATH
|
194
|
+
end
|
195
|
+
|
196
|
+
def message
|
197
|
+
messages.join("\n")
|
198
|
+
end
|
199
|
+
end
|
183
200
|
end
|
184
201
|
end
|
185
202
|
end
|
@@ -10,9 +10,7 @@ module Script
|
|
10
10
|
property! :type, accepts: String
|
11
11
|
property! :project_name, accepts: String
|
12
12
|
property! :path_to_project, accepts: String
|
13
|
-
property! :
|
14
|
-
property! :sparse_checkout_branch, accepts: String
|
15
|
-
property! :sparse_checkout_set_path, accepts: String
|
13
|
+
property! :sparse_checkout_details, accepts: SparseCheckoutDetails
|
16
14
|
|
17
15
|
def self.for(
|
18
16
|
ctx:,
|
@@ -20,9 +18,7 @@ module Script
|
|
20
18
|
type:,
|
21
19
|
project_name:,
|
22
20
|
path_to_project:,
|
23
|
-
|
24
|
-
sparse_checkout_branch:,
|
25
|
-
sparse_checkout_set_path:
|
21
|
+
sparse_checkout_details:
|
26
22
|
)
|
27
23
|
|
28
24
|
project_creators = {
|
@@ -36,33 +32,22 @@ module Script
|
|
36
32
|
type: type,
|
37
33
|
project_name: project_name,
|
38
34
|
path_to_project: path_to_project,
|
39
|
-
|
40
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
41
|
-
sparse_checkout_set_path: sparse_checkout_set_path
|
35
|
+
sparse_checkout_details: sparse_checkout_details,
|
42
36
|
)
|
43
37
|
end
|
44
38
|
|
45
39
|
# the sparse checkout process is common to all script types
|
46
40
|
def setup_dependencies
|
47
|
-
|
41
|
+
sparse_checkout_details.setup(ctx)
|
48
42
|
clean
|
49
43
|
end
|
50
44
|
|
51
45
|
private
|
52
46
|
|
53
|
-
def setup_sparse_checkout
|
54
|
-
ShopifyCLI::Git.sparse_checkout(
|
55
|
-
sparse_checkout_repo,
|
56
|
-
sparse_checkout_set_path,
|
57
|
-
sparse_checkout_branch,
|
58
|
-
ctx
|
59
|
-
)
|
60
|
-
end
|
61
|
-
|
62
47
|
def clean
|
63
|
-
source = File.join(path_to_project,
|
48
|
+
source = File.join(path_to_project, sparse_checkout_details.path, ".")
|
64
49
|
FileUtils.cp_r(source, path_to_project)
|
65
|
-
ctx.rm_rf(
|
50
|
+
ctx.rm_rf(sparse_checkout_details.path.split("/")[0])
|
66
51
|
ctx.rm_rf(".git")
|
67
52
|
end
|
68
53
|
|
@@ -83,6 +83,8 @@ module Script
|
|
83
83
|
valid_types: e["message"],
|
84
84
|
filename: script_config.filename,
|
85
85
|
)
|
86
|
+
elsif (errors = user_errors.filter { |err| err["tag"] == "input_query_validation_error" }).any?
|
87
|
+
raise Errors::InvalidInputQueryErrors, errors.map { |err| err["message"] }
|
86
88
|
elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
|
87
89
|
raise Domain::Errors::MetadataValidationError
|
88
90
|
else
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Layers
|
5
|
+
module Infrastructure
|
6
|
+
class SparseCheckoutDetails
|
7
|
+
include SmartProperties
|
8
|
+
property! :repo, accepts: String
|
9
|
+
property! :branch, accepts: String
|
10
|
+
property! :path, accepts: String
|
11
|
+
property! :input_queries_enabled, accepts: [true, false]
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.class == other.class &&
|
15
|
+
self.class.properties.all? { |name, _| self[name] == other[name] }
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup(ctx)
|
19
|
+
ShopifyCLI::Git.sparse_checkout(repo, patterns_to_checkout, branch, ctx)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def patterns_to_checkout
|
25
|
+
paths = [path]
|
26
|
+
unless input_queries_enabled
|
27
|
+
paths << "!#{path}/#{ScriptProjectRepository::INPUT_QUERY_PATH}"
|
28
|
+
paths << "!#{path}/schema.graphql"
|
29
|
+
end
|
30
|
+
paths.join(" ")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -86,6 +86,9 @@ module Script
|
|
86
86
|
"type(s): %{valid_types}.",
|
87
87
|
configuration_schema_field_invalid_value_error_help: "Change the value of the type.",
|
88
88
|
|
89
|
+
input_query_error_cause: "Input query is invalid:\n%{messages}\n\n",
|
90
|
+
input_query_error_help: "Fix the query in the `%{input_query_path}` file.",
|
91
|
+
|
89
92
|
script_not_found_cause: "Can't find script %s for Script API %s",
|
90
93
|
|
91
94
|
system_call_failure_cause: "Something went wrong while running: {{command:%{cmd}}}.",
|
@@ -216,6 +216,17 @@ module Script
|
|
216
216
|
"script.error.configuration_schema_field_invalid_value_error_help"
|
217
217
|
),
|
218
218
|
}
|
219
|
+
when Layers::Infrastructure::Errors::InvalidInputQueryErrors
|
220
|
+
{
|
221
|
+
cause_of_error: ShopifyCLI::Context.message(
|
222
|
+
"script.error.input_query_error_cause",
|
223
|
+
messages: e.messages.map { |message| " {{x}} #{message}." }.join("\n"),
|
224
|
+
),
|
225
|
+
help_suggestion: ShopifyCLI::Context.message(
|
226
|
+
"script.error.input_query_error_help",
|
227
|
+
input_query_path: e.input_query_path,
|
228
|
+
),
|
229
|
+
}
|
219
230
|
when Layers::Infrastructure::Errors::DependencyInstallError
|
220
231
|
{
|
221
232
|
cause_of_error: ShopifyCLI::Context.message("script.error.dependency_install_cause"),
|
@@ -16,6 +16,7 @@ module Theme
|
|
16
16
|
subcommand :Package, "package", Project.project_filepath("commands/package")
|
17
17
|
subcommand :Open, "open", Project.project_filepath("commands/open")
|
18
18
|
subcommand :List, "list", Project.project_filepath("commands/list")
|
19
|
+
subcommand :Share, "share", Project.project_filepath("commands/share")
|
19
20
|
subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
|
20
21
|
end
|
21
22
|
ShopifyCLI::Commands.register("Theme::Command", "theme")
|
@@ -24,7 +24,10 @@ module Theme
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def call(*)
|
27
|
-
@theme_check.run
|
27
|
+
@theme_check.run!
|
28
|
+
rescue ThemeCheck::Cli::Abort, ThemeCheck::ThemeCheckError => e
|
29
|
+
raise ShopifyCLI::Abort,
|
30
|
+
ShopifyCLI::Context.message("theme.check.error", e.full_message)
|
28
31
|
end
|
29
32
|
|
30
33
|
def self.help
|
@@ -17,8 +17,8 @@ module Theme
|
|
17
17
|
def call(_args, _name)
|
18
18
|
theme = find_theme(**options.flags)
|
19
19
|
|
20
|
-
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.editor_url))
|
21
|
-
@ctx.
|
20
|
+
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.preview_url, theme.editor_url))
|
21
|
+
@ctx.open_browser_url!(theme.preview_url)
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.help
|
@@ -104,9 +104,7 @@ module Theme
|
|
104
104
|
|
105
105
|
if unpublished
|
106
106
|
name = theme || ask_theme_name
|
107
|
-
|
108
|
-
new_theme.create
|
109
|
-
return new_theme
|
107
|
+
return ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root, name: name)
|
110
108
|
end
|
111
109
|
|
112
110
|
if theme
|
@@ -16,6 +16,7 @@ module Theme
|
|
16
16
|
parser.on("--port=PORT") { |port| flags[:port] = port.to_i }
|
17
17
|
parser.on("--poll") { flags[:poll] = true }
|
18
18
|
parser.on("--live-reload=MODE") { |mode| flags[:mode] = as_reload_mode(mode) }
|
19
|
+
parser.on("--theme-editor-sync") { flags[:editor_sync] = true }
|
19
20
|
end
|
20
21
|
|
21
22
|
def call(_args, name)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "shopify_cli/theme/theme"
|
4
|
+
require "shopify_cli/theme/syncer"
|
5
|
+
require "project_types/theme/commands/common/root_helper"
|
6
|
+
|
7
|
+
module Theme
|
8
|
+
class Command
|
9
|
+
class Share < ShopifyCLI::Command::SubCommand
|
10
|
+
include Common::RootHelper
|
11
|
+
|
12
|
+
recommend_default_ruby_range
|
13
|
+
|
14
|
+
def call(_args, name)
|
15
|
+
root = root_value(options, name)
|
16
|
+
theme = create_theme(root)
|
17
|
+
|
18
|
+
upload(theme)
|
19
|
+
|
20
|
+
@ctx.done(done_message(theme))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.help
|
24
|
+
tool = ShopifyCLI::TOOL_NAME
|
25
|
+
@ctx.message("theme.share.help", tool, tool)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_theme(root)
|
31
|
+
ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root)
|
32
|
+
end
|
33
|
+
|
34
|
+
def upload(theme)
|
35
|
+
syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme)
|
36
|
+
syncer.start_threads
|
37
|
+
|
38
|
+
CLI::UI::Frame.open(upload_message(theme)) do
|
39
|
+
UI::SyncProgressBar.new(syncer).progress(:upload_theme!)
|
40
|
+
end
|
41
|
+
|
42
|
+
raise ShopifyCLI::AbortSilent if syncer.has_any_error?
|
43
|
+
ensure
|
44
|
+
syncer.shutdown
|
45
|
+
end
|
46
|
+
|
47
|
+
def upload_message(theme)
|
48
|
+
@ctx.message("theme.share.upload", theme.name, theme.id, theme.shop)
|
49
|
+
end
|
50
|
+
|
51
|
+
def done_message(theme)
|
52
|
+
@ctx.message("theme.share.done", theme.name, theme.preview_url, theme.editor_url)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|