shopify-cli 2.11.2 → 2.12.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 +16 -1
- data/Gemfile.lock +1 -1
- data/bin/shopify +8 -4
- data/docs/users/installation.md +1 -44
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +114 -0
- data/lib/project_types/script/cli.rb +2 -0
- data/lib/project_types/script/commands/create.rb +2 -2
- data/lib/project_types/script/commands/push.rb +4 -6
- data/lib/project_types/script/config/extension_points.yml +0 -4
- data/lib/project_types/script/forms/create.rb +1 -14
- data/lib/project_types/script/layers/application/connect_app.rb +3 -2
- data/lib/project_types/script/layers/infrastructure/errors.rb +11 -0
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +2 -6
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +29 -18
- data/lib/project_types/script/layers/infrastructure/languages/tool_version_checker.rb +26 -0
- data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +3 -6
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +30 -19
- data/lib/project_types/script/loaders/project.rb +8 -7
- data/lib/project_types/script/messages/messages.rb +13 -12
- data/lib/project_types/script/ui/error_handler.rb +13 -0
- data/lib/project_types/theme/commands/common/root_helper.rb +65 -0
- data/lib/project_types/theme/commands/init.rb +2 -0
- data/lib/project_types/theme/commands/pull.rb +16 -8
- data/lib/project_types/theme/commands/push.rb +15 -7
- data/lib/project_types/theme/commands/serve.rb +6 -2
- data/lib/project_types/theme/conversions/base_glob.rb +50 -0
- data/lib/project_types/theme/conversions/ignore_glob.rb +15 -0
- data/lib/project_types/theme/conversions/include_glob.rb +15 -0
- data/lib/project_types/theme/messages/messages.rb +5 -5
- data/lib/shopify_cli/commands/app/create/node.rb +1 -0
- data/lib/shopify_cli/commands/app/create/php.rb +1 -0
- data/lib/shopify_cli/commands/app/create/rails.rb +1 -0
- data/lib/shopify_cli/commands/app/deploy.rb +1 -0
- data/lib/shopify_cli/environment.rb +6 -0
- data/lib/shopify_cli/git.rb +9 -1
- data/lib/shopify_cli/messages/messages.rb +21 -1
- data/lib/shopify_cli/tasks/ensure_git_dependency.rb +14 -0
- data/lib/shopify_cli/tasks.rb +1 -0
- data/lib/shopify_cli/theme/dev_server/proxy.rb +14 -2
- data/lib/shopify_cli/theme/include_filter.rb +4 -2
- data/lib/shopify_cli/theme/syncer.rb +13 -4
- data/lib/shopify_cli/version.rb +1 -1
- metadata +8 -2
@@ -20,21 +20,22 @@ module Script
|
|
20
20
|
project.env = env
|
21
21
|
project
|
22
22
|
rescue SmartProperties::InitializationError, SmartProperties::InvalidValueError => error
|
23
|
-
handle_error(error, context: context
|
23
|
+
handle_error(error, context: context)
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.handle_error(error, context
|
27
|
-
if
|
26
|
+
def self.handle_error(error, context:)
|
27
|
+
if ShopifyCLI::Environment.interactive?
|
28
28
|
properties_hash = { api_key: "SHOPIFY_API_KEY", secret: "SHOPIFY_API_SECRET" }
|
29
29
|
missing_env_variables = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
30
|
-
|
31
|
-
|
30
|
+
message = context.message("script.error.missing_env_file_variables", missing_env_variables)
|
31
|
+
message += context.message("script.error.missing_env_file_variables_solution", ShopifyCLI::TOOL_NAME)
|
32
32
|
else
|
33
33
|
properties_hash = { api_key: "--api-key", secret: "--api-secret" }
|
34
34
|
missing_options = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
|
35
|
-
|
36
|
-
|
35
|
+
message = context.message("script.error.missing_push_options_ci", missing_options)
|
36
|
+
message += context.message("script.error.missing_push_options_ci_solution", ShopifyCLI::TOOL_NAME)
|
37
37
|
end
|
38
|
+
raise ShopifyCLI::Abort, message
|
38
39
|
end
|
39
40
|
|
40
41
|
def self.env_file_exists?(directory)
|
@@ -113,6 +113,10 @@ module Script
|
|
113
113
|
dependency_install_cause: "Something went wrong while installing the needed dependencies.",
|
114
114
|
dependency_install_help: "Correct the errors.",
|
115
115
|
|
116
|
+
invalid_environment_cause: "Your environment %{tool} version, %{env_version}, "\
|
117
|
+
"is too low. It must be at least %{minimum_version}.",
|
118
|
+
invalid_environment_help: "Update %{tool}.",
|
119
|
+
|
116
120
|
failed_api_request_cause: "Something went wrong while communicating with Shopify.",
|
117
121
|
failed_api_request_help: "Try again.",
|
118
122
|
|
@@ -150,11 +154,13 @@ module Script
|
|
150
154
|
language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
|
151
155
|
language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
|
152
156
|
no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
157
|
+
missing_push_options_ci: "The following are missing: %s. ",
|
158
|
+
missing_push_options_ci_solution: "To add them to a CI environment:\n\t1. Run a connect command " \
|
159
|
+
"({{command:%1$s script connect}})\n\t2. Navigate to the .env file at the root of your project\n\t" \
|
160
|
+
"3. Copy the missing values and pass them through as arguments in {{command:%1$s script push}}",
|
161
|
+
missing_env_file_variables: "The following are missing in the .env file: %s. ",
|
162
|
+
missing_env_file_variables_solution: "To add it, connect your script with " \
|
163
|
+
"{{command:%1$s script connect}} ",
|
158
164
|
},
|
159
165
|
|
160
166
|
create: {
|
@@ -164,7 +170,7 @@ module Script
|
|
164
170
|
Options:
|
165
171
|
{{command:--name=NAME}} Script project name.
|
166
172
|
{{command:--api=TYPE}} Script API name. Supported values: %2$s.
|
167
|
-
{{command:--language=LANGUAGE}} Programming language. Supported values: %3$s.
|
173
|
+
{{command:--language=LANGUAGE}} Programming language. Defaults to wasm. Supported values: %3$s.
|
168
174
|
HELP
|
169
175
|
|
170
176
|
error: {
|
@@ -191,9 +197,7 @@ module Script
|
|
191
197
|
HELP
|
192
198
|
|
193
199
|
error: {
|
194
|
-
|
195
|
-
operation_failed_with_api_key: "Couldn't push script to app (API key: %{api_key}).",
|
196
|
-
operation_failed_no_api_key: "Couldn't push script to app.",
|
200
|
+
operation_failed: "Couldn't push script to app.",
|
197
201
|
},
|
198
202
|
|
199
203
|
script_pushed: "{{v}} Script pushed to app (API key: %{api_key}).",
|
@@ -206,8 +210,6 @@ module Script
|
|
206
210
|
HELP
|
207
211
|
error: {
|
208
212
|
operation_failed: "Couldn't connect script to app.",
|
209
|
-
missing_env_file_variables: "The following variables are missing in the .env file: %s."\
|
210
|
-
" To connect the script to an app, enter the value into the .env file or delete the .env file, and then run {{command:%s script connect}}",
|
211
213
|
},
|
212
214
|
},
|
213
215
|
javy: {
|
@@ -233,7 +235,6 @@ module Script
|
|
233
235
|
forms: {
|
234
236
|
create: {
|
235
237
|
select_extension_point: "Which Script API do you want to use?",
|
236
|
-
select_language: "Which language do you want to use?",
|
237
238
|
script_name: "What do you want to name your script?",
|
238
239
|
},
|
239
240
|
},
|
@@ -237,6 +237,19 @@ module Script
|
|
237
237
|
),
|
238
238
|
help_suggestion: ShopifyCLI::Context.message("script.error.graphql_error_help"),
|
239
239
|
}
|
240
|
+
when Layers::Infrastructure::Errors::InvalidEnvironmentError
|
241
|
+
{
|
242
|
+
cause_of_error: ShopifyCLI::Context.message(
|
243
|
+
"script.error.invalid_environment_cause",
|
244
|
+
tool: e.tool,
|
245
|
+
env_version: e.env_version,
|
246
|
+
minimum_version: e.minimum_version,
|
247
|
+
),
|
248
|
+
help_suggestion: ShopifyCLI::Context.message(
|
249
|
+
"script.error.invalid_environment_help",
|
250
|
+
tool: e.tool,
|
251
|
+
),
|
252
|
+
}
|
240
253
|
when Layers::Infrastructure::Errors::SystemCallFailureError
|
241
254
|
{
|
242
255
|
cause_of_error: ShopifyCLI::Context
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Theme
|
4
|
+
class Command
|
5
|
+
module Common
|
6
|
+
module RootHelper
|
7
|
+
def root_value(options, name)
|
8
|
+
argv = default_argv(options)
|
9
|
+
command_index = argv.index(name.to_s)
|
10
|
+
|
11
|
+
return "." if command_index.nil?
|
12
|
+
|
13
|
+
next_index = command_index + 1
|
14
|
+
option_by_key = options_map(options)
|
15
|
+
|
16
|
+
while next_index < argv.size
|
17
|
+
element = argv[next_index]
|
18
|
+
option = option_by_key[element]
|
19
|
+
|
20
|
+
return element if option.nil?
|
21
|
+
|
22
|
+
# Skip the option argument
|
23
|
+
next_index += 1 unless option.arg.nil?
|
24
|
+
|
25
|
+
# PATTERN arguments take precedence over the `root`
|
26
|
+
if option.arg =~ /PATTERN/
|
27
|
+
next_index += 1 while option_argument?(argv, next_index, option_by_key)
|
28
|
+
next
|
29
|
+
end
|
30
|
+
|
31
|
+
next_index += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
"."
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def default_argv(options)
|
40
|
+
options.parser.default_argv
|
41
|
+
end
|
42
|
+
|
43
|
+
def options_map(options)
|
44
|
+
map = {}
|
45
|
+
options_list(options).each do |option|
|
46
|
+
map[option.short.first] = option
|
47
|
+
map[option.long.first] = option
|
48
|
+
end
|
49
|
+
map
|
50
|
+
end
|
51
|
+
|
52
|
+
def options_list(options)
|
53
|
+
options.parser.top.list
|
54
|
+
end
|
55
|
+
|
56
|
+
def option_argument?(argv, next_index, option_by_key)
|
57
|
+
return false unless next_index < argv.size
|
58
|
+
|
59
|
+
element = argv[next_index]
|
60
|
+
option_by_key[element].nil?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -4,35 +4,43 @@ require "shopify_cli/theme/development_theme"
|
|
4
4
|
require "shopify_cli/theme/ignore_filter"
|
5
5
|
require "shopify_cli/theme/include_filter"
|
6
6
|
require "shopify_cli/theme/syncer"
|
7
|
+
require "project_types/theme/commands/common/root_helper"
|
8
|
+
require "project_types/theme/conversions/include_glob"
|
9
|
+
require "project_types/theme/conversions/ignore_glob"
|
7
10
|
|
8
11
|
module Theme
|
9
12
|
class Command
|
10
13
|
class Pull < ShopifyCLI::Command::SubCommand
|
14
|
+
include Common::RootHelper
|
15
|
+
|
11
16
|
recommend_default_ruby_range
|
12
17
|
|
13
18
|
options do |parser, flags|
|
19
|
+
Conversions::IncludeGlob.register(parser)
|
20
|
+
Conversions::IgnoreGlob.register(parser)
|
21
|
+
|
14
22
|
parser.on("-n", "--nodelete") { flags[:nodelete] = true }
|
15
23
|
parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
|
16
24
|
parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
|
17
25
|
parser.on("-l", "--live") { flags[:live] = true }
|
18
26
|
parser.on("-d", "--development") { flags[:development] = true }
|
19
|
-
parser.on("-o", "--only=PATTERN") do |pattern|
|
27
|
+
parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
|
20
28
|
flags[:includes] ||= []
|
21
|
-
flags[:includes]
|
29
|
+
flags[:includes] += pattern
|
22
30
|
end
|
23
|
-
parser.on("-x", "--ignore=PATTERN") do |pattern|
|
31
|
+
parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
|
24
32
|
flags[:ignores] ||= []
|
25
|
-
flags[:ignores]
|
33
|
+
flags[:ignores] += pattern
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
|
-
def call(
|
30
|
-
root =
|
37
|
+
def call(_args, name)
|
38
|
+
root = root_value(options, name)
|
31
39
|
delete = !options.flags[:nodelete]
|
32
40
|
theme = find_theme(root, **options.flags)
|
33
41
|
return if theme.nil?
|
34
42
|
|
35
|
-
include_filter = ShopifyCLI::Theme::IncludeFilter.new(options.flags[:includes])
|
43
|
+
include_filter = ShopifyCLI::Theme::IncludeFilter.new(root, options.flags[:includes])
|
36
44
|
ignore_filter = ShopifyCLI::Theme::IgnoreFilter.from_path(root)
|
37
45
|
ignore_filter.add_patterns(options.flags[:ignores]) if options.flags[:ignores]
|
38
46
|
|
@@ -75,7 +83,7 @@ module Theme
|
|
75
83
|
|
76
84
|
if development
|
77
85
|
dev_theme = ShopifyCLI::Theme::DevelopmentTheme.find(@ctx, root: root)
|
78
|
-
return dev_theme || @ctx.abort(@ctx.message("theme.pull.theme_not_found",
|
86
|
+
return dev_theme || @ctx.abort(@ctx.message("theme.pull.theme_not_found", "development"))
|
79
87
|
end
|
80
88
|
|
81
89
|
select_theme(root)
|
@@ -4,13 +4,21 @@ require "shopify_cli/theme/development_theme"
|
|
4
4
|
require "shopify_cli/theme/ignore_filter"
|
5
5
|
require "shopify_cli/theme/include_filter"
|
6
6
|
require "shopify_cli/theme/syncer"
|
7
|
+
require "project_types/theme/commands/common/root_helper"
|
8
|
+
require "project_types/theme/conversions/include_glob"
|
9
|
+
require "project_types/theme/conversions/ignore_glob"
|
7
10
|
|
8
11
|
module Theme
|
9
12
|
class Command
|
10
13
|
class Push < ShopifyCLI::Command::SubCommand
|
14
|
+
include Common::RootHelper
|
15
|
+
|
11
16
|
recommend_default_ruby_range
|
12
17
|
|
13
18
|
options do |parser, flags|
|
19
|
+
Conversions::IncludeGlob.register(parser)
|
20
|
+
Conversions::IgnoreGlob.register(parser)
|
21
|
+
|
14
22
|
parser.on("-n", "--nodelete") { flags[:nodelete] = true }
|
15
23
|
parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
|
16
24
|
parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
|
@@ -20,18 +28,18 @@ module Theme
|
|
20
28
|
parser.on("-j", "--json") { flags[:json] = true }
|
21
29
|
parser.on("-a", "--allow-live") { flags[:allow_live] = true }
|
22
30
|
parser.on("-p", "--publish") { flags[:publish] = true }
|
23
|
-
parser.on("-o", "--only=PATTERN") do |pattern|
|
31
|
+
parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
|
24
32
|
flags[:includes] ||= []
|
25
|
-
flags[:includes]
|
33
|
+
flags[:includes] += pattern
|
26
34
|
end
|
27
|
-
parser.on("-x", "--ignore=PATTERN") do |pattern|
|
35
|
+
parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
|
28
36
|
flags[:ignores] ||= []
|
29
|
-
flags[:ignores]
|
37
|
+
flags[:ignores] += pattern
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
33
|
-
def call(
|
34
|
-
root =
|
41
|
+
def call(_args, name)
|
42
|
+
root = root_value(options, name)
|
35
43
|
delete = !options.flags[:nodelete]
|
36
44
|
theme = find_theme(root, **options.flags)
|
37
45
|
return if theme.nil?
|
@@ -42,7 +50,7 @@ module Theme
|
|
42
50
|
return unless CLI::UI::Prompt.confirm(question)
|
43
51
|
end
|
44
52
|
|
45
|
-
include_filter = ShopifyCLI::Theme::IncludeFilter.new(options.flags[:includes])
|
53
|
+
include_filter = ShopifyCLI::Theme::IncludeFilter.new(root, options.flags[:includes])
|
46
54
|
ignore_filter = ShopifyCLI::Theme::IgnoreFilter.from_path(root)
|
47
55
|
ignore_filter.add_patterns(options.flags[:ignores]) if options.flags[:ignores]
|
48
56
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "shopify_cli/theme/dev_server"
|
3
|
+
require "project_types/theme/commands/common/root_helper"
|
3
4
|
|
4
5
|
module Theme
|
5
6
|
class Command
|
6
7
|
class Serve < ShopifyCLI::Command::SubCommand
|
8
|
+
include Common::RootHelper
|
9
|
+
|
7
10
|
recommend_default_ruby_range
|
8
11
|
|
9
12
|
DEFAULT_HTTP_HOST = "127.0.0.1"
|
@@ -15,10 +18,11 @@ module Theme
|
|
15
18
|
parser.on("--live-reload=MODE") { |mode| flags[:mode] = as_reload_mode(mode) }
|
16
19
|
end
|
17
20
|
|
18
|
-
def call(
|
21
|
+
def call(_args, name)
|
22
|
+
root = root_value(options, name)
|
19
23
|
flags = options.flags.dup
|
20
24
|
host = flags[:host] || DEFAULT_HTTP_HOST
|
21
|
-
ShopifyCLI::Theme::DevServer.start(@ctx,
|
25
|
+
ShopifyCLI::Theme::DevServer.start(@ctx, root, host: host, **flags) do |syncer|
|
22
26
|
UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delay_low_priority_files: true)
|
23
27
|
end
|
24
28
|
rescue ShopifyCLI::Theme::DevServer::AddressBindingError
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Theme
|
4
|
+
module Conversions
|
5
|
+
class BaseGlob
|
6
|
+
class << self
|
7
|
+
def register(parser)
|
8
|
+
parser.accept(self) { |_val| convert(parser) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert(parser)
|
12
|
+
argv = parser.default_argv
|
13
|
+
option_index = argv.index { |v| options.include?(v) }
|
14
|
+
|
15
|
+
return [] if option_index.nil?
|
16
|
+
|
17
|
+
start_index = option_index + 1
|
18
|
+
option_by_key = options_map(parser)
|
19
|
+
values = []
|
20
|
+
|
21
|
+
argv[start_index..-1].each do |value|
|
22
|
+
return values unless option_by_key[value].nil?
|
23
|
+
values << value
|
24
|
+
end
|
25
|
+
|
26
|
+
values
|
27
|
+
end
|
28
|
+
|
29
|
+
def options
|
30
|
+
raise "`#{self.class.name}#options` must be defined"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def options_map(parser)
|
36
|
+
map = {}
|
37
|
+
parser.top.list.each do |option|
|
38
|
+
map[option.short.first] = option
|
39
|
+
map[option.long.first] = option
|
40
|
+
end
|
41
|
+
map
|
42
|
+
end
|
43
|
+
|
44
|
+
def parameter?(value)
|
45
|
+
value.start_with?("-")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -65,8 +65,8 @@ module Theme
|
|
65
65
|
{{command:-j, --json}} Output JSON instead of a UI.
|
66
66
|
{{command:-a, --allow-live}} Allow push to a live theme.
|
67
67
|
{{command:-p, --publish}} Publish as the live theme after uploading.
|
68
|
-
{{command:-o, --only}} Upload only the specified files.
|
69
|
-
{{command:-x, --ignore}} Skip uploading the specified files.
|
68
|
+
{{command:-o, --only}} Upload only the specified files (Multiple flags allowed).
|
69
|
+
{{command:-x, --ignore}} Skip uploading the specified files (Multiple flags allowed).
|
70
70
|
|
71
71
|
Run without options to select theme from a list.
|
72
72
|
HELP
|
@@ -96,7 +96,7 @@ module Theme
|
|
96
96
|
help: <<~HELP,
|
97
97
|
Uploads the current theme as a development theme to the connected store, then prints theme editor and preview URLs to your terminal. While running, changes will push to the store in real time.
|
98
98
|
|
99
|
-
Usage: {{command:%s theme serve}}
|
99
|
+
Usage: {{command:%s theme serve [ ROOT ]}}
|
100
100
|
|
101
101
|
Options:
|
102
102
|
{{command:--port=PORT}} Local port to serve theme preview from.
|
@@ -202,8 +202,8 @@ module Theme
|
|
202
202
|
{{command:-l, --live}} Pull theme files from your remote live theme.
|
203
203
|
{{command:-d, --development}} Pull theme files from your remote development theme.
|
204
204
|
{{command:-n, --nodelete}} Runs the pull command without deleting local files.
|
205
|
-
{{command:-o, --only}} Download only the specified files.
|
206
|
-
{{command:-x, --ignore}} Skip downloading the specified files.
|
205
|
+
{{command:-o, --only}} Download only the specified files (Multiple flags allowed).
|
206
|
+
{{command:-x, --ignore}} Skip downloading the specified files (Multiple flags allowed).
|
207
207
|
|
208
208
|
Run without options to select theme from a list.
|
209
209
|
HELP
|
@@ -25,6 +25,12 @@ module ShopifyCLI
|
|
25
25
|
::Semantic::Version.new(out.chomp)
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.npm_version(context: Context.new)
|
29
|
+
out, err, stat = context.capture3("npm", "--version")
|
30
|
+
raise ShopifyCLI::Abort, err unless stat.success?
|
31
|
+
::Semantic::Version.new(out.chomp)
|
32
|
+
end
|
33
|
+
|
28
34
|
def self.interactive=(interactive)
|
29
35
|
@interactive = interactive
|
30
36
|
end
|
data/lib/shopify_cli/git.rb
CHANGED
@@ -4,7 +4,15 @@ module ShopifyCLI
|
|
4
4
|
# git.
|
5
5
|
class Git
|
6
6
|
class << self
|
7
|
-
# Check if Git
|
7
|
+
# Check if Git exists in the environment
|
8
|
+
def exists?(ctx)
|
9
|
+
_output, status = ctx.capture2e("git", "version")
|
10
|
+
status.success?
|
11
|
+
rescue Errno::ENOENT # git is not installed
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check if the current working directory is a Git repository
|
8
16
|
def available?(ctx)
|
9
17
|
_output, status = ctx.capture2e("git", "status")
|
10
18
|
status.success?
|
@@ -277,6 +277,24 @@ module ShopifyCLI
|
|
277
277
|
HELP
|
278
278
|
},
|
279
279
|
},
|
280
|
+
extension: {
|
281
|
+
push: {
|
282
|
+
checkout_ui_extension: {
|
283
|
+
localization: {
|
284
|
+
error: {
|
285
|
+
bundle_too_large: "Total size of all locale files must be less than %s.",
|
286
|
+
file_empty: "Locale file `%s` is empty.",
|
287
|
+
file_too_large: "Locale file `%s` too large; size must be less than %s.",
|
288
|
+
invalid_file_extension: "Invalid locale filename: `%s`; only .json files are allowed.",
|
289
|
+
invalid_locale_code: "Invalid locale filename: `%s`; locale code should be 2 or 3 letters,"\
|
290
|
+
" optionally followed by a two-letter region code, e.g. `fr-CA`.",
|
291
|
+
single_default_locale: "There must be one and only one locale identified as the default locale,"\
|
292
|
+
" e.g. `en.default.json`",
|
293
|
+
},
|
294
|
+
},
|
295
|
+
},
|
296
|
+
},
|
297
|
+
},
|
280
298
|
error_reporting: {
|
281
299
|
unhandled_error: {
|
282
300
|
message: "{{x}} {{red:An unexpected error occured.}}",
|
@@ -355,6 +373,7 @@ module ShopifyCLI
|
|
355
373
|
error: {
|
356
374
|
directory_exists: "Project directory already exists. Please create a project with a new name.",
|
357
375
|
no_branches_found: "Could not find any git branches",
|
376
|
+
nonexistent: "Git needs to be installed: https://git-scm.com/download",
|
358
377
|
repo_not_initiated:
|
359
378
|
"Git repo is not initiated. Please run {{command:git init}} and make at least one commit.",
|
360
379
|
no_commits_made: "No git commits have been made. Please make at least one commit.",
|
@@ -672,7 +691,8 @@ module ShopifyCLI
|
|
672
691
|
},
|
673
692
|
},
|
674
693
|
ensure_dev_store: {
|
675
|
-
could_not_verify_store: "Couldn't verify your store
|
694
|
+
could_not_verify_store: "Couldn't verify your store. If you don't have a development store set up, "\
|
695
|
+
"please create one in your Partners dashboard and run `shopify app connect`.",
|
676
696
|
convert_to_dev_store: <<~MESSAGE,
|
677
697
|
Do you want to convert %s to a development store?
|
678
698
|
Doing this will allow you to install your app, but the store will become {{bold:transfer-disabled}}.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "shopify_cli"
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
module Tasks
|
5
|
+
class EnsureGitDependency < ShopifyCLI::Task
|
6
|
+
def call(ctx)
|
7
|
+
return if ShopifyCLI::Environment.acceptance_test?
|
8
|
+
unless ShopifyCLI::Git.exists?(ctx)
|
9
|
+
raise ShopifyCLI::Abort, ctx.message("core.git.error.nonexistent")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/shopify_cli/tasks.rb
CHANGED
@@ -34,6 +34,7 @@ module ShopifyCLI
|
|
34
34
|
register :CreateApiClient, :create_api_client, "shopify_cli/tasks/create_api_client"
|
35
35
|
register :EnsureAuthenticated, :ensure_authenticated, "shopify_cli/tasks/ensure_authenticated"
|
36
36
|
register :EnsureEnv, :ensure_env, "shopify_cli/tasks/ensure_env"
|
37
|
+
register :EnsureGitDependency, :ensure_git_dependency, "shopify_cli/tasks/ensure_git_dependency"
|
37
38
|
register :EnsureLoopbackURL, :ensure_loopback_url, "shopify_cli/tasks/ensure_loopback_url"
|
38
39
|
register :EnsureProjectType, :ensure_project_type, "shopify_cli/tasks/ensure_project_type"
|
39
40
|
register :EnsureDevStore, :ensure_dev_store, "shopify_cli/tasks/ensure_dev_store"
|
@@ -3,7 +3,6 @@ require "net/http"
|
|
3
3
|
require "stringio"
|
4
4
|
require "time"
|
5
5
|
require "cgi"
|
6
|
-
|
7
6
|
require_relative "proxy/template_param_builder"
|
8
7
|
|
9
8
|
module ShopifyCLI
|
@@ -70,13 +69,26 @@ module ShopifyCLI
|
|
70
69
|
@core_endpoints << env["PATH_INFO"]
|
71
70
|
end
|
72
71
|
|
73
|
-
body = response.body
|
72
|
+
body = patch_body(env, response.body)
|
74
73
|
body = [body] unless body.respond_to?(:each)
|
75
74
|
[response.code, headers, body]
|
76
75
|
end
|
77
76
|
|
78
77
|
private
|
79
78
|
|
79
|
+
def patch_body(env, body)
|
80
|
+
return [""] unless body
|
81
|
+
|
82
|
+
body.gsub(%r{(data-.+=(["']))(http:|https:)?//#{@theme.shop}(.*)(\2)}) do |_|
|
83
|
+
match = Regexp.last_match
|
84
|
+
"#{match[1]}http://#{host(env)}#{match[4]}#{match[5]}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def host(env)
|
89
|
+
env["HTTP_HOST"]
|
90
|
+
end
|
91
|
+
|
80
92
|
def has_body?(headers)
|
81
93
|
headers["Content-Length"] || headers["Transfer-Encoding"]
|
82
94
|
end
|
@@ -9,7 +9,8 @@ module ShopifyCLI
|
|
9
9
|
|
10
10
|
attr_reader :globs, :regexes
|
11
11
|
|
12
|
-
def initialize(patterns = [])
|
12
|
+
def initialize(root, patterns = [])
|
13
|
+
@root = Pathname.new(root)
|
13
14
|
@patterns = patterns.nil? ? [] : patterns.compact.reject(&:empty?)
|
14
15
|
|
15
16
|
regexes, globs = patterns_to_regexes_and_globs(@patterns)
|
@@ -22,9 +23,10 @@ module ShopifyCLI
|
|
22
23
|
return true unless present?(@patterns)
|
23
24
|
|
24
25
|
path = path.to_s
|
25
|
-
|
26
26
|
return true if path.empty?
|
27
27
|
|
28
|
+
path = @root.join(path).to_s
|
29
|
+
|
28
30
|
regexes.each do |regex|
|
29
31
|
return true if regex_match?(regex, path)
|
30
32
|
end
|