shopify-cli 2.14.0 → 2.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.github/workflows/stale.yml +46 -0
  4. data/CHANGELOG.md +24 -0
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +39 -7
  7. data/Rakefile +40 -0
  8. data/ext/shopify-extensions/version +1 -1
  9. data/lib/project_types/extension/forms/questions/ask_template.rb +5 -8
  10. data/lib/project_types/extension/messages/messages.rb +11 -1
  11. data/lib/project_types/extension/models/development_server_requirements.rb +13 -7
  12. data/lib/project_types/extension/models/server_config/root.rb +2 -0
  13. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +13 -0
  14. data/lib/project_types/script/config/extension_points.yml +18 -0
  15. data/lib/project_types/script/layers/infrastructure/errors.rb +17 -0
  16. data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
  17. data/lib/project_types/script/messages/messages.rb +3 -0
  18. data/lib/project_types/script/ui/error_handler.rb +11 -0
  19. data/lib/project_types/theme/commands/pull.rb +2 -2
  20. data/lib/project_types/theme/commands/push.rb +2 -2
  21. data/lib/project_types/theme/commands/serve.rb +1 -0
  22. data/lib/project_types/theme/conversions/base_glob.rb +20 -5
  23. data/lib/project_types/theme/messages/messages.rb +47 -8
  24. data/lib/shopify_cli/changelog.rb +76 -0
  25. data/lib/shopify_cli/command.rb +8 -7
  26. data/lib/shopify_cli/environment.rb +19 -11
  27. data/lib/shopify_cli/git.rb +36 -0
  28. data/lib/shopify_cli/messages/messages.rb +16 -9
  29. data/lib/shopify_cli/release.rb +194 -0
  30. data/lib/shopify_cli/sed.rb +19 -0
  31. data/lib/shopify_cli/services/app/create/node_service.rb +2 -14
  32. data/lib/shopify_cli/services/app/create/php_service.rb +1 -6
  33. data/lib/shopify_cli/services/app/create/rails_service.rb +4 -12
  34. data/lib/shopify_cli/theme/dev_server/hot-reload.js +40 -13
  35. data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +1 -1
  36. data/lib/shopify_cli/theme/dev_server/hot_reload/sections_index.rb +51 -0
  37. data/lib/shopify_cli/theme/dev_server/hot_reload.rb +6 -1
  38. data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
  39. data/lib/shopify_cli/theme/dev_server/remote_watcher/json_files_update_job.rb +34 -0
  40. data/lib/shopify_cli/theme/dev_server/remote_watcher.rb +44 -0
  41. data/lib/shopify_cli/theme/dev_server/watcher.rb +1 -1
  42. data/lib/shopify_cli/theme/dev_server.rb +15 -3
  43. data/lib/shopify_cli/theme/file.rb +15 -4
  44. data/lib/shopify_cli/theme/syncer/checksums.rb +60 -0
  45. data/lib/shopify_cli/theme/syncer/forms/apply_to_all.rb +39 -0
  46. data/lib/shopify_cli/theme/syncer/forms/apply_to_all_form.rb +35 -0
  47. data/lib/shopify_cli/theme/syncer/forms/base_strategy_form.rb +62 -0
  48. data/lib/shopify_cli/theme/syncer/forms/select_delete_strategy.rb +27 -0
  49. data/lib/shopify_cli/theme/syncer/forms/select_update_strategy.rb +28 -0
  50. data/lib/shopify_cli/theme/syncer/ignore_helper.rb +33 -0
  51. data/lib/shopify_cli/theme/syncer/json_delete_handler.rb +51 -0
  52. data/lib/shopify_cli/theme/syncer/json_update_handler.rb +82 -0
  53. data/lib/shopify_cli/theme/syncer/merger.rb +53 -0
  54. data/lib/shopify_cli/theme/syncer/operation.rb +1 -1
  55. data/lib/shopify_cli/theme/syncer.rb +79 -63
  56. data/lib/shopify_cli/theme/theme.rb +12 -4
  57. data/lib/shopify_cli/theme/theme_admin_api.rb +24 -23
  58. data/lib/shopify_cli/thread_pool/job.rb +10 -2
  59. data/lib/shopify_cli/thread_pool.rb +15 -3
  60. data/lib/shopify_cli/tunnel.rb +9 -0
  61. data/lib/shopify_cli/version.rb +1 -1
  62. data/shopify-cli.gemspec +3 -1
  63. metadata +21 -4
  64. data/lib/project_types/rails/ruby.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be8f00a6bb6d3e7059a63e77ff74327d9e11474cc34b156ec54da33080119e11
