shopify-cli 2.24.0 → 2.25.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 +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/project_types/extension/commands/serve.rb +57 -3
- data/lib/project_types/extension/extension_project.rb +8 -1
- data/lib/project_types/extension/loaders/project.rb +3 -2
- data/lib/project_types/extension/messages/messages.rb +21 -6
- data/lib/project_types/extension/models/server_config/development_renderer.rb +1 -1
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +18 -6
- data/lib/project_types/theme/commands/serve.rb +15 -3
- data/lib/project_types/theme/messages/messages.rb +4 -2
- data/lib/shopify_cli/commands/logout.rb +13 -2
- data/lib/shopify_cli/environment.rb +1 -1
- data/lib/shopify_cli/file_system_listener.rb +30 -0
- data/lib/shopify_cli/git.rb +116 -33
- data/lib/shopify_cli/identity_auth.rb +1 -0
- data/lib/shopify_cli/project.rb +1 -1
- data/lib/shopify_cli/tasks/ensure_project_type.rb +3 -1
- data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/certificate_manager.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/errors.rb +9 -0
- data/lib/shopify_cli/theme/dev_server/header_hash.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hooks/file_change_hook.rb +77 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_deleter.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/{hot-reload-no-script.html → hot_reload/resources/hot-reload-no-script.html} +0 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/resources/hot_reload.js +48 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/resources/sse_client.js +43 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/resources/theme.js +114 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/resources/theme_extension.js +121 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/script_injector.rb +57 -0
- data/lib/shopify_cli/theme/dev_server/hot_reload/sections_index.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +8 -76
- data/lib/shopify_cli/theme/dev_server/local_assets.rb +28 -28
- data/lib/shopify_cli/theme/dev_server/proxy.rb +33 -25
- data/lib/shopify_cli/theme/dev_server/proxy_param_builder.rb +82 -0
- data/lib/shopify_cli/theme/dev_server/reload_mode.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/remote_watcher/json_files_update_job.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/remote_watcher.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/sse.rb +1 -1
- data/lib/shopify_cli/theme/dev_server/watcher.rb +8 -9
- data/lib/shopify_cli/theme/dev_server/web_server.rb +1 -1
- data/lib/shopify_cli/theme/dev_server.rb +287 -99
- data/lib/shopify_cli/theme/extension/app_extension.rb +40 -0
- data/lib/shopify_cli/theme/extension/dev_server/hooks/file_change_hook.rb +68 -0
- data/lib/shopify_cli/theme/extension/dev_server/hot_reload/script_injector.rb +30 -0
- data/lib/shopify_cli/theme/extension/dev_server/hot_reload.rb +13 -0
- data/lib/shopify_cli/theme/extension/dev_server/local_assets.rb +30 -0
- data/lib/shopify_cli/theme/{dev_server/proxy/template_param_builder.rb → extension/dev_server/proxy_param_builder.rb} +26 -16
- data/lib/shopify_cli/theme/extension/dev_server/watcher.rb +47 -0
- data/lib/shopify_cli/theme/extension/dev_server.rb +150 -0
- data/lib/shopify_cli/theme/extension/host_theme.rb +104 -0
- data/lib/shopify_cli/theme/extension/syncer/extension_serve_job.rb +133 -0
- data/lib/shopify_cli/theme/extension/syncer/operation.rb +21 -0
- data/lib/shopify_cli/theme/extension/syncer.rb +81 -0
- data/lib/shopify_cli/theme/extension/ui/host_theme_progress_bar.rb +35 -0
- data/lib/shopify_cli/theme/ignore_helper.rb +31 -0
- data/lib/shopify_cli/theme/root.rb +62 -0
- data/lib/shopify_cli/theme/syncer.rb +12 -6
- data/lib/shopify_cli/theme/theme.rb +10 -52
- data/lib/shopify_cli/version.rb +1 -1
- metadata +27 -7
- data/.github/workflows/triage.yml +0 -22
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +0 -194
- data/lib/shopify_cli/theme/syncer/ignore_helper.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dadea44d5b05c23d4e74988aac50cae2713ee0809ad3b92b0a32a2ae51915a35
|
4
|
+
data.tar.gz: efaccb6aee8feb1bd714f4b6d2fa2ded67e522ac49eedaaa592fc3dbc066b04d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d283f76d8b288ad25487a50f86ff9482abef14f4d9ad7d95e006ea36a976f4cfb2410235e5a18cf12ea5c19d225117fd0516735b574c7c63551809422a102e19
|
7
|
+
data.tar.gz: 63e45bf4543a6743859c02a766e8b61c682703145d6230410d5200f76d9ca207c7ae996a1dc89dd8e918dfbb21d17aa17dd834f694df274f96a9fab29a4af606
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@ From version 2.6.0, the sections in this file adhere to the [keep a changelog](h
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## Version 2.25.0 - 2022-09-14
|
6
|
+
|
7
|
+
### Added
|
8
|
+
* [#2600](https://github.com/Shopify/shopify-cli/pull/2600): Add support to the `SIGTERM` signal
|
9
|
+
* [#2602](https://github.com/Shopify/shopify-cli/pull/2602): Add `--only/--ignore` support to the `theme serve` command
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
* [#2607](https://github.com/Shopify/shopify-cli/pull/2607): Fix proxy to redirect to host and port set by cli
|
13
|
+
|
5
14
|
## Version 2.24.0 - 2022-08-29
|
6
15
|
|
7
16
|
### Fixed
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Shopify CLI 2.0
|
2
2
|
|
3
|
-
<a href=""><img src="https://github.com/shopify/shopify-cli/workflows/
|
3
|
+
<a href="https://github.com/Shopify/shopify-cli/actions/workflows/shopify.yml"><img src="https://github.com/shopify/shopify-cli/actions/workflows/shopify.yml/badge.svg" alt="Shopify"></a>
|
4
4
|
<img src="https://img.shields.io/github/v/release/shopify/shopify-cli?include_prereleases&style=flat-square" alt="Latest Version">
|
5
5
|
<img src="https://img.shields.io/github/forks/shopify/shopify-cli?style=flat-square" alt="GitHub forks">
|
6
6
|
<img src="https://img.shields.io/github/stars/shopify/shopify-cli?style=flat-square" alt="GitHub stars">
|
@@ -17,6 +17,24 @@ module Extension
|
|
17
17
|
parser.on("-p", "--port=PORT", "Specify the port to use") do |port|
|
18
18
|
flags[:port] = port.to_i
|
19
19
|
end
|
20
|
+
parser.on("-T", "--theme=NAME_OR_ID", "Theme ID or name of the theme app extension host theme.") do |theme|
|
21
|
+
flags[:theme] = theme
|
22
|
+
end
|
23
|
+
parser.on("--api-key=API_KEY", "Connect your extension and app by inserting your app's API key") do |api_key|
|
24
|
+
flags[:api_key] = api_key.gsub('"', "")
|
25
|
+
end
|
26
|
+
parser.on("--api-secret=API_SECRET", "The API secret of the app the script is registered with.") do |api_secret|
|
27
|
+
flags[:api_secret] = api_secret.gsub('"', "")
|
28
|
+
end
|
29
|
+
parser.on("--extension-id=EXTENSION_ID", "The id of the extension's registration.") do |registration_id|
|
30
|
+
flags[:registration_id] = registration_id.gsub('"', "")
|
31
|
+
end
|
32
|
+
parser.on("--extension-title=EXTENSION_TITLE", "The title of the extension") do |extension_title|
|
33
|
+
flags[:extension_title] = extension_title.gsub('"', "")
|
34
|
+
end
|
35
|
+
parser.on("--extension-type=EXTENSION_TYPE", "The type of the extension") do |extension_type|
|
36
|
+
flags[:extension_type] = extension_type.gsub('"', "")
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
40
|
class RuntimeConfiguration
|
@@ -26,13 +44,27 @@ module Extension
|
|
26
44
|
property :resource_url, accepts: String, default: nil
|
27
45
|
property! :tunnel_requested, accepts: [true, false], reader: :tunnel_requested?, default: true
|
28
46
|
property :port, accepts: (1...(2**16))
|
47
|
+
property :theme, accepts: String, default: nil
|
48
|
+
property :api_key, accepts: String, default: nil
|
49
|
+
property :api_secret, accepts: String, default: nil
|
50
|
+
property :registration_id, accepts: String, default: nil
|
51
|
+
property :extension_title, accepts: String, default: nil
|
52
|
+
property :extension_type, accepts: String, default: nil
|
29
53
|
end
|
30
54
|
|
31
|
-
def call(
|
55
|
+
def call(args, _command_name)
|
56
|
+
@ctx.root = args.first || @ctx.root
|
57
|
+
|
32
58
|
config = RuntimeConfiguration.new(
|
33
59
|
tunnel_requested: tunnel_requested?,
|
34
60
|
resource_url: options.flags[:resource_url],
|
35
|
-
port: options.flags[:port]
|
61
|
+
port: options.flags[:port],
|
62
|
+
theme: options.flags[:theme],
|
63
|
+
api_key: options.flags[:api_key],
|
64
|
+
api_secret: options.flags[:api_secret],
|
65
|
+
registration_id: options.flags[:registration_id],
|
66
|
+
extension_title: options.flags[:extension_title],
|
67
|
+
extension_type: options.flags[:extension_type],
|
36
68
|
)
|
37
69
|
|
38
70
|
ShopifyCLI::Result
|
@@ -49,6 +81,23 @@ module Extension
|
|
49
81
|
|
50
82
|
private
|
51
83
|
|
84
|
+
def project
|
85
|
+
return super unless options.flags[:extension_type]
|
86
|
+
|
87
|
+
@project ||= Extension::Loaders::Project.load(
|
88
|
+
context: options.flags[:context],
|
89
|
+
directory: @ctx.root,
|
90
|
+
api_key: options.flags[:api_key],
|
91
|
+
api_secret: options.flags[:api_secret],
|
92
|
+
registration_id: options.flags[:registration_id],
|
93
|
+
env: {
|
94
|
+
ExtensionProjectKeys::TITLE_KEY => options.flags[:extension_title],
|
95
|
+
ExtensionProjectKeys::REGISTRATION_ID_KEY => options.flags[:registration_id],
|
96
|
+
ExtensionProjectKeys::SPECIFICATION_IDENTIFIER_KEY => options.flags[:extension_type],
|
97
|
+
}
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
52
101
|
def tunnel_requested?
|
53
102
|
tunnel = options.flags[:tunnel]
|
54
103
|
tunnel.nil? || !!tunnel
|
@@ -87,7 +136,12 @@ module Extension
|
|
87
136
|
context: @ctx,
|
88
137
|
tunnel_url: runtime_configuration.tunnel_url,
|
89
138
|
port: runtime_configuration.port,
|
90
|
-
|
139
|
+
theme: runtime_configuration.theme,
|
140
|
+
api_key: runtime_configuration.api_key,
|
141
|
+
api_secret: runtime_configuration.api_secret,
|
142
|
+
registration_id: runtime_configuration.registration_id,
|
143
|
+
resource_url: runtime_configuration.resource_url,
|
144
|
+
project: project,
|
91
145
|
)
|
92
146
|
runtime_configuration
|
93
147
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "shopify_cli"
|
3
|
+
require "shopify_cli/environment"
|
3
4
|
require "securerandom"
|
4
5
|
|
5
6
|
module Extension
|
@@ -82,7 +83,13 @@ module Extension
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def specification_identifier
|
85
|
-
|
86
|
+
key = ExtensionProjectKeys::SPECIFICATION_IDENTIFIER_KEY
|
87
|
+
|
88
|
+
if ShopifyCLI::Environment.run_as_subprocess?
|
89
|
+
get_extra_field(key)
|
90
|
+
else
|
91
|
+
config[key]
|
92
|
+
end
|
86
93
|
end
|
87
94
|
|
88
95
|
def registration_id?
|
@@ -3,12 +3,13 @@
|
|
3
3
|
module Extension
|
4
4
|
module Loaders
|
5
5
|
module Project
|
6
|
-
def self.load(context:, directory:, api_key:, registration_id:, api_secret:)
|
6
|
+
def self.load(context:, directory:, api_key:, registration_id:, api_secret:, env: {})
|
7
7
|
env_overrides = {
|
8
8
|
"SHOPIFY_API_KEY" => api_key,
|
9
9
|
"SHOPIFY_API_SECRET" => api_secret,
|
10
10
|
"EXTENSION_ID" => registration_id,
|
11
|
-
}.compact
|
11
|
+
}.compact.merge(env)
|
12
|
+
|
12
13
|
env_file_present = env_file_exists?(directory)
|
13
14
|
env = if env_file_present
|
14
15
|
ShopifyCLI::Resources::EnvFile.read(directory, overrides: env_overrides)
|
@@ -102,15 +102,32 @@ module Extension
|
|
102
102
|
serve: {
|
103
103
|
help: <<~HELP,
|
104
104
|
Serve your extension in a local simulator for development.
|
105
|
-
Usage: {{command:%s extension serve}}
|
105
|
+
Usage: {{command:%s extension serve [ ROOT ]}}
|
106
106
|
Options:
|
107
|
-
|
107
|
+
{{command:-p, --port=PORT}} Local port of the development serve.
|
108
|
+
{{command:-T, --theme=NAME_OR_ID}} Theme ID or name of the host theme.
|
109
|
+
{{command:--tunnel=TUNNEL}} Establish an ngrok tunnel (default: false).
|
110
|
+
{{command:--api-key=API_KEY}} Connect your extension and app by inserting your app's API key (which you can get from your app setup page on shopify.dev).
|
111
|
+
{{command:--api-secret=API_SECRET}} The API secret of the app the script is registered with.
|
112
|
+
{{command:--extension-id=EXTENSION_ID}} The id of the extension's registration.
|
108
113
|
HELP
|
109
|
-
frame_title: "
|
114
|
+
frame_title: "Viewing extension…",
|
110
115
|
no_available_ports_found: "No available ports found to run extension.",
|
111
116
|
serve_failure_message: "Failed to run extension code.",
|
112
117
|
serve_missing_information: "Missing shop or api_key.",
|
113
118
|
tunnel_already_running: "A tunnel running on another port has been detected. Close the tunnel and try again.",
|
119
|
+
preview_message: <<~PREVIEW_MESSAGE,
|
120
|
+
Enable your theme app extension:
|
121
|
+
{{green:%s}}
|
122
|
+
|
123
|
+
Setup your theme app extension in the host theme:
|
124
|
+
{{green:%s}}
|
125
|
+
|
126
|
+
Preview your theme app extension:
|
127
|
+
{{green:%s}}
|
128
|
+
|
129
|
+
(Use Ctrl-C to stop)
|
130
|
+
PREVIEW_MESSAGE
|
114
131
|
},
|
115
132
|
tunnel: {
|
116
133
|
duplicate_session: <<~MESSAGE,
|
@@ -267,9 +284,7 @@ module Extension
|
|
267
284
|
{{*}} You’re ready to start building {{green:%s}}!
|
268
285
|
MESSAGE
|
269
286
|
},
|
270
|
-
|
271
|
-
unsupported: "shopify extension serve is not supported for theme app extensions",
|
272
|
-
},
|
287
|
+
|
273
288
|
},
|
274
289
|
},
|
275
290
|
}
|
@@ -25,7 +25,7 @@ module Extension
|
|
25
25
|
when "checkout_post_purchase"
|
26
26
|
new(name: "@shopify/post-purchase-ui-extensions", version: "^0.13.2")
|
27
27
|
when "pos_ui_extension"
|
28
|
-
new(name: "@shopify/retail-ui-extensions", version: "^0.
|
28
|
+
new(name: "@shopify/retail-ui-extensions", version: "^0.12.0")
|
29
29
|
when "web_pixel_extension"
|
30
30
|
nil
|
31
31
|
else
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "base64"
|
3
3
|
require "json"
|
4
|
+
require "shopify_cli/theme/extension/dev_server"
|
4
5
|
|
5
6
|
module Extension
|
6
7
|
module Models
|
@@ -64,16 +65,27 @@ module Extension
|
|
64
65
|
"Theme App Extension"
|
65
66
|
end
|
66
67
|
|
67
|
-
def choose_port?(
|
68
|
-
|
68
|
+
def choose_port?(_ctx)
|
69
|
+
false
|
69
70
|
end
|
70
71
|
|
71
|
-
def establish_tunnel?(
|
72
|
-
|
72
|
+
def establish_tunnel?(_ctx)
|
73
|
+
false
|
73
74
|
end
|
74
75
|
|
75
|
-
def serve(
|
76
|
-
ctx
|
76
|
+
def serve(**options)
|
77
|
+
@ctx = options[:context]
|
78
|
+
root = options[:context]&.root
|
79
|
+
project = options[:project]
|
80
|
+
properties = options
|
81
|
+
.slice(:port, :theme)
|
82
|
+
.compact
|
83
|
+
.merge({
|
84
|
+
project: project,
|
85
|
+
specification_handler: self,
|
86
|
+
})
|
87
|
+
|
88
|
+
ShopifyCLI::Theme::Extension::DevServer.start(@ctx, root, **properties)
|
77
89
|
end
|
78
90
|
|
79
91
|
private
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "shopify_cli/theme/dev_server"
|
3
3
|
require "project_types/theme/commands/common/root_helper"
|
4
|
+
require "shopify_cli/theme/ignore_filter"
|
5
|
+
require "shopify_cli/theme/include_filter"
|
6
|
+
require "project_types/theme/conversions/include_glob"
|
7
|
+
require "project_types/theme/conversions/ignore_glob"
|
4
8
|
|
5
9
|
module Theme
|
6
10
|
class Command
|
@@ -12,6 +16,9 @@ module Theme
|
|
12
16
|
DEFAULT_HTTP_HOST = "127.0.0.1"
|
13
17
|
|
14
18
|
options do |parser, flags|
|
19
|
+
Conversions::IncludeGlob.register(parser)
|
20
|
+
Conversions::IgnoreGlob.register(parser)
|
21
|
+
|
15
22
|
parser.on("--host=HOST") { |host| flags[:host] = host.to_s }
|
16
23
|
parser.on("--port=PORT") { |port| flags[:port] = port.to_i }
|
17
24
|
parser.on("--poll") { flags[:poll] = true }
|
@@ -19,6 +26,14 @@ module Theme
|
|
19
26
|
parser.on("--theme-editor-sync") { flags[:editor_sync] = true }
|
20
27
|
parser.on("--stable") { flags[:stable] = true }
|
21
28
|
parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
|
29
|
+
parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
|
30
|
+
flags[:includes] ||= []
|
31
|
+
flags[:includes] |= pattern
|
32
|
+
end
|
33
|
+
parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
|
34
|
+
flags[:ignores] ||= []
|
35
|
+
flags[:ignores] |= pattern
|
36
|
+
end
|
22
37
|
end
|
23
38
|
|
24
39
|
def call(_args, name)
|
@@ -31,9 +46,6 @@ module Theme
|
|
31
46
|
ShopifyCLI::Theme::DevServer.start(@ctx, root, host: host, **flags) do |syncer|
|
32
47
|
UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delay_low_priority_files: true)
|
33
48
|
end
|
34
|
-
rescue ShopifyCLI::Theme::DevServer::AddressBindingError
|
35
|
-
raise ShopifyCLI::Abort,
|
36
|
-
ShopifyCLI::Context.message("theme.serve.error.address_binding_error", ShopifyCLI::TOOL_NAME)
|
37
49
|
end
|
38
50
|
|
39
51
|
def self.as_reload_mode(mode)
|
@@ -138,6 +138,8 @@ module Theme
|
|
138
138
|
viewing_theme: "Viewing theme…",
|
139
139
|
syncing_theme: "Syncing theme #%s on %s",
|
140
140
|
open_fail: "Couldn't open the theme",
|
141
|
+
stop_signal: "Stop signal: \"%s\"",
|
142
|
+
stopping: "Stopping…",
|
141
143
|
auth: {
|
142
144
|
error_message: <<~ERROR_MESSAGE,
|
143
145
|
It looks like you are using credentials that do not work with {{command:%s theme serve}}.
|
@@ -230,8 +232,6 @@ module Theme
|
|
230
232
|
},
|
231
233
|
},
|
232
234
|
error: {
|
233
|
-
address_binding_error: "Couldn't bind to localhost."\
|
234
|
-
" To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
|
235
235
|
invalid_subdirectory: <<~MESSAGE,
|
236
236
|
The presence of %s in the directory structure isn't supported.
|
237
237
|
|
@@ -262,6 +262,8 @@ module Theme
|
|
262
262
|
ENSURE_USER
|
263
263
|
address_already_in_use: "The address \"%s\" is already in use.",
|
264
264
|
try_port_option: "Use the --port=PORT option to serve the theme in a different port.",
|
265
|
+
binding_error: "Couldn't bind to localhost." \
|
266
|
+
" To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
|
265
267
|
},
|
266
268
|
check: {
|
267
269
|
help: <<~HELP,
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require "shopify_cli"
|
2
2
|
require "shopify_cli/theme/development_theme"
|
3
|
+
require "shopify_cli/theme/extension/host_theme"
|
3
4
|
|
4
5
|
module ShopifyCLI
|
5
6
|
module Commands
|
6
7
|
class Logout < ShopifyCLI::Command
|
7
8
|
def call(*)
|
8
9
|
try_delete_development_theme
|
10
|
+
try_delete_host_theme
|
11
|
+
|
9
12
|
ShopifyCLI::IdentityAuth.delete_tokens_and_keys
|
10
13
|
ShopifyCLI::DB.del(:shop) if has_shop?
|
11
14
|
ShopifyCLI::DB.del(:organization_id) if has_organization_id?
|
@@ -31,8 +34,16 @@ module ShopifyCLI
|
|
31
34
|
return unless has_shop?
|
32
35
|
|
33
36
|
ShopifyCLI::Theme::DevelopmentTheme.delete(@ctx)
|
34
|
-
rescue ShopifyCLI::API::APIRequestError, ShopifyCLI::Abort, ShopifyCLI::AbortSilent
|
35
|
-
|
37
|
+
rescue ShopifyCLI::API::APIRequestError, ShopifyCLI::Abort, ShopifyCLI::AbortSilent => e
|
38
|
+
@ctx.debug("[Logout Error]: #{e.message}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def try_delete_host_theme
|
42
|
+
return unless has_shop?
|
43
|
+
|
44
|
+
ShopifyCLI::Theme::Extension::HostTheme.delete(@ctx)
|
45
|
+
rescue ShopifyCLI::API::APIRequestError, ShopifyCLI::Abort, ShopifyCLI::AbortSilent => e
|
46
|
+
@ctx.debug("[Logout Error]: #{e.message}")
|
36
47
|
end
|
37
48
|
end
|
38
49
|
end
|
@@ -159,7 +159,7 @@ module ShopifyCLI
|
|
159
159
|
env_variable_truthy?(
|
160
160
|
Constants::EnvironmentVariables::MONORAIL_REAL_EVENTS,
|
161
161
|
env_variables: env_variables
|
162
|
-
)
|
162
|
+
) && !run_as_subprocess?(env_variables: env_variables)
|
163
163
|
end
|
164
164
|
|
165
165
|
def self.auth_token(env_variables: ENV)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "listen"
|
3
|
+
require "observer"
|
4
|
+
|
5
|
+
module ShopifyCLI
|
6
|
+
class FileSystemListener
|
7
|
+
include Observable
|
8
|
+
|
9
|
+
def initialize(root:, force_poll:, ignore_regex:)
|
10
|
+
@root = root
|
11
|
+
@force_poll = force_poll
|
12
|
+
@ignore_regex = ignore_regex
|
13
|
+
|
14
|
+
@listener = Listen.to(@root, force_polling: @force_poll, ignore: @ignore_regex) do |updated, added, removed|
|
15
|
+
changed
|
16
|
+
notify_observers(updated, added, removed)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
@listener.start
|
22
|
+
rescue ArgumentError
|
23
|
+
# Ignore errors during the transition of 'listen' events
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop
|
27
|
+
@listener.stop
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/shopify_cli/git.rb
CHANGED
@@ -46,12 +46,77 @@ module ShopifyCLI
|
|
46
46
|
end
|
47
47
|
|
48
48
|
##
|
49
|
-
#
|
50
|
-
# it will also output progress of the cloning process.
|
49
|
+
# returns array with components of git clone command
|
51
50
|
#
|
52
51
|
# #### Parameters
|
53
52
|
#
|
54
|
-
# * `
|
53
|
+
# * `repo` - repo url without branch name
|
54
|
+
# * `dest` - a filepath to where the repo should be cloned to
|
55
|
+
# * `branch` - branch name when cloning
|
56
|
+
#
|
57
|
+
# #### Returns
|
58
|
+
#
|
59
|
+
# * array of strings
|
60
|
+
#
|
61
|
+
# #### Example
|
62
|
+
#
|
63
|
+
# ["clone", "--single-branch", "--branch", "test-branch", "test-app"]
|
64
|
+
#
|
65
|
+
def git_clone_command(repo, dest, branch)
|
66
|
+
if branch
|
67
|
+
["clone", "--single-branch", "--branch", branch, repo, dest]
|
68
|
+
else
|
69
|
+
["clone", "--single-branch", repo, dest]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# calls git to clone a new repo into a supplied destination,
|
75
|
+
# it will also call a supplied block with the percentage of clone completion
|
76
|
+
#
|
77
|
+
# #### Parameters
|
78
|
+
#
|
79
|
+
# * `repo_with_branch` - a git url for git to clone the repo from
|
80
|
+
# * `dest` - a filepath to where the repo should be cloned to
|
81
|
+
# * `ctx` - the current running context of your command, defaults to a new context.
|
82
|
+
#
|
83
|
+
# #### Returns
|
84
|
+
#
|
85
|
+
# * `sha_string` - string of the sha of the most recent commit to the repo
|
86
|
+
#
|
87
|
+
# #### Example
|
88
|
+
#
|
89
|
+
# ShopifyCLI::Git.raw_clone('git@github.com:shopify/test.git', 'test-app')
|
90
|
+
#
|
91
|
+
def raw_clone(repo_with_branch, dest, ctx: Context.new)
|
92
|
+
if Dir.exist?(dest) && !Dir.empty?(dest)
|
93
|
+
ctx.abort(ctx.message("core.git.error.directory_exists"))
|
94
|
+
else
|
95
|
+
msg = []
|
96
|
+
# require at usage point to not slow down CLI startup
|
97
|
+
# https://github.com/Shopify/shopify-cli/pull/698#discussion_r444342445
|
98
|
+
require "open3"
|
99
|
+
|
100
|
+
repo, branch = repo_with_branch.split("#")
|
101
|
+
git_cmd = git_clone_command(repo, dest, branch)
|
102
|
+
|
103
|
+
success = Open3.popen3("git", *git_cmd, "--progress") do |_stdin, _stdout, stderr, thread|
|
104
|
+
msg = clone_progress(stderr, bar: nil)
|
105
|
+
|
106
|
+
thread.value
|
107
|
+
end.success?
|
108
|
+
|
109
|
+
ctx.abort((msg.join("\n"))) unless success
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# calls git to clone a new repo into a supplied destination,
|
115
|
+
# it will also output progress of the cloning process into a new progress bar
|
116
|
+
#
|
117
|
+
# #### Parameters
|
118
|
+
#
|
119
|
+
# * `repo_with_branch` - a git url for git to clone the repo from
|
55
120
|
# * `dest` - a filepath to where the repo should be cloned to
|
56
121
|
# * `ctx` - the current running context of your command, defaults to a new context.
|
57
122
|
#
|
@@ -63,17 +128,30 @@ module ShopifyCLI
|
|
63
128
|
#
|
64
129
|
# ShopifyCLI::Git.clone('git@github.com:shopify/test.git', 'test-app')
|
65
130
|
#
|
66
|
-
def clone(
|
67
|
-
if Dir.exist?(dest)
|
131
|
+
def clone(repo_with_branch, dest, ctx: Context.new)
|
132
|
+
if Dir.exist?(dest) && !Dir.empty?(dest)
|
68
133
|
ctx.abort(ctx.message("core.git.error.directory_exists"))
|
69
134
|
else
|
70
|
-
|
135
|
+
msg = []
|
136
|
+
# require at usage point to not slow down CLI startup
|
137
|
+
# https://github.com/Shopify/shopify-cli/pull/698#discussion_r444342445
|
138
|
+
require "open3"
|
139
|
+
|
140
|
+
repo, branch = repo_with_branch.split("#")
|
141
|
+
git_cmd = git_clone_command(repo, dest, branch)
|
142
|
+
|
71
143
|
success_message = ctx.message("core.git.cloned", dest)
|
144
|
+
|
72
145
|
CLI::UI::Frame.open(ctx.message("core.git.cloning", repo, dest), success_text: success_message) do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
146
|
+
CLI::UI::Progress.progress do |bar|
|
147
|
+
success = Open3.popen3("git", *git_cmd, "--progress") do |_stdin, _stdout, stderr, thread|
|
148
|
+
msg = clone_progress(stderr, bar: bar)
|
149
|
+
|
150
|
+
thread.value
|
151
|
+
end.success?
|
152
|
+
|
153
|
+
ctx.abort((msg.join("\n"))) unless success
|
154
|
+
bar.tick(set_percent: 1.0)
|
77
155
|
end
|
78
156
|
end
|
79
157
|
end
|
@@ -197,6 +275,34 @@ module ShopifyCLI
|
|
197
275
|
end
|
198
276
|
end
|
199
277
|
|
278
|
+
##
|
279
|
+
# handles showing the progress of the git clone command.
|
280
|
+
# if block given, assumes passing percent to block, otherwise
|
281
|
+
# increments bar for progress bar
|
282
|
+
#
|
283
|
+
# #### Parameters
|
284
|
+
#
|
285
|
+
# * `stderr` - Open3.popen3 output stream
|
286
|
+
# * `bar` - progress bar object to set percent
|
287
|
+
#
|
288
|
+
def clone_progress(stderr, bar: nil)
|
289
|
+
msg = []
|
290
|
+
|
291
|
+
while (line = stderr.gets)
|
292
|
+
msg << line.chomp
|
293
|
+
next unless line.strip.start_with?("Receiving objects:")
|
294
|
+
percent = (line.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
|
295
|
+
|
296
|
+
if block_given?
|
297
|
+
yield percent
|
298
|
+
elsif !bar.nil?
|
299
|
+
bar.tick(set_percent: percent)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
msg
|
304
|
+
end
|
305
|
+
|
200
306
|
private
|
201
307
|
|
202
308
|
def exec(*args, dir: Dir.pwd, default: nil, ctx: Context.new)
|
@@ -209,29 +315,6 @@ module ShopifyCLI
|
|
209
315
|
def rev_parse(*args, dir: nil, ctx: Context.new)
|
210
316
|
exec("rev-parse", *args, dir: dir, ctx: ctx)
|
211
317
|
end
|
212
|
-
|
213
|
-
def clone_progress(*git_command, ctx:)
|
214
|
-
CLI::UI::Progress.progress do |bar|
|
215
|
-
msg = []
|
216
|
-
require "open3"
|
217
|
-
|
218
|
-
success = Open3.popen3("git", *git_command, "--progress") do |_stdin, _stdout, stderr, thread|
|
219
|
-
while (line = stderr.gets)
|
220
|
-
msg << line.chomp
|
221
|
-
next unless line.strip.start_with?("Receiving objects:")
|
222
|
-
percent = (line.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
|
223
|
-
bar.tick(set_percent: percent)
|
224
|
-
next
|
225
|
-
end
|
226
|
-
|
227
|
-
thread.value
|
228
|
-
end.success?
|
229
|
-
|
230
|
-
ctx.abort(msg.join("\n")) unless success
|
231
|
-
bar.tick(set_percent: 1.0)
|
232
|
-
success
|
233
|
-
end
|
234
|
-
end
|
235
318
|
end
|
236
319
|
end
|
237
320
|
end
|
@@ -87,6 +87,7 @@ module ShopifyCLI
|
|
87
87
|
|
88
88
|
def fetch_or_auth_partners_token
|
89
89
|
if EnvAuthToken.partners_token_present?
|
90
|
+
return Environment.auth_token if Environment.run_as_subprocess?
|
90
91
|
return EnvAuthToken.fetch_exchanged_partners_token do |env_token|
|
91
92
|
exchange_partners_auth_token(env_token)
|
92
93
|
end
|
data/lib/shopify_cli/project.rb
CHANGED
@@ -109,7 +109,7 @@ module ShopifyCLI
|
|
109
109
|
|
110
110
|
def at(dir)
|
111
111
|
proj_dir = directory(dir)
|
112
|
-
|
112
|
+
if !proj_dir && !ShopifyCLI::Environment.run_as_subprocess?
|
113
113
|
raise(ShopifyCLI::Abort, Context.message("core.project.error.not_in_project"))
|
114
114
|
end
|
115
115
|
@at ||= Hash.new { |h, k| h[k] = new(directory: k) }
|
@@ -4,7 +4,9 @@ module ShopifyCLI
|
|
4
4
|
module Tasks
|
5
5
|
class EnsureProjectType < ShopifyCLI::Task
|
6
6
|
def call(ctx, project_type)
|
7
|
-
|
7
|
+
if project_type.to_sym == ShopifyCLI::Project.current_project_type || Environment.run_as_subprocess?
|
8
|
+
return true
|
9
|
+
end
|
8
10
|
ctx.abort(ctx.message("core.tasks.ensure_project_type.wrong_project_type", project_type))
|
9
11
|
end
|
10
12
|
end
|