shopify-cli 2.8.0 → 2.10.2
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/.github/ISSUE_TEMPLATE.md +18 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile.lock +1 -1
- data/RELEASING.md +4 -3
- data/ext/javy/javy.rb +1 -1
- data/lib/project_types/extension/commands/push.rb +2 -2
- data/lib/project_types/extension/messages/messages.rb +1 -1
- data/lib/project_types/extension/models/development_server.rb +2 -4
- data/lib/project_types/rails/gem.rb +1 -2
- data/lib/project_types/script/cli.rb +10 -0
- data/lib/project_types/script/commands/connect.rb +1 -1
- data/lib/project_types/script/commands/create.rb +8 -2
- data/lib/project_types/script/commands/push.rb +35 -12
- data/lib/project_types/script/config/extension_points.yml +12 -0
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/graphql/module_upload_url_generate.graphql +5 -1
- data/lib/project_types/script/layers/application/build_script.rb +6 -3
- data/lib/project_types/script/layers/application/connect_app.rb +11 -5
- data/lib/project_types/script/layers/application/extension_points.rb +50 -26
- data/lib/project_types/script/layers/application/project_dependencies.rb +1 -1
- data/lib/project_types/script/layers/application/push_script.rb +41 -30
- data/lib/project_types/script/layers/domain/errors.rb +10 -3
- data/lib/project_types/script/layers/domain/extension_point.rb +16 -2
- data/lib/project_types/script/layers/domain/push_package.rb +0 -3
- data/lib/project_types/script/layers/domain/script_config.rb +6 -4
- data/lib/project_types/script/layers/domain/script_project.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/errors.rb +47 -23
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -0
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +2 -12
- data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +15 -0
- data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +36 -0
- data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +18 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +7 -8
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -54
- data/lib/project_types/script/layers/infrastructure/script_service.rb +35 -12
- data/lib/project_types/script/layers/infrastructure/script_uploader.rb +22 -9
- data/lib/project_types/script/loaders/project.rb +44 -0
- data/lib/project_types/script/loaders/specification_handler.rb +22 -0
- data/lib/project_types/script/messages/messages.rb +38 -19
- data/lib/project_types/script/ui/error_handler.rb +52 -30
- data/lib/project_types/theme/commands/pull.rb +45 -17
- data/lib/project_types/theme/commands/push.rb +62 -27
- data/lib/project_types/theme/commands/serve.rb +5 -0
- data/lib/project_types/theme/messages/messages.rb +33 -18
- data/lib/shopify_cli/constants.rb +7 -2
- data/lib/shopify_cli/context.rb +66 -12
- data/lib/shopify_cli/core/executor.rb +4 -4
- data/lib/shopify_cli/environment.rb +50 -20
- data/lib/shopify_cli/identity_auth.rb +4 -3
- data/lib/shopify_cli/messages/messages.rb +2 -0
- data/lib/shopify_cli/method_object.rb +21 -9
- data/lib/shopify_cli/resources/env_file.rb +5 -1
- data/lib/shopify_cli/result.rb +61 -59
- data/lib/shopify_cli/task.rb +5 -3
- data/lib/shopify_cli/theme/dev_server/hot-reload.js +19 -1
- data/lib/shopify_cli/theme/dev_server/hot_reload.rb +18 -2
- data/lib/shopify_cli/theme/dev_server/proxy.rb +1 -0
- data/lib/shopify_cli/theme/dev_server/reload_mode.rb +34 -0
- data/lib/shopify_cli/theme/dev_server.rb +6 -21
- data/lib/shopify_cli/theme/file.rb +2 -2
- data/lib/shopify_cli/theme/filter/path_matcher.rb +38 -0
- data/lib/shopify_cli/theme/ignore_filter.rb +14 -18
- data/lib/shopify_cli/theme/include_filter.rb +43 -0
- data/lib/shopify_cli/theme/syncer.rb +17 -2
- data/lib/shopify_cli/theme/theme.rb +26 -4
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +6 -1
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +10 -5
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +6 -4
- data/vendor/deps/ruby2_keywords/LICENSE +22 -0
- data/vendor/deps/ruby2_keywords/README.md +67 -0
- data/vendor/deps/ruby2_keywords/Rakefile +54 -0
- data/vendor/deps/ruby2_keywords/lib/ruby2_keywords.rb +57 -0
- data/vendor/deps/ruby2_keywords/ruby2_keywords.gemspec +18 -0
- data/vendor/deps/ruby2_keywords/test/test_keyword.rb +41 -0
- metadata +16 -2
data/lib/shopify_cli/result.rb
CHANGED
|
@@ -363,70 +363,72 @@ module ShopifyCLI
|
|
|
363
363
|
Result::Failure.new(error)
|
|
364
364
|
end
|
|
365
365
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
366
|
+
class << self
|
|
367
|
+
##
|
|
368
|
+
# takes either a value or a block and chooses the appropriate result
|
|
369
|
+
# container based on the type of the value or the type of the block's return
|
|
370
|
+
# value. If the type is an exception, it is wrapped in a
|
|
371
|
+
# `ShopifyCli::Result::Failure` and otherwise in a
|
|
372
|
+
# `ShopifyCli::Result::Success`. If a block was provided instead of value, a
|
|
373
|
+
# `Proc` is returned and the result wrapping doesn't occur until the block
|
|
374
|
+
# is invoked.
|
|
375
|
+
#
|
|
376
|
+
# #### Parameters
|
|
377
|
+
#
|
|
378
|
+
# * `*args` should be an `Array` with zero or one element
|
|
379
|
+
# * `&block` should be a `Proc` that takes zero or one argument
|
|
380
|
+
#
|
|
381
|
+
# #### Returns
|
|
382
|
+
#
|
|
383
|
+
# Returns either a `Result::Success`, `Result::Failure` or a `Proc` that
|
|
384
|
+
# produces one of the former when invoked.
|
|
385
|
+
#
|
|
386
|
+
# #### Examples
|
|
387
|
+
#
|
|
388
|
+
# Result.wrap(1) # => ShopifyCli::Result::Success
|
|
389
|
+
# Result.wrap(RuntimeError.new) # => ShopifyCli::Result::Failure
|
|
390
|
+
#
|
|
391
|
+
# Result.wrap { 1 } # => Proc
|
|
392
|
+
# Result.wrap { 1 }.call # => ShopifyCli::Result::Success
|
|
393
|
+
# Result.wrap { raise }.call # => ShopifyCli::Result::Failure
|
|
394
|
+
#
|
|
395
|
+
# Result.wrap { |s| s.upcase }.call("hello").tap do |result|
|
|
396
|
+
# result # => Result::Success
|
|
397
|
+
# result.value # => "HELLO"
|
|
398
|
+
# end
|
|
399
|
+
#
|
|
400
|
+
ruby2_keywords def wrap(*values, &block)
|
|
401
|
+
raise ArgumentError, "expected either a value or a block" unless (values.length == 1) ^ block
|
|
401
402
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
end
|
|
413
|
-
else
|
|
414
|
-
->(*args) do
|
|
415
|
-
begin
|
|
416
|
-
wrap(block.call(*args))
|
|
417
|
-
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
418
|
-
wrap(error)
|
|
403
|
+
if values.length == 1
|
|
404
|
+
values.pop.yield_self do |value|
|
|
405
|
+
case value
|
|
406
|
+
when Result::Success, Result::Failure
|
|
407
|
+
value
|
|
408
|
+
when NilClass, Exception
|
|
409
|
+
Result.failure(value)
|
|
410
|
+
else
|
|
411
|
+
Result.success(value)
|
|
412
|
+
end
|
|
419
413
|
end
|
|
414
|
+
else
|
|
415
|
+
->(*args) do
|
|
416
|
+
begin
|
|
417
|
+
wrap(block.call(*args))
|
|
418
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
419
|
+
wrap(error)
|
|
420
|
+
end
|
|
421
|
+
end.ruby2_keywords
|
|
420
422
|
end
|
|
421
423
|
end
|
|
422
|
-
end
|
|
423
424
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
425
|
+
##
|
|
426
|
+
# Wraps the given block and invokes it with the passed arguments.
|
|
427
|
+
#
|
|
428
|
+
ruby2_keywords def call(*args, &block)
|
|
429
|
+
raise ArgumentError, "expected a block" unless block
|
|
430
|
+
wrap(&block).call(*args)
|
|
431
|
+
end
|
|
430
432
|
end
|
|
431
433
|
end
|
|
432
434
|
end
|
data/lib/shopify_cli/task.rb
CHANGED
|
@@ -15,9 +15,23 @@
|
|
|
15
15
|
eventSource.onerror = () => eventSource.close();
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
function reloadMode() {
|
|
19
|
+
var namespace = window.__SHOPIFY_CLI_ENV__;
|
|
20
|
+
return namespace.mode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isFullPageReloadMode(){
|
|
24
|
+
return reloadMode() === "full-page";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isReloadModeActive(){
|
|
28
|
+
return reloadMode() !== "off";
|
|
29
|
+
}
|
|
19
30
|
|
|
20
31
|
function isRefreshRequired(files) {
|
|
32
|
+
if (isFullPageReloadMode()) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
21
35
|
return files.some((file) => !isCssFile(file) && !isSectionFile(file));
|
|
22
36
|
}
|
|
23
37
|
|
|
@@ -119,4 +133,8 @@
|
|
|
119
133
|
}
|
|
120
134
|
}
|
|
121
135
|
}
|
|
136
|
+
|
|
137
|
+
if (isReloadModeActive()) {
|
|
138
|
+
connect();
|
|
139
|
+
}
|
|
122
140
|
})();
|
|
@@ -4,10 +4,11 @@ module ShopifyCLI
|
|
|
4
4
|
module Theme
|
|
5
5
|
module DevServer
|
|
6
6
|
class HotReload
|
|
7
|
-
def initialize(ctx, app, theme:, watcher:, ignore_filter: nil)
|
|
7
|
+
def initialize(ctx, app, theme:, watcher:, mode:, ignore_filter: nil)
|
|
8
8
|
@ctx = ctx
|
|
9
9
|
@app = app
|
|
10
10
|
@theme = theme
|
|
11
|
+
@mode = mode
|
|
11
12
|
@streams = SSE::Streams.new
|
|
12
13
|
@watcher = watcher
|
|
13
14
|
@watcher.add_observer(self, :notify_streams_of_file_change)
|
|
@@ -48,12 +49,27 @@ module ShopifyCLI
|
|
|
48
49
|
|
|
49
50
|
def inject_hot_reload_javascript(body)
|
|
50
51
|
hot_reload_js = ::File.read("#{__dir__}/hot-reload.js")
|
|
51
|
-
hot_reload_script =
|
|
52
|
+
hot_reload_script = [
|
|
53
|
+
"<script>",
|
|
54
|
+
params_js,
|
|
55
|
+
hot_reload_js,
|
|
56
|
+
"</script>",
|
|
57
|
+
].join("\n")
|
|
58
|
+
|
|
52
59
|
body = body.join.gsub("</body>", "#{hot_reload_script}\n</body>")
|
|
53
60
|
|
|
54
61
|
[body]
|
|
55
62
|
end
|
|
56
63
|
|
|
64
|
+
def params_js
|
|
65
|
+
env = { mode: @mode }
|
|
66
|
+
<<~JS
|
|
67
|
+
(() => {
|
|
68
|
+
window.__SHOPIFY_CLI_ENV__ = #{env.to_json};
|
|
69
|
+
})();
|
|
70
|
+
JS
|
|
71
|
+
end
|
|
72
|
+
|
|
57
73
|
def create_stream
|
|
58
74
|
stream = @streams.new
|
|
59
75
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShopifyCLI
|
|
4
|
+
module Theme
|
|
5
|
+
module DevServer
|
|
6
|
+
class ReloadMode
|
|
7
|
+
MODES = [:"hot-reload", :"full-page", :off]
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def default
|
|
11
|
+
:"hot-reload"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get!(mode)
|
|
15
|
+
MODES.find { |m| m == mode.to_sym } || raise_error(mode)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def raise_error(invalid_mode)
|
|
21
|
+
error_message = ShopifyCLI::Context.message("theme.serve.reload_mode_is_not_valid", invalid_mode)
|
|
22
|
+
help_message = ShopifyCLI::Context.message("theme.serve.try_a_valid_reload_mode", valid_modes)
|
|
23
|
+
|
|
24
|
+
ShopifyCLI::Context.abort(error_message, help_message)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def valid_modes
|
|
28
|
+
MODES.map { |v| "`#{v}`" }.join(", ")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -6,6 +6,7 @@ require_relative "syncer"
|
|
|
6
6
|
require_relative "dev_server/cdn_fonts"
|
|
7
7
|
require_relative "dev_server/hot_reload"
|
|
8
8
|
require_relative "dev_server/header_hash"
|
|
9
|
+
require_relative "dev_server/reload_mode"
|
|
9
10
|
require_relative "dev_server/local_assets"
|
|
10
11
|
require_relative "dev_server/proxy"
|
|
11
12
|
require_relative "dev_server/sse"
|
|
@@ -25,7 +26,7 @@ module ShopifyCLI
|
|
|
25
26
|
class << self
|
|
26
27
|
attr_accessor :ctx
|
|
27
28
|
|
|
28
|
-
def start(ctx, root, host: "127.0.0.1", port: 9292, poll: false)
|
|
29
|
+
def start(ctx, root, host: "127.0.0.1", port: 9292, poll: false, mode: ReloadMode.default)
|
|
29
30
|
@ctx = ctx
|
|
30
31
|
theme = DevelopmentTheme.new(ctx, root: root)
|
|
31
32
|
ignore_filter = IgnoreFilter.from_path(root)
|
|
@@ -36,7 +37,7 @@ module ShopifyCLI
|
|
|
36
37
|
@app = Proxy.new(ctx, theme: theme, syncer: @syncer)
|
|
37
38
|
@app = CdnFonts.new(@app, theme: theme)
|
|
38
39
|
@app = LocalAssets.new(ctx, @app, theme: theme)
|
|
39
|
-
@app = HotReload.new(ctx, @app, theme: theme, watcher: watcher, ignore_filter: ignore_filter)
|
|
40
|
+
@app = HotReload.new(ctx, @app, theme: theme, watcher: watcher, mode: mode, ignore_filter: ignore_filter)
|
|
40
41
|
stopped = false
|
|
41
42
|
address = "http://#{host}:#{port}"
|
|
42
43
|
|
|
@@ -83,7 +84,9 @@ module ShopifyCLI
|
|
|
83
84
|
ShopifyCLI::API::APIRequestUnauthorizedError
|
|
84
85
|
raise ShopifyCLI::Abort, @ctx.message("theme.serve.ensure_user", theme.shop)
|
|
85
86
|
rescue Errno::EADDRINUSE
|
|
86
|
-
|
|
87
|
+
error_message = @ctx.message("theme.serve.address_already_in_use", address)
|
|
88
|
+
help_message = @ctx.message("theme.serve.try_port_option")
|
|
89
|
+
@ctx.abort(error_message, help_message)
|
|
87
90
|
rescue Errno::EADDRNOTAVAIL
|
|
88
91
|
raise AddressBindingError, "Error binding to the address #{host}."
|
|
89
92
|
end
|
|
@@ -94,24 +97,6 @@ module ShopifyCLI
|
|
|
94
97
|
@syncer.shutdown
|
|
95
98
|
WebServer.shutdown
|
|
96
99
|
end
|
|
97
|
-
|
|
98
|
-
private
|
|
99
|
-
|
|
100
|
-
def abort_address_already_in_use(address)
|
|
101
|
-
open_frame(@ctx.message("theme.serve.already_in_use_error"), color: :red) do
|
|
102
|
-
@ctx.puts(@ctx.message("theme.serve.address_already_in_use", address))
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
open_frame(@ctx.message("theme.serve.try_this"), color: :green) do
|
|
106
|
-
@ctx.puts(@ctx.message("theme.serve.try_port_option"))
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
raise ShopifyCLI::AbortSilent
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def open_frame(title, color:, &block)
|
|
113
|
-
CLI::UI::Frame.open(title, color: CLI::UI.resolve_color(color), timing: false, &block)
|
|
114
|
-
end
|
|
115
100
|
end
|
|
116
101
|
end
|
|
117
102
|
end
|
|
@@ -18,7 +18,7 @@ module ShopifyCLI
|
|
|
18
18
|
|
|
19
19
|
def read
|
|
20
20
|
if text?
|
|
21
|
-
path.read
|
|
21
|
+
path.read(universal_newline: true)
|
|
22
22
|
else
|
|
23
23
|
path.read(mode: "rb")
|
|
24
24
|
end
|
|
@@ -27,7 +27,7 @@ module ShopifyCLI
|
|
|
27
27
|
def write(content)
|
|
28
28
|
path.parent.mkpath unless path.parent.directory?
|
|
29
29
|
if text?
|
|
30
|
-
path.write(content)
|
|
30
|
+
path.write(content, universal_newline: true)
|
|
31
31
|
else
|
|
32
32
|
path.write(content, 0, mode: "wb")
|
|
33
33
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShopifyCLI
|
|
4
|
+
module Theme
|
|
5
|
+
module Filter
|
|
6
|
+
module PathMatcher
|
|
7
|
+
def regex_match?(regex, path)
|
|
8
|
+
regex.match?(path)
|
|
9
|
+
rescue StandardError
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def glob_match?(glob, path)
|
|
14
|
+
!!::File.fnmatch?(glob, path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def regex?(pattern)
|
|
18
|
+
pattern.start_with?("/") && pattern.end_with?("/")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def as_regex(pattern)
|
|
22
|
+
Regexp.new(pattern.gsub(%r{^\/|\/$}, ""))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def as_glob(pattern)
|
|
26
|
+
# if specifying a directory, match everything below it
|
|
27
|
+
pattern += "*" if pattern.end_with?("/")
|
|
28
|
+
|
|
29
|
+
# The pattern will be scoped to root directory, so it should match anything
|
|
30
|
+
# within that space
|
|
31
|
+
pattern.prepend("*") unless pattern.start_with?("*")
|
|
32
|
+
|
|
33
|
+
pattern
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "filter/path_matcher"
|
|
4
|
+
|
|
3
5
|
module ShopifyCLI
|
|
4
6
|
module Theme
|
|
5
7
|
class IgnoreFilter
|
|
8
|
+
include Filter::PathMatcher
|
|
9
|
+
|
|
6
10
|
FILE = ".shopifyignore"
|
|
7
11
|
|
|
8
12
|
DEFAULT_REGEXES = [
|
|
@@ -72,11 +76,11 @@ module ShopifyCLI
|
|
|
72
76
|
return true if path.empty?
|
|
73
77
|
|
|
74
78
|
regexes.each do |regex|
|
|
75
|
-
return true if regex
|
|
79
|
+
return true if regex_match?(regex, path)
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
globs.each do |glob|
|
|
79
|
-
return true if
|
|
83
|
+
return true if glob_match?(glob, path)
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
false
|
|
@@ -91,24 +95,16 @@ module ShopifyCLI
|
|
|
91
95
|
new_regexes = DEFAULT_REGEXES.dup
|
|
92
96
|
new_globs = DEFAULT_GLOBS.dup
|
|
93
97
|
|
|
94
|
-
patterns
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
patterns
|
|
99
|
+
.map(&:strip)
|
|
100
|
+
.each do |pattern|
|
|
101
|
+
if regex?(pattern)
|
|
102
|
+
new_regexes << as_regex(pattern)
|
|
103
|
+
else
|
|
104
|
+
new_globs << as_glob(pattern)
|
|
105
|
+
end
|
|
100
106
|
end
|
|
101
107
|
|
|
102
|
-
# if specifying a directory, match everything below it
|
|
103
|
-
pattern += "*" if pattern.end_with?("/")
|
|
104
|
-
|
|
105
|
-
# The pattern will be scoped to root directory, so it should match anything
|
|
106
|
-
# within that space
|
|
107
|
-
pattern.prepend("*") unless pattern.start_with?("*")
|
|
108
|
-
|
|
109
|
-
new_globs << pattern
|
|
110
|
-
end
|
|
111
|
-
|
|
112
108
|
[new_regexes, new_globs]
|
|
113
109
|
end
|
|
114
110
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "filter/path_matcher"
|
|
4
|
+
|
|
5
|
+
module ShopifyCLI
|
|
6
|
+
module Theme
|
|
7
|
+
class IncludeFilter
|
|
8
|
+
include Filter::PathMatcher
|
|
9
|
+
|
|
10
|
+
def initialize(pattern = nil)
|
|
11
|
+
@pattern = pattern
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def match?(path)
|
|
15
|
+
return true unless present?(@pattern)
|
|
16
|
+
|
|
17
|
+
if regex_pattern?
|
|
18
|
+
regex_match?(regex_pattern, path)
|
|
19
|
+
else
|
|
20
|
+
glob_match?(glob_pattern, path)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def present?(pattern)
|
|
27
|
+
!pattern.nil? && !pattern.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def regex_pattern?
|
|
31
|
+
@is_regex_pattern ||= regex?(@pattern)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def regex_pattern
|
|
35
|
+
@regex_pattern ||= as_regex(@pattern)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def glob_pattern
|
|
39
|
+
@glob_pattern ||= as_glob(@pattern)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -16,13 +16,15 @@ module ShopifyCLI
|
|
|
16
16
|
API_VERSION = "unstable"
|
|
17
17
|
|
|
18
18
|
attr_reader :checksums
|
|
19
|
+
attr_accessor :include_filter
|
|
19
20
|
attr_accessor :ignore_filter
|
|
20
21
|
|
|
21
22
|
def_delegators :@error_reporter, :has_any_error?
|
|
22
23
|
|
|
23
|
-
def initialize(ctx, theme:, ignore_filter: nil)
|
|
24
|
+
def initialize(ctx, theme:, include_filter: nil, ignore_filter: nil)
|
|
24
25
|
@ctx = ctx
|
|
25
26
|
@theme = theme
|
|
27
|
+
@include_filter = include_filter
|
|
26
28
|
@ignore_filter = ignore_filter
|
|
27
29
|
@error_reporter = ErrorReporter.new(ctx)
|
|
28
30
|
@standard_reporter = StandardReporter.new(ctx)
|
|
@@ -193,7 +195,7 @@ module ShopifyCLI
|
|
|
193
195
|
# Already enqueued
|
|
194
196
|
return if @pending.include?(operation)
|
|
195
197
|
|
|
196
|
-
if
|
|
198
|
+
if ignore?(operation)
|
|
197
199
|
@ctx.debug("ignore #{operation.file_path}")
|
|
198
200
|
return
|
|
199
201
|
end
|
|
@@ -251,6 +253,19 @@ module ShopifyCLI
|
|
|
251
253
|
response
|
|
252
254
|
end
|
|
253
255
|
|
|
256
|
+
def ignore?(operation)
|
|
257
|
+
path = operation.file_path
|
|
258
|
+
ignored_by_ignore_filter?(path) || ignored_by_include_filter?(path)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def ignored_by_ignore_filter?(path)
|
|
262
|
+
ignore_filter&.ignore?(path)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def ignored_by_include_filter?(path)
|
|
266
|
+
include_filter && !include_filter.match?(path)
|
|
267
|
+
end
|
|
268
|
+
|
|
254
269
|
def get(file)
|
|
255
270
|
_status, body, response = ShopifyCLI::AdminAPI.rest_request(
|
|
256
271
|
@ctx,
|
|
@@ -173,15 +173,37 @@ module ShopifyCLI
|
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
def live(ctx, root: nil)
|
|
176
|
-
|
|
176
|
+
find(ctx, root) { |attrs| attrs["role"] == "main" }
|
|
177
|
+
end
|
|
177
178
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
def development(ctx, root: nil)
|
|
180
|
+
find(ctx, root) { |attrs| attrs["role"] == "development" }
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Finds a Theme by its identifier
|
|
184
|
+
#
|
|
185
|
+
# #### Parameters
|
|
186
|
+
# * `ctx` - current running context of your command
|
|
187
|
+
# * `root` - theme root
|
|
188
|
+
# * `identifier` - theme ID or theme name
|
|
189
|
+
def find_by_identifier(ctx, root: nil, identifier:)
|
|
190
|
+
find(ctx, root) do |attrs|
|
|
191
|
+
attrs.slice("name", "id").values.map(&:to_s).include?(identifier)
|
|
192
|
+
end
|
|
181
193
|
end
|
|
182
194
|
|
|
183
195
|
private
|
|
184
196
|
|
|
197
|
+
def find(ctx, root, &block)
|
|
198
|
+
_status, body = fetch_themes(ctx)
|
|
199
|
+
|
|
200
|
+
body["themes"]
|
|
201
|
+
.find(&block)
|
|
202
|
+
.tap do |attrs|
|
|
203
|
+
break new(ctx, root: root, **allowed_attrs(attrs)) if attrs
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
185
207
|
def allowed_attrs(attrs)
|
|
186
208
|
attrs.slice("id", "name", "role").transform_keys(&:to_sym)
|
|
187
209
|
end
|
data/lib/shopify_cli/version.rb
CHANGED
data/lib/shopify_cli.rb
CHANGED
|
@@ -15,12 +15,13 @@ ENV["PATH"] = ENV["PATH"].split(":").select { |p| p.start_with?("/", "~") }.join
|
|
|
15
15
|
vendor_path = File.expand_path("../../vendor/lib", __FILE__)
|
|
16
16
|
$LOAD_PATH.unshift(vendor_path) unless $LOAD_PATH.include?(vendor_path)
|
|
17
17
|
|
|
18
|
-
deps = %w(cli-ui cli-kit smart_properties webrick)
|
|
18
|
+
deps = %w(cli-ui cli-kit smart_properties ruby2_keywords webrick)
|
|
19
19
|
deps.each do |dep|
|
|
20
20
|
vendor_path = File.expand_path("../../vendor/deps/#{dep}/lib", __FILE__)
|
|
21
21
|
$LOAD_PATH.unshift(vendor_path) unless $LOAD_PATH.include?(vendor_path)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
require "ruby2_keywords"
|
|
24
25
|
require "cli/ui"
|
|
25
26
|
require "cli/kit"
|
|
26
27
|
require "smart_properties"
|
|
@@ -139,6 +140,10 @@ module ShopifyCLI
|
|
|
139
140
|
require "shopify_cli/messages/messages"
|
|
140
141
|
Context.load_messages(ShopifyCLI::Messages::MESSAGES)
|
|
141
142
|
|
|
143
|
+
# cli-ui utilities for capturing the output close the stream while capturing.
|
|
144
|
+
# By setting the value here we persist the tty value for the whole lifetime of the process.
|
|
145
|
+
Environment.interactive = $stdin.tty?
|
|
146
|
+
|
|
142
147
|
def self.cache_dir
|
|
143
148
|
cache_dir = if Environment.test?
|
|
144
149
|
TEMP_DIR
|
|
@@ -174,11 +174,16 @@ module CLI
|
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
def os
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
@current_os ||= case RbConfig::CONFIG['host_os']
|
|
178
|
+
when /darwin/ then :mac
|
|
179
|
+
when /linux/ then :linux
|
|
180
|
+
else
|
|
181
|
+
if RUBY_PLATFORM !~ /cygwin/ && ENV['OS'] == 'Windows_NT'
|
|
182
|
+
:windows
|
|
183
|
+
else
|
|
184
|
+
raise "Could not determine OS from host_os #{RbConfig::CONFIG["host_os"]}"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
182
187
|
end
|
|
183
188
|
|
|
184
189
|
private
|
|
@@ -4,15 +4,17 @@ module CLI
|
|
|
4
4
|
# Determines which OS is currently running the UI, to make it easier to
|
|
5
5
|
# adapt its behaviour to the features of the OS.
|
|
6
6
|
def self.current
|
|
7
|
-
@current_os ||= case
|
|
7
|
+
@current_os ||= case RbConfig::CONFIG['host_os']
|
|
8
8
|
when /darwin/
|
|
9
9
|
Mac
|
|
10
10
|
when /linux/
|
|
11
11
|
Linux
|
|
12
|
-
when /mingw32/
|
|
13
|
-
Windows
|
|
14
12
|
else
|
|
15
|
-
|
|
13
|
+
if RUBY_PLATFORM !~ /cygwin/ && ENV['OS'] == 'Windows_NT'
|
|
14
|
+
Windows
|
|
15
|
+
else
|
|
16
|
+
raise "Could not determine OS from host_os #{RbConfig::CONFIG["host_os"]}"
|
|
17
|
+
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
|