shopify-cli 2.11.1 → 2.13.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/shopify.yml +2 -1
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +32 -0
- data/Gemfile.lock +14 -14
- data/bin/shopify +17 -4
- data/dev.yml +1 -1
- data/docs/users/installation.md +1 -44
- data/ext/javy/hashes/javy-arm-macos-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.2.0.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/lib/project_types/extension/commands/build.rb +0 -3
- data/lib/project_types/extension/commands/check.rb +0 -1
- data/lib/project_types/extension/commands/create.rb +0 -1
- data/lib/project_types/extension/commands/push.rb +0 -1
- data/lib/project_types/extension/commands/serve.rb +0 -1
- data/lib/project_types/extension/features/argo_setup_steps.rb +4 -6
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +114 -0
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +7 -1
- data/lib/project_types/extension/tasks/configure_features.rb +15 -2
- data/lib/project_types/extension/tasks/convert_server_config.rb +2 -1
- data/lib/project_types/script/cli.rb +2 -0
- data/lib/project_types/script/commands/create.rb +5 -5
- 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/errors.rb +1 -1
- data/lib/project_types/script/forms/create.rb +7 -20
- data/lib/project_types/script/layers/application/build_script.rb +22 -24
- data/lib/project_types/script/layers/application/connect_app.rb +3 -2
- data/lib/project_types/script/layers/application/create_script.rb +9 -10
- data/lib/project_types/script/layers/application/project_dependencies.rb +12 -14
- data/lib/project_types/script/layers/application/push_script.rb +2 -0
- data/lib/project_types/script/layers/domain/errors.rb +3 -3
- data/lib/project_types/script/layers/domain/push_package.rb +6 -0
- data/lib/project_types/script/layers/domain/script_config.rb +2 -4
- data/lib/project_types/script/layers/domain/script_project.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 +20 -9
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +29 -18
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -15
- 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 +22 -10
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +30 -19
- data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +0 -3
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -0
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +13 -25
- data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -2
- data/lib/project_types/script/loaders/project.rb +8 -7
- data/lib/project_types/script/messages/messages.rb +20 -19
- data/lib/project_types/script/ui/error_handler.rb +17 -4
- data/lib/project_types/script/ui/strict_spinner.rb +4 -6
- data/lib/project_types/theme/cli.rb +2 -0
- data/lib/project_types/theme/commands/common/root_helper.rb +71 -0
- data/lib/project_types/theme/commands/init.rb +2 -0
- data/lib/project_types/theme/commands/list.rb +34 -0
- data/lib/project_types/theme/commands/open.rb +65 -0
- data/lib/project_types/theme/commands/pull.rb +20 -10
- data/lib/project_types/theme/commands/push.rb +18 -12
- 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/forms/select.rb +11 -39
- data/lib/project_types/theme/messages/messages.rb +36 -7
- data/lib/project_types/theme/presenters/theme_presenter.rb +48 -0
- data/lib/project_types/theme/presenters/themes_presenter.rb +32 -0
- data/lib/shopify_cli/api.rb +1 -1
- data/lib/shopify_cli/command.rb +3 -1
- 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/constants.rb +3 -3
- data/lib/shopify_cli/context.rb +11 -13
- data/lib/shopify_cli/environment.rb +6 -0
- data/lib/shopify_cli/git.rb +9 -1
- data/lib/shopify_cli/messages/messages.rb +23 -3
- data/lib/shopify_cli/services/app/create/rails_service.rb +1 -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/dev_server.rb +1 -3
- data/lib/shopify_cli/theme/development_theme.rb +11 -0
- data/lib/shopify_cli/theme/include_filter.rb +4 -2
- data/lib/shopify_cli/theme/syncer.rb +20 -11
- data/lib/shopify_cli/theme/theme.rb +0 -4
- data/lib/shopify_cli/version.rb +1 -1
- data/shopify-dev +9 -11
- metadata +16 -2
@@ -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
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "project_types/theme/presenters/themes_presenter"
|
4
|
+
|
1
5
|
module Theme
|
2
6
|
module Forms
|
3
7
|
class Select < ShopifyCLI::Form
|
@@ -6,53 +10,21 @@ module Theme
|
|
6
10
|
|
7
11
|
def ask
|
8
12
|
self.theme = CLI::UI::Prompt.ask(title, allow_empty: false) do |handler|
|
9
|
-
|
13
|
+
theme_presenters.each do |presenter|
|
14
|
+
theme = presenter.theme
|
15
|
+
|
10
16
|
next if exclude_roles&.include?(theme.role)
|
11
17
|
next if !include_foreign_developments && theme.foreign_development?
|
12
|
-
|
18
|
+
|
19
|
+
handler.option(presenter.to_s(:short)) { theme }
|
13
20
|
end
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
17
24
|
private
|
18
25
|
|
19
|
-
def
|
20
|
-
|
21
|
-
.sort_by { |theme| theme_sort_order(theme) }
|
22
|
-
end
|
23
|
-
|
24
|
-
def theme_sort_order(theme)
|
25
|
-
case theme.role
|
26
|
-
when "live"
|
27
|
-
0
|
28
|
-
when "unpublished"
|
29
|
-
1
|
30
|
-
when "development"
|
31
|
-
2
|
32
|
-
else
|
33
|
-
3
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def theme_tags(theme)
|
38
|
-
color = case theme.role
|
39
|
-
when "live"
|
40
|
-
"green"
|
41
|
-
when "unpublished"
|
42
|
-
"yellow"
|
43
|
-
when "development"
|
44
|
-
"blue"
|
45
|
-
else
|
46
|
-
"italic"
|
47
|
-
end
|
48
|
-
|
49
|
-
tags = ["{{#{color}:[#{theme.role}]}}"]
|
50
|
-
|
51
|
-
if theme.current_development?
|
52
|
-
tags << "{{cyan:[yours]}}}}"
|
53
|
-
end
|
54
|
-
|
55
|
-
tags.join(" ")
|
26
|
+
def theme_presenters
|
27
|
+
Theme::Presenters::ThemesPresenter.new(ctx, root).all
|
56
28
|
end
|
57
29
|
end
|
58
30
|
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
|
@@ -87,7 +87,7 @@ module Theme
|
|
87
87
|
{{info:View your theme:}}
|
88
88
|
{{underline:%s}}
|
89
89
|
|
90
|
-
{{info:Customize this theme in the
|
90
|
+
{{info:Customize this theme in the Theme Editor:}}
|
91
91
|
{{underline:%s}}
|
92
92
|
DONE
|
93
93
|
name: "Theme name",
|
@@ -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.
|
@@ -130,7 +130,7 @@ module Theme
|
|
130
130
|
SERVING
|
131
131
|
customize_or_preview: <<~CUSTOMIZE_OR_PREVIEW,
|
132
132
|
|
133
|
-
Customize this theme in the
|
133
|
+
Customize this theme in the Theme Editor:
|
134
134
|
{{green:%s}}
|
135
135
|
|
136
136
|
Share this theme preview:
|
@@ -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
|
@@ -215,6 +215,35 @@ module Theme
|
|
215
215
|
WARN
|
216
216
|
theme_not_found: "Theme \"%s\" doesn't exist",
|
217
217
|
},
|
218
|
+
open: {
|
219
|
+
select: "Select a theme to open",
|
220
|
+
theme_not_found: "Theme \"%s\" doesn't exist",
|
221
|
+
details: <<~DETAILS,
|
222
|
+
{{*}} {{bold:%s}}
|
223
|
+
|
224
|
+
Customize your theme in the Theme Editor:
|
225
|
+
{{green:%s}}
|
226
|
+
|
227
|
+
DETAILS
|
228
|
+
help: <<~HELP,
|
229
|
+
{{command:%s theme open}}: Opens the preview of your remote theme.
|
230
|
+
|
231
|
+
Usage: {{command:%s theme open}}
|
232
|
+
|
233
|
+
Options:
|
234
|
+
{{command:-t, --theme=NAME_OR_ID}} Theme ID or name of your theme.
|
235
|
+
{{command:-l, --live}} Open your live theme.
|
236
|
+
{{command:-d, --development}} Open your development theme.
|
237
|
+
HELP
|
238
|
+
},
|
239
|
+
list: {
|
240
|
+
title: "{{*}} List of {{bold:%s}} themes:",
|
241
|
+
help: <<~HELP,
|
242
|
+
{{command:%s theme list}}: Lists your remote themes.
|
243
|
+
|
244
|
+
Usage: {{command:%s theme list}}
|
245
|
+
HELP
|
246
|
+
},
|
218
247
|
},
|
219
248
|
}.freeze
|
220
249
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Theme
|
6
|
+
module Presenters
|
7
|
+
class ThemePresenter
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
COLOR_BY_ROLE = {
|
11
|
+
"live" => "green",
|
12
|
+
"unpublished" => "yellow",
|
13
|
+
"development" => "blue",
|
14
|
+
}
|
15
|
+
|
16
|
+
attr_reader :theme
|
17
|
+
|
18
|
+
def_delegators :theme, :id, :name, :role
|
19
|
+
|
20
|
+
def initialize(theme)
|
21
|
+
@theme = theme
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s(mode = :long)
|
25
|
+
case mode
|
26
|
+
when :short
|
27
|
+
"{{bold:#{name} #{theme_tags}}}"
|
28
|
+
when :long
|
29
|
+
"{{green:##{id}}} {{bold:#{name} #{theme_tags}}}"
|
30
|
+
else
|
31
|
+
inspect
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def theme_tags
|
38
|
+
tags = ["{{#{tag_color}:[#{role}]}}"]
|
39
|
+
tags << "{{cyan:[yours]}}}}" if theme.current_development?
|
40
|
+
tags.join(" ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def tag_color
|
44
|
+
COLOR_BY_ROLE[role] || "italic"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "theme_presenter"
|
4
|
+
|
5
|
+
module Theme
|
6
|
+
module Presenters
|
7
|
+
class ThemesPresenter
|
8
|
+
ORDER_BY_ROLE = %w(live unpublished development)
|
9
|
+
|
10
|
+
def initialize(ctx, root)
|
11
|
+
@ctx = ctx
|
12
|
+
@root = root
|
13
|
+
end
|
14
|
+
|
15
|
+
def all
|
16
|
+
all_themes
|
17
|
+
.sort_by { |theme| order_by_role(theme) }
|
18
|
+
.map { |theme| ThemePresenter.new(theme) }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def order_by_role(theme)
|
24
|
+
ORDER_BY_ROLE.index(theme.role) || ORDER_BY_ROLE.size
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_themes
|
28
|
+
ShopifyCLI::Theme::Theme.all(@ctx, root: @root)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/shopify_cli/api.rb
CHANGED
@@ -85,7 +85,7 @@ module ShopifyCLI
|
|
85
85
|
end
|
86
86
|
rescue Errno::ETIMEDOUT, Timeout::Error
|
87
87
|
ctx.debug("timeout in #{method} #{uri} with X-Request-Id: #{headers["X-Request-Id"]}")
|
88
|
-
raise APIRequestTimeoutError
|
88
|
+
raise APIRequestTimeoutError, "Timeout"
|
89
89
|
end.retry_after(APIRequestRetriableError, retries: 3) do |e|
|
90
90
|
sleep(1) if e.is_a?(APIRequestThrottledError)
|
91
91
|
end
|
data/lib/shopify_cli/command.rb
CHANGED
@@ -100,8 +100,10 @@ module ShopifyCLI
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def check_node_version
|
103
|
+
return unless @compatible_node_range
|
104
|
+
|
103
105
|
context = Context.new
|
104
|
-
if
|
106
|
+
if context.which("node").nil?
|
105
107
|
raise ShopifyCLI::Abort, context.message("core.errors.missing_node")
|
106
108
|
end
|
107
109
|
|
data/lib/shopify_cli/context.rb
CHANGED
@@ -570,21 +570,19 @@ module ShopifyCLI
|
|
570
570
|
trap("INFO", "DEFAULT")
|
571
571
|
|
572
572
|
fork do
|
573
|
-
|
574
|
-
|
573
|
+
r, w = IO.pipe
|
574
|
+
@signal = false
|
575
|
+
trap("SIGINFO") do
|
576
|
+
@signal = true
|
577
|
+
w.write(0)
|
578
|
+
end
|
579
|
+
while r.read(1)
|
580
|
+
next unless @signal
|
575
581
|
@signal = false
|
576
|
-
|
577
|
-
@signal = true
|
578
|
-
w.write(0)
|
579
|
-
end
|
580
|
-
while r.read(1)
|
581
|
-
next unless @signal
|
582
|
-
@signal = false
|
583
|
-
yield
|
584
|
-
end
|
585
|
-
rescue Interrupt
|
586
|
-
exit(0)
|
582
|
+
yield
|
587
583
|
end
|
584
|
+
rescue Interrupt
|
585
|
+
exit(0)
|
588
586
|
end
|
589
587
|
end
|
590
588
|
|
@@ -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?
|
@@ -15,7 +15,7 @@ module ShopifyCLI
|
|
15
15
|
},
|
16
16
|
core: {
|
17
17
|
errors: {
|
18
|
-
missing_node: "Node is
|
18
|
+
missing_node: "Node is required to continue. Install node here: https://nodejs.org/en/download.",
|
19
19
|
option_parser: {
|
20
20
|
invalid_option: "The option {{command:%s}} is not supported.",
|
21
21
|
missing_argument: "The required argument {{command:%s}} is missing.",
|
@@ -42,7 +42,7 @@ module ShopifyCLI
|
|
42
42
|
invalid_type: "The type %s is not supported. The only supported types are"\
|
43
43
|
" {{command:[ rails | node | php ]}}",
|
44
44
|
help: <<~HELP,
|
45
|
-
{{command:%s app create}}: Creates a
|
45
|
+
{{command:%s app create}}: Creates a new project in a subdirectory.
|
46
46
|
Usage: {{command:%s app create [ rails | node | php ]}}
|
47
47
|
HELP
|
48
48
|
rails: {
|
@@ -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}}.
|
@@ -109,7 +109,7 @@ module ShopifyCLI
|
|
109
109
|
|
110
110
|
def check_ruby
|
111
111
|
ruby_version = Rails::Ruby.version(context)
|
112
|
-
return if ruby_version.satisfies?("~>2.5") || ruby_version.satisfies?("~>3.
|
112
|
+
return if ruby_version.satisfies?("~>2.5") || ruby_version.satisfies?("~>3.1.0")
|
113
113
|
context.abort(context.message("core.app.create.rails.error.invalid_ruby_version"))
|
114
114
|
end
|
115
115
|
|
@@ -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
|
@@ -28,7 +28,7 @@ module ShopifyCLI
|
|
28
28
|
|
29
29
|
def start(ctx, root, host: "127.0.0.1", port: 9292, poll: false, mode: ReloadMode.default)
|
30
30
|
@ctx = ctx
|
31
|
-
theme = DevelopmentTheme.
|
31
|
+
theme = DevelopmentTheme.find_or_create!(ctx, root: root)
|
32
32
|
ignore_filter = IgnoreFilter.from_path(root)
|
33
33
|
@syncer = Syncer.new(ctx, theme: theme, ignore_filter: ignore_filter)
|
34
34
|
watcher = Watcher.new(ctx, theme: theme, syncer: @syncer, ignore_filter: ignore_filter, poll: poll)
|
@@ -41,8 +41,6 @@ module ShopifyCLI
|
|
41
41
|
stopped = false
|
42
42
|
address = "http://#{host}:#{port}"
|
43
43
|
|
44
|
-
theme.ensure_exists!
|
45
|
-
|
46
44
|
trap("INT") do
|
47
45
|
stopped = true
|
48
46
|
stop
|
@@ -38,6 +38,8 @@ module ShopifyCLI
|
|
38
38
|
@ctx.debug("Created temporary development theme: #{@id}")
|
39
39
|
ShopifyCLI::DB.set(development_theme_id: @id)
|
40
40
|
end
|
41
|
+
|
42
|
+
self
|
41
43
|
end
|
42
44
|
|
43
45
|
def exists?
|
@@ -63,6 +65,15 @@ module ShopifyCLI
|
|
63
65
|
new(ctx).delete
|
64
66
|
end
|
65
67
|
|
68
|
+
def self.find(ctx, root: nil)
|
69
|
+
dev_theme = new(ctx, root: root)
|
70
|
+
dev_theme.exists? ? dev_theme : nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.find_or_create!(ctx, root: nil)
|
74
|
+
new(ctx, root: root).ensure_exists!
|
75
|
+
end
|
76
|
+
|
66
77
|
private
|
67
78
|
|
68
79
|
def generate_theme_name
|