4
- data.tar.gz: ed986614e2b2c0b9b9ca70a175c2133a3130643f3678bbf17148556be4f39f86
3
+ metadata.gz: a06f3c09c3e5e000956befefcbb7b8108096236d9b03cd021959881324c7cfe5
4
+ data.tar.gz: b1daa60127f1b93ceed1f00d151e67f9709bca8ae77a962913f6fd1edfaac0c9
5
5
  SHA512:
6
- metadata.gz: cc1c384e33b5bc316e38ab1ab58b978ab56e811309c82746f9218fc8de2cd4d57b243414f324421baff1abdc69829d952840e2c2bd94049963858ca3700c5600
7
- data.tar.gz: d065d5a10be15c0f79c800798fb0302e9b2519b7b22fea5879ae321297e8bd0859d8b21756b40ae8abe78387e1e3e62b600d0e796a5848545b1c8e5c37af4cd2
6
+ metadata.gz: 31e29e63fd9f7e569f7d4834549645b1ca206489274709aa7577f57b6888b3bd28d06eb5bd5899721cf9478239fa524b7937c009575a93c0ac096cd56c911fa6
7
+ data.tar.gz: '09f19940da497bf3fab8d8c78c801fc127c2a8cad8fe49887f86b05de373dc96acb805c8c282ce76c72d7ea89526d65f0ec0ef3732d6854110a50d02de2f240b'
@@ -17,7 +17,7 @@ When contributing to the Shopify CLI, there are a set of [design guidelines](htt
17
17
 
18
18
  ### Where to find known issues
19
19
 
20
- We track all of our issues in GitHub and [bugs](https://github.com/Shopify/shopify-cli/labels/Bug) are labeled accordingly. If you are planning to work on an issue, avoid ones which already have an assignee, where someone has commented within the last two weeks they are working on it, or the issue is labeled with [fix in progress](https://github.com/Shopify/shopify-cli/labels/fix%20in%20progress). We will do our best to communicate when an issue is being worked on internally.
20
+ We track all of our issues in GitHub and [bugs](https://github.com/Shopify/shopify-cli/labels/type:bug) are labeled accordingly. If you are planning to work on an issue, avoid ones which already have an assignee, where someone has commented within the last two weeks they are working on it, or the issue is labeled with [fix in progress](https://github.com/Shopify/shopify-cli/labels/fix%20in%20progress). We will do our best to communicate when an issue is being worked on internally.
21
21
 
22
22
  ### Running against a local environment
23
23
 
@@ -0,0 +1,46 @@
1
+ # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
2
+ #
3
+ # You can adjust the behavior by modifying this file.
4
+ # For more information, see:
5
+ # https://github.com/actions/stale
6
+ name: Mark stale issues and pull requests
7
+
8
+ on:
9
+ schedule:
10
+ - cron: '31 3 * * *' # randomly chosen time of day
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ stale:
15
+
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ issues: write
19
+ pull-requests: write
20
+
21
+ steps:
22
+ - uses: actions/stale@v4
23
+ with:
24
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
25
+ days-before-issue-stale: 90
26
+ days-before-pr-stale: 30
27
+ days-before-close: 10
28
+ stale-issue-message: |-
29
+ This issue seems inactive. If it's still relevant, please add a comment saying so. Otherwise, take no action.
30
+
31
+ → If there's no activity within a week, then a bot will automatically close this.
32
+
33
+ Thanks for helping to improve Shopify's dev tooling and experience.
34
+ stale-pr-message: |-
35
+ This PR seems inactive. If it's still relevant, please add a comment saying so. Otherwise, take no action.
36
+
37
+ → If there's no activity within a week, then a bot will automatically close this.
38
+
39
+ Thanks for helping to improve Shopify's dev tooling and experience.
40
+ stale-issue-label: 'no-issue-activity'
41
+ stale-pr-label: 'no-pr-activity'
42
+ ascending: true
43
+ # The math seems a bit fuzzy, but this should amount to a max of 50 issues daily.
44
+ # But then the same issues get checked first so we don't end up progressing too quickly until we can close what we started.
45
+ # Hopefully https://github.com/actions/stale/issues/692 will be closed and fix some of this mess.
46
+ operations-per-run: 200
data/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@ 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.15.2
6
+
7
+ ### Fixed
8
+ * [#2121](https://github.com/Shopify/shopify-cli/pull/2121): Fix the hot-reload to work when the section name is not equal to the type
9
+
10
+ ## Version 2.15.1
11
+
12
+ ### Added
13
+ * [#1934](https://github.com/Shopify/shopify-cli/pull/1934): Block directories in theme assets
14
+ * [#1880](https://github.com/Shopify/shopify-cli/pull/1880): Recognize attempts to pass a store name and suggest correction
15
+ * [#2174](https://github.com/Shopify/shopify-cli/pull/2174): Add optional 2-way sync between the CLI (`theme serve`) and the Theme Editor
16
+
17
+ ### Fixed
18
+ * [#1874](https://github.com/Shopify/shopify-cli/pull/1874): Make ngrok errors more robust and helpful
19
+ * [#2172](https://github.com/Shopify/shopify-cli/pull/2172): Fix Ruby check for Rails app creation
20
+
21
+ ## Version 2.15.0
22
+
23
+ ### Fixed
24
+ * [#2086](https://github.com/Shopify/shopify-cli/pull/2086): Improve check of dependency versions
25
+ * [#2149](https://github.com/Shopify/shopify-cli/pull/2149): Fix `ThemeAdminAPI` not to handle asset errors
26
+ * [#2122](https://github.com/Shopify/shopify-cli/pull/2122): Fix `--only`/`--ignore` flags parser to support multiple occurrences without quotes
27
+ * [#2146](https://github.com/Shopify/shopify-cli/pull/2146): Prevent duplicate locales for Checkout extension localization
28
+
5
29
  ## Version 2.14.0
6
30
 
7
31
  ### Changed
data/Gemfile CHANGED
@@ -15,6 +15,7 @@ group :development, :test do
15
15
  gem "rubocop-rake", require: false
16
16
  gem "iniparse", "~> 1.5"
17
17
  gem "colorize", "~> 0.8.1"
18
+ gem "octokit", "~> 4.0"
18
19
  end
19
20
 
20
21
  group :test do
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify-cli (2.14.0)
4
+ shopify-cli (2.15.2)
5
5
  bugsnag (~> 6.22)
6
6
  listen (~> 3.7.0)
7
7
  theme-check (~> 1.10.1)
@@ -13,13 +13,13 @@ GEM
13
13
  public_suffix (>= 2.0.2, < 5.0)
14
14
  ansi (1.5.0)
15
15
  ast (2.4.2)
16
- bugsnag (6.23.0)
16
+ bugsnag (6.24.2)
17
17
  concurrent-ruby (~> 1.0)
18
18
  builder (3.2.4)
19
19
  byebug (11.1.3)
20
20
  coderay (1.1.3)
21
21
  colorize (0.8.1)
22
- concurrent-ruby (1.1.9)
22
+ concurrent-ruby (1.1.10)
23
23
  crack (0.4.5)
24
24
  rexml
25
25
  cucumber (7.0.0)
@@ -55,11 +55,34 @@ GEM
55
55
  cucumber-messages (~> 17.0, >= 17.0.1)
56
56
  diff-lcs (1.4.4)
57
57
  fakefs (1.3.2)
58
+ faraday (1.10.0)
59
+ faraday-em_http (~> 1.0)
60
+ faraday-em_synchrony (~> 1.0)
61
+ faraday-excon (~> 1.1)
62
+ faraday-httpclient (~> 1.0)
63
+ faraday-multipart (~> 1.0)
64
+ faraday-net_http (~> 1.0)
65
+ faraday-net_http_persistent (~> 1.0)
66
+ faraday-patron (~> 1.0)
67
+ faraday-rack (~> 1.0)
68
+ faraday-retry (~> 1.0)
69
+ ruby2_keywords (>= 0.0.4)
70
+ faraday-em_http (1.0.0)
71
+ faraday-em_synchrony (1.0.0)
72
+ faraday-excon (1.1.0)
73
+ faraday-httpclient (1.0.1)
74
+ faraday-multipart (1.0.3)
75
+ multipart-post (>= 1.2, < 3)
76
+ faraday-net_http (1.0.1)
77
+ faraday-net_http_persistent (1.2.0)
78
+ faraday-patron (1.0.0)
79
+ faraday-rack (1.0.0)
80
+ faraday-retry (1.0.3)
58
81
  ffi (1.15.4)
59
82
  hashdiff (1.0.1)
60
83
  iniparse (1.5.0)
61
- liquid (5.1.0)
62
- listen (3.7.0)
84
+ liquid (5.3.0)
85
+ listen (3.7.1)
63
86
  rb-fsevent (~> 0.10, >= 0.10.3)
64
87
  rb-inotify (~> 0.9, >= 0.9.10)
65
88
  method_source (1.0.0)
@@ -77,9 +100,13 @@ GEM
77
100
  ruby-progressbar
78
101
  mocha (1.13.0)
79
102
  multi_test (0.1.2)
103
+ multipart-post (2.1.1)
80
104
  nokogiri (1.13.3)
81
105
  mini_portile2 (~> 2.8.0)
82
106
  racc (~> 1.4)
107
+ octokit (4.22.0)
108
+ faraday (>= 0.9)
109
+ sawyer (~> 0.8.0, >= 0.5.3)
83
110
  parallel (1.21.0)
84
111
  parser (3.1.1.0)
85
112
  ast (~> 2.4.1)
@@ -94,7 +121,7 @@ GEM
94
121
  rack (2.2.3)
95
122
  rainbow (3.1.1)
96
123
  rake (13.0.6)
97
- rb-fsevent (0.11.0)
124
+ rb-fsevent (0.11.1)
98
125
  rb-inotify (0.10.1)
99
126
  ffi (~> 1.0)
100
127
  regexp_parser (2.2.0)
@@ -117,9 +144,13 @@ GEM
117
144
  rubocop-shopify (2.0.1)
118
145
  rubocop (~> 1.11)
119
146
  ruby-progressbar (1.11.0)
147
+ ruby2_keywords (0.0.5)
148
+ sawyer (0.8.2)
149
+ addressable (>= 2.3.5)
150
+ faraday (> 0.8, < 2.0)
120
151
  sys-uname (1.2.2)
121
152
  ffi (~> 1.1)
122
- theme-check (1.10.1)
153
+ theme-check (1.10.2)
123
154
  liquid (>= 5.1.0)
124
155
  nokogiri (>= 1.12)
125
156
  parser (~> 3)
@@ -144,6 +175,7 @@ DEPENDENCIES
144
175
  minitest-fail-fast
145
176
  minitest-reporters
146
177
  mocha
178
+ octokit (~> 4.0)
147
179
  pry-byebug
148
180
  rack
149
181
  rake
data/Rakefile CHANGED
@@ -129,6 +129,46 @@ end
129
129
  desc("Builds all distribution packages of the CLI")
130
130
  task(package: "package:all")
131
131
 
132
+ namespace :release do
133
+ require "shopify_cli/release"
134
+
135
+ task :prepare, [:new_version] do |_t, args|
136
+ new_version = args[:new_version]
137
+ unless new_version
138
+ raise <<~NO_NEW_VERSION
139
+ New version must be provided, e.g.:
140
+
141
+ $ GITHUB_ACCESS_TOKEN=abcdef rake "release:prepare[1.2.3]"
142
+
143
+ NO_NEW_VERSION
144
+ end
145
+ github_access_token = ENV["GITHUB_ACCESS_TOKEN"]
146
+ unless github_access_token
147
+ raise <<~NO_GITHUB_ACCESS_TOKEN
148
+ GitHub access token must be provided, e.g.:
149
+
150
+ $ GITHUB_ACCESS_TOKEN=abcdef rake "release:prepare[1.2.3]"
151
+ NO_GITHUB_ACCESS_TOKEN
152
+ end
153
+
154
+ ShopifyCLI::Release.new(new_version, github_access_token).prepare!
155
+ puts "Completed!"
156
+ end
157
+
158
+ task :package do
159
+ github_access_token = ENV["GITHUB_ACCESS_TOKEN"]
160
+ unless github_access_token
161
+ raise <<~NO_GITHUB_ACCESS_TOKEN
162
+ GitHub access token must be provided, e.g.:
163
+
164
+ $ GITHUB_ACCESS_TOKEN=abcdef rake release:package
165
+ NO_GITHUB_ACCESS_TOKEN
166
+ end
167
+ ShopifyCLI::Release.new(ShopifyCLI::VERSION, github_access_token).package!
168
+ puts "Completed!"
169
+ end
170
+ end
171
+
132
172
  namespace :extensions do
133
173
  task :update do
134
174
  version = ENV.fetch("VERSION").strip
@@ -1 +1 @@
1
- v0.1.0
1
+ v0.2.0
@@ -11,21 +11,18 @@ module Extension
11
11
  default: -> { CLI::UI::Prompt.method(:ask) }
12
12
 
13
13
  def call(project_details)
14
- return project_details unless template_required?(project_details)
15
- project_details.template = template || choose_interactively
14
+ if template_required?(project_details)
15
+ project_details.template = template || choose_interactively
16
+ end
16
17
  project_details
17
18
  end
18
19
 
19
20
  private
20
21
 
21
22
  def template_required?(project_details)
22
- return false unless extension_server_beta?
23
23
  type = project_details&.type&.identifier
24
- Models::DevelopmentServerRequirements::SUPPORTED_EXTENSION_TYPES.include?(type.downcase)
25
- end
26
-
27
- def extension_server_beta?
28
- ShopifyCLI::Shopifolk.check && ShopifyCLI::Feature.enabled?(:extension_server_beta)
24
+ (Models::DevelopmentServerRequirements.beta_enabled? &&
25
+ Models::DevelopmentServerRequirements.type_supported?(type.downcase))
29
26
  end
30
27
 
31
28
  def choose_interactively
@@ -41,7 +41,7 @@ module Extension
41
41
  invalid_api_key: "The API key %s does not match any of your apps.",
42
42
  ask_app: "Which app would you like to register this extension with?",
43
43
  no_apps: "{{x}} You don’t have any apps.",
44
- learn_about_apps: "{{*}} Learn more about building apps at <https://shopify.dev/concepts/apps>, " \
44
+ learn_about_apps: "{{*}} Learn more about building apps at <https://shopify.dev/apps>, " \
45
45
  "or try creating a new app using {{command:shopify [node|rails] create}}.",
46
46
  loading_apps: "Loading your apps…",
47
47
  no_available_extensions: "{{x}} There are no available extensions for this app.",
@@ -115,6 +115,16 @@ module Extension
115
115
  tunnel_already_running: "A tunnel running on another port has been detected. Close the tunnel and try again.",
116
116
  },
117
117
  tunnel: {
118
+ duplicate_session: <<~MESSAGE,
119
+ Another ngrok tunnel is currently running with your auth token, possibly on another machine.
120
+
121
+ Terminate that tunnel before opening a new one.
122
+ MESSAGE
123
+ invalid_token: <<~MESSAGE,
124
+ The ngrok token currently configured is invalid.
125
+
126
+ After generating a new token, update your local ngrok configuration using {{command:shopify app tunnel auth <token>}}
127
+ MESSAGE
118
128
  missing_token: "{{x}} {{red:auth requires a token argument}}. "\
119
129
  "Find it on your ngrok dashboard: {{underline:https://dashboard.ngrok.com/auth/your-authtoken}}.",
120
130
  invalid_port: "%s is not a valid port.",
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "shopify_cli"
3
4
 
4
5
  module Extension
@@ -12,21 +13,26 @@ module Extension
12
13
 
13
14
  class << self
14
15
  def supported?(type)
15
- binary_installed? && type_supported?(type) && beta_enabled?
16
+ binary_installed? && type_supported?(type) && type_enabled?(type)
16
17
  end
17
18
 
18
- private
19
-
20
- def binary_installed?
21
- Models::DevelopmentServer.new.executable_installed?
19
+ def beta_enabled?
20
+ ShopifyCLI::Feature.enabled?(:extension_server_beta)
22
21
  end
23
22
 
24
23
  def type_supported?(type)
25
24
  SUPPORTED_EXTENSION_TYPES.include?(type.downcase)
26
25
  end
27
26
 
28
- def beta_enabled?
29
- ShopifyCLI::Shopifolk.check && ShopifyCLI::Feature.enabled?(:extension_server_beta)
27
+ private
28
+
29
+ def binary_installed?
30
+ Models::DevelopmentServer.new.executable_installed?
31
+ end
32
+
33
+ # Some types are enabled unconditionally; others require beta_enabled
34
+ def type_enabled?(type)
35
+ beta_enabled? || "checkout_ui_extension" == type.downcase
30
36
  end
31
37
  end
32
38
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "yaml"
4
+
3
5
  module Extension
4
6
  module Models
5
7
  module ServerConfig
@@ -43,6 +43,7 @@ module Extension
43
43
  # Localization is optional
44
44
  return {} if locale_filenames.empty?
45
45
 
46
+ validate_no_duplicate_locale(locale_filenames)
46
47
  validate_total_size(locale_filenames)
47
48
  default_locale = single_default_locale(locale_filenames)
48
49
 
@@ -61,6 +62,18 @@ module Extension
61
62
  end
62
63
  end
63
64
 
65
+ def validate_no_duplicate_locale(locale_filenames)
66
+ duplicate_locale = locale_filenames
67
+ .map { |filename| basename_for_locale_filename(filename.downcase) }
68
+ .group_by { |locale| locale }
69
+ .detect { |_k, v| v.size > 1 }
70
+ &.first
71
+ raise(
72
+ ShopifyCLI::Abort,
73
+ ShopifyCLI::Context.message("#{L10N_ERROR_PREFIX}.duplicate_locale_code", duplicate_locale)
74
+ ) unless duplicate_locale.nil?
75
+ end
76
+
64
77
  def validate_total_size(locale_filenames)
65
78
  total_size = locale_filenames.sum { |filename| File.size(filename) }
66
79
  if total_size > L10N_BUNDLE_SIZE_LIMIT
@@ -36,3 +36,21 @@ delivery_discount_types:
36
36
  repo: "https://github.com/Shopify/scripts-apis-examples"
37
37
  wasm:
38
38
  repo: "https://github.com/Shopify/scripts-apis-examples"
39
+ product_discount_type:
40
+ beta: true
41
+ domain: 'discounts'
42
+ libraries:
43
+ wasm:
44
+ repo: "https://github.com/Shopify/scripts-apis-examples"
45
+ order_discount_type:
46
+ beta: true
47
+ domain: 'discounts'
48
+ libraries:
49
+ wasm:
50
+ repo: "https://github.com/Shopify/scripts-apis-examples"
51
+ shipping_discount_type:
52
+ beta: true
53
+ domain: 'discounts'
54
+ libraries:
55
+ wasm:
56
+ repo: "https://github.com/Shopify/scripts-apis-examples"
@@ -180,6 +180,23 @@ module Script
180
180
  @max_size = max_size
181
181
  end
182
182
  end
183
+
184
+ class InvalidInputQueryErrors < ScriptProjectError
185
+ attr_reader :messages
186
+
187
+ def initialize(messages)
188
+ @messages = messages
189
+ super()
190
+ end
191
+
192
+ def input_query_path
193
+ ScriptProjectRepository::INPUT_QUERY_PATH
194
+ end
195
+
196
+ def message
197
+ messages.join("\n")
198
+ end
199
+ end
183
200
  end
184
201
  end
185
202
  end
@@ -83,6 +83,8 @@ module Script
83
83
  valid_types: e["message"],
84
84
  filename: script_config.filename,
85
85
  )
86
+ elsif (errors = user_errors.filter { |err| err["tag"] == "input_query_validation_error" }).any?
87
+ raise Errors::InvalidInputQueryErrors, errors.map { |err| err["message"] }
86
88
  elsif user_errors.find { |err| %w(not_use_msgpack_error schema_version_argument_error).include?(err["tag"]) }
87
89
  raise Domain::Errors::MetadataValidationError
88
90
  else
@@ -86,6 +86,9 @@ module Script
86
86
  "type(s): %{valid_types}.",
87
87
  configuration_schema_field_invalid_value_error_help: "Change the value of the type.",
88
88
 
89
+ input_query_error_cause: "Input query is invalid:\n%{messages}\n\n",
90
+ input_query_error_help: "Fix the query in the `%{input_query_path}` file.",
91
+
89
92
  script_not_found_cause: "Can't find script %s for Script API %s",
90
93
 
91
94
  system_call_failure_cause: "Something went wrong while running: {{command:%{cmd}}}.",
@@ -216,6 +216,17 @@ module Script
216
216
  "script.error.configuration_schema_field_invalid_value_error_help"
217
217
  ),
218
218
  }
219
+ when Layers::Infrastructure::Errors::InvalidInputQueryErrors
220
+ {
221
+ cause_of_error: ShopifyCLI::Context.message(
222
+ "script.error.input_query_error_cause",
223
+ messages: e.messages.map { |message| " {{x}} #{message}." }.join("\n"),
224
+ ),
225
+ help_suggestion: ShopifyCLI::Context.message(
226
+ "script.error.input_query_error_help",
227
+ input_query_path: e.input_query_path,
228
+ ),
229
+ }
219
230
  when Layers::Infrastructure::Errors::DependencyInstallError
220
231
  {
221
232
  cause_of_error: ShopifyCLI::Context.message("script.error.dependency_install_cause"),
@@ -26,11 +26,11 @@ module Theme
26
26
  parser.on("-d", "--development") { flags[:development] = true }
27
27
  parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
28
28
  flags[:includes] ||= []
29
- flags[:includes] += pattern
29
+ flags[:includes] |= pattern
30
30
  end
31
31
  parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
32
32
  flags[:ignores] ||= []
33
- flags[:ignores] += pattern
33
+ flags[:ignores] |= pattern
34
34
  end
35
35
  end
36
36
 
@@ -30,11 +30,11 @@ module Theme
30
30
  parser.on("-p", "--publish") { flags[:publish] = true }
31
31
  parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
32
32
  flags[:includes] ||= []
33
- flags[:includes] += pattern
33
+ flags[:includes] |= pattern
34
34
  end
35
35
  parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
36
36
  flags[:ignores] ||= []
37
- flags[:ignores] += pattern
37
+ flags[:ignores] |= pattern
38
38
  end
39
39
  end
40
40
 
@@ -16,6 +16,7 @@ module Theme
16
16
  parser.on("--port=PORT") { |port| flags[:port] = port.to_i }
17
17
  parser.on("--poll") { flags[:poll] = true }
18
18
  parser.on("--live-reload=MODE") { |mode| flags[:mode] = as_reload_mode(mode) }
19
+ parser.on("--theme-editor-sync") { flags[:editor_sync] = true }
19
20
  end
20
21
 
21
22
  def call(_args, name)
@@ -10,8 +10,22 @@ module Theme
10
10
 
11
11
  def convert(parser)
12
12
  argv = parser.default_argv
13
- option_index = argv.index { |v| options.include?(v) }
13
+ values = []
14
+
15
+ option_indexes(argv).each do |option_index|
16
+ values += option_values(argv, parser, option_index)
17
+ end
18
+
19
+ values
20
+ end
21
+
22
+ def options
23
+ raise "`#{self.class.name}#options` must be defined"
24
+ end
25
+
26
+ private
14
27
 
28
+ def option_values(argv, parser, option_index)
15
29
  return [] if option_index.nil?
16
30
 
17
31
  start_index = option_index + 1
@@ -26,12 +40,13 @@ module Theme
26
40
  values
27
41
  end
28
42
 
29
- def options
30
- raise "`#{self.class.name}#options` must be defined"
43
+ def option_indexes(argv)
44
+ argv
45
+ .each_with_index
46
+ .select { |item, _index| options.include?(item) }
47
+ .map(&:last)
31
48
  end
32
49
 
33
- private
34
-
35
50
  def options_map(parser)
36
51
  map = {}
37
52
  parser.top.list.each do |option|
@@ -101,13 +101,14 @@ module Theme
101
101
  Usage: {{command:%s theme serve [ ROOT ]}}
102
102
 
103
103
  Options:
104
- {{command:--port=PORT}} Local port to serve theme preview from.
105
- {{command:--poll}} Force polling to detect file changes.
106
- {{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
107
- {{command:--live-reload=MODE}} The live reload mode switches the server behavior when a file is modified:
108
- - {{command:hot-reload}} Hot reloads local changes to CSS and sections (default)
109
- - {{command:full-page}} Always refreshes the entire page
110
- - {{command:off}} Deactivate live reload
104
+ {{command:--port=PORT}} Local port to serve theme preview from.
105
+ {{command:--poll}} Force polling to detect file changes.
106
+ {{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
107
+ {{command:--theme-editor-sync}} Synchronize Theme Editor updates in the local theme files.
108
+ {{command:--live-reload=MODE}} The live reload mode switches the server behavior when a file is modified:
109
+ - {{command:hot-reload}} Hot reloads local changes to CSS and sections (default)
110
+ - {{command:full-page}} Always refreshes the entire page
111
+ - {{command:off}} Deactivate live reload
111
112
  HELP
112
113
  reload_mode_is_not_valid: "The live reload mode `%s` is not valid.",
113
114
  try_a_valid_reload_mode: "Try a valid live reload mode: %s.",
@@ -121,18 +122,56 @@ module Theme
121
122
  fixed: "Fixed",
122
123
  },
123
124
  },
125
+ syncer: {
126
+ forms: {
127
+ apply_to_all: {
128
+ title: "Would like apply this to all the other %s files?",
129
+ yes: "Yes",
130
+ no: "No",
131
+ },
132
+ update_strategy: {
133
+ title_context: <<~TITLE,
134
+
135
+ The local file {{command:%s}} is different from the remote version in the development theme."
136
+ TITLE
137
+ title_question: "What would you like to do?",
138
+ keep_remote: "Keep the remote version",
139
+ keep_local: "Keep the local version",
140
+ union_merge: "Merge files (it may break the local file)",
141
+ exit: "Exit",
142
+ },
143
+ delete_strategy: {
144
+ title_context: <<~TITLE,
145
+
146
+ The local file {{command:%s}} has been recently removed, but it's present on your remote development theme.",
147
+ TITLE
148
+ title_question: "What would you like to do?",
149
+ delete: "Delete permanently",
150
+ restore: "Restore with the remote version",
151
+ exit: "Exit",
152
+ },
153
+ },
154
+ },
124
155
  error: {
125
156
  address_binding_error: "Couldn't bind to localhost."\
126
157
  " To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
158
+ invalid_subdirectory: <<~MESSAGE,
159
+ The presence of %s in the directory structure isn't supported.
160
+
161
+ Move any files to a parent folder, then delete unsupported subdirectories.
162
+
163
+ • Required directory structure: https://shopify.dev/themes/architecture#directory-structure-and-component-types
164
+ MESSAGE
127
165
  },
128
166
  serving: <<~SERVING,
129
167
 
130
168
  Serving %s
131
169
 
132
170
  SERVING
171
+ download_changes: ", and use 'theme pull' to get the changes",
133
172
  customize_or_preview: <<~CUSTOMIZE_OR_PREVIEW,
134
173
 
135
- Customize this theme in the Theme Editor:
174
+ Customize this theme in the Theme Editor%s:
136
175
  {{green:%s}}
137
176
 
138
177
  Share this theme preview: