shopify-cli 2.7.3 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +44 -0
  4. data/Gemfile.lock +1 -1
  5. data/RELEASING.md +4 -3
  6. data/dev.yml +2 -2
  7. data/ext/javy/javy.rb +8 -9
  8. data/lib/graphql/get_extension_registrations.graphql +27 -0
  9. data/lib/project_types/extension/cli.rb +27 -2
  10. data/lib/project_types/extension/commands/build.rb +10 -10
  11. data/lib/project_types/extension/commands/create.rb +2 -3
  12. data/lib/project_types/extension/commands/push.rb +36 -8
  13. data/lib/project_types/extension/extension_project.rb +1 -1
  14. data/lib/project_types/extension/features/argo_serve.rb +6 -5
  15. data/lib/project_types/extension/forms/questions/ask_registration.rb +6 -2
  16. data/lib/project_types/extension/loaders/project.rb +29 -0
  17. data/lib/project_types/extension/loaders/specification_handler.rb +22 -0
  18. data/lib/project_types/extension/messages/messages.rb +4 -0
  19. data/lib/project_types/extension/models/app.rb +1 -1
  20. data/lib/project_types/extension/models/development_server.rb +2 -4
  21. data/lib/project_types/extension/models/specification_handlers/default.rb +4 -0
  22. data/lib/project_types/extension/tasks/convert_server_config.rb +3 -1
  23. data/lib/project_types/extension/tasks/execute_commands/base.rb +13 -0
  24. data/lib/project_types/extension/tasks/execute_commands/build.rb +29 -0
  25. data/lib/project_types/extension/tasks/execute_commands/create.rb +33 -0
  26. data/lib/project_types/extension/tasks/execute_commands/serve.rb +35 -0
  27. data/lib/project_types/extension/tasks/merge_server_config.rb +33 -22
  28. data/lib/project_types/rails/gem.rb +1 -2
  29. data/lib/project_types/script/cli.rb +7 -0
  30. data/lib/project_types/script/commands/connect.rb +19 -0
  31. data/lib/project_types/script/commands/create.rb +8 -2
  32. data/lib/project_types/script/commands/push.rb +35 -12
  33. data/lib/project_types/script/layers/application/connect_app.rb +15 -3
  34. data/lib/project_types/script/layers/application/create_script.rb +16 -16
  35. data/lib/project_types/script/layers/application/extension_points.rb +50 -26
  36. data/lib/project_types/script/layers/application/push_script.rb +5 -2
  37. data/lib/project_types/script/layers/domain/errors.rb +3 -2
  38. data/lib/project_types/script/layers/domain/extension_point.rb +14 -0
  39. data/lib/project_types/script/layers/domain/script_config.rb +6 -4
  40. data/lib/project_types/script/layers/infrastructure/errors.rb +38 -23
  41. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +49 -28
  42. data/lib/project_types/script/layers/infrastructure/script_service.rb +22 -5
  43. data/lib/project_types/script/loaders/project.rb +44 -0
  44. data/lib/project_types/script/loaders/specification_handler.rb +22 -0
  45. data/lib/project_types/script/messages/messages.rb +39 -16
  46. data/lib/project_types/script/ui/error_handler.rb +46 -29
  47. data/lib/project_types/theme/commands/pull.rb +45 -17
  48. data/lib/project_types/theme/commands/push.rb +65 -28
  49. data/lib/project_types/theme/commands/serve.rb +5 -0
  50. data/lib/project_types/theme/messages/messages.rb +34 -18
  51. data/lib/shopify_cli/command.rb +6 -0
  52. data/lib/shopify_cli/commands/login.rb +1 -1
  53. data/lib/shopify_cli/commands/switch.rb +1 -1
  54. data/lib/shopify_cli/constants.rb +11 -2
  55. data/lib/shopify_cli/context.rb +66 -12
  56. data/lib/shopify_cli/core/executor.rb +4 -4
  57. data/lib/shopify_cli/environment.rb +50 -20
  58. data/lib/shopify_cli/form.rb +2 -0
  59. data/lib/shopify_cli/identity_auth.rb +4 -3
  60. data/lib/shopify_cli/messages/messages.rb +9 -1
  61. data/lib/shopify_cli/method_object.rb +21 -9
  62. data/lib/shopify_cli/partners_api/app_extensions/job.rb +36 -0
  63. data/lib/shopify_cli/partners_api/app_extensions.rb +46 -0
  64. data/lib/shopify_cli/partners_api/organizations.rb +2 -5
  65. data/lib/shopify_cli/partners_api.rb +1 -0
  66. data/lib/shopify_cli/project.rb +8 -7
  67. data/lib/shopify_cli/resources/env_file.rb +18 -6
  68. data/lib/shopify_cli/result.rb +61 -59
  69. data/lib/shopify_cli/task.rb +5 -3
  70. data/lib/shopify_cli/theme/dev_server/cdn/cdn_helper.rb +49 -0
  71. data/lib/shopify_cli/theme/dev_server/cdn_assets.rb +69 -0
  72. data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +8 -28
  73. data/lib/shopify_cli/theme/dev_server/hot-reload.js +34 -3
  74. data/lib/shopify_cli/theme/dev_server/hot_reload.rb +18 -2
  75. data/lib/shopify_cli/theme/dev_server/local_assets.rb +4 -0
  76. data/lib/shopify_cli/theme/dev_server/proxy/template_param_builder.rb +84 -0
  77. data/lib/shopify_cli/theme/dev_server/proxy.rb +10 -15
  78. data/lib/shopify_cli/theme/dev_server/reload_mode.rb +34 -0
  79. data/lib/shopify_cli/theme/dev_server.rb +8 -21
  80. data/lib/shopify_cli/theme/file.rb +2 -2
  81. data/lib/shopify_cli/theme/filter/path_matcher.rb +38 -0
  82. data/lib/shopify_cli/theme/ignore_filter.rb +14 -18
  83. data/lib/shopify_cli/theme/include_filter.rb +43 -0
  84. data/lib/shopify_cli/theme/syncer.rb +17 -2
  85. data/lib/shopify_cli/theme/theme.rb +26 -4
  86. data/lib/shopify_cli/thread_pool/job.rb +27 -0
  87. data/lib/shopify_cli/thread_pool.rb +37 -0
  88. data/lib/shopify_cli/version.rb +1 -1
  89. data/lib/shopify_cli.rb +6 -1
  90. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +3 -1
  91. data/vendor/deps/ruby2_keywords/LICENSE +22 -0
  92. data/vendor/deps/ruby2_keywords/README.md +67 -0
  93. data/vendor/deps/ruby2_keywords/Rakefile +54 -0
  94. data/vendor/deps/ruby2_keywords/lib/ruby2_keywords.rb +57 -0
  95. data/vendor/deps/ruby2_keywords/ruby2_keywords.gemspec +18 -0
  96. data/vendor/deps/ruby2_keywords/test/test_keyword.rb +41 -0
  97. metadata +28 -4
  98. data/lib/graphql/all_orgs_with_extensions.graphql +0 -37
  99. data/lib/project_types/extension/tasks/run_extension_command.rb +0 -82
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f839cd234fbc37b84d85cc7ba1efddedf6b1571adba40562b3f4296286ca0130
4
- data.tar.gz: fb66a6a0728d317bddc220e1af1c4fa0049bd42e34cbef6f4310daa19cfe9e86
3
+ metadata.gz: a580fc4c23a82fc147e126d1f2cc4b057e5194e75e9c3045e2fa26c97f3d88da
4
+ data.tar.gz: 7cd7c21a2bac85a9f0bd3809acfb2ae7389f99be65e34e4411cb4fc4bc6235e8
5
5
  SHA512:
6
- metadata.gz: 11c1e49165ad7140139fe89b56e55287e6a3facca584c18234a4dbb302428d01a62cf2f4c5c27edf1943c9ec7f6610c8733fc1689b3cb78f9425b01c2f4f3836
7
- data.tar.gz: 8fc34d5588a785bbd8fa7f47b0dc8f9682dc955a8c23aa733dd33e39e37ebc9fbe898c542314ea16604a7f08a384d54ec693c8eb129af7bde0a156567c345058
6
+ metadata.gz: 8ef4d2ddcb62c393d7ad69fca6cbdfd577926522fcafe6f172f3370cc4a55d8bf3db68f8fc154dbb6c483b38f718df7991e43c773801c27e1f7a055e3cd0ed1b
7
+ data.tar.gz: 94d84b3588aeb62ee53f49593e486e268d58a112d73cdae15e2212dbb4a356ba736ff5e5adf31db4d979e83d7e1a8f56650911b0aab89837ef251f73ce6926b4
data/.gitignore CHANGED
@@ -23,3 +23,4 @@ packaging/rpm/shopify-cli.spec
23
23
  ext/shopify-extensions/shopify-extensions
24
24
  ext/javy/bin
25
25
  .console_history
26
+ TODO.md
data/CHANGELOG.md CHANGED
@@ -1,8 +1,52 @@
1
1
  From version 2.6.0, the sections in this file adhere to the [keep a changelog](https://keepachangelog.com/en/1.0.0/) specification.
2
+
3
+ ## [Unreleased]
4
+
5
+ ## Version 2.10.0
6
+ ### Fixed
7
+ * [#1937](https://github.com/Shopify/shopify-cli/pull/1937): Fix `theme pull` to no longer add empty lines on Windows
8
+ * [#1952](https://github.com/Shopify/shopify-cli/pull/1952): Fix CORS (cross-origin resource sharing) errors
9
+ * [#1965](https://github.com/Shopify/shopify-cli/pull/1965): Revert: Fix partners ability to login to external shops. (#1873)
10
+
11
+ ### Added
12
+ * [#1892](https://github.com/Shopify/shopify-cli/pull/1892): Add `-o`/`--only` parameter to filter files on `theme push`/`theme pull` commands
13
+
14
+ ## Version 2.9.0
15
+ ### Fixed
16
+ * [#1922](https://github.com/Shopify/shopify-cli/pull/1922): Respect RUBY_BINDIR from Homebrew for installing gem
17
+ * [#1906](https://github.com/Shopify/shopify-cli/pull/1906): Fix Ngrok incompatibility with some Apple ARM environments
18
+ * [#1873](https://github.com/Shopify/shopify-cli/pull/1873): Fix partners ability to login to external shops.
19
+ * [#1909](https://github.com/Shopify/shopify-cli/pull/1909): Fix `theme serve` on Safari
20
+
21
+ ### Added
22
+ * [#1900](https://github.com/Shopify/shopify-cli/pull/1900): Add `-d`/`--development` flag to Shopify theme pull command
23
+ * [#1891](https://github.com/Shopify/shopify-cli/pull/1891): Allow for additional arguments in `shopify push script` on CI.
24
+ * [#1877](https://github.com/Shopify/shopify-cli/pull/1877): Add theme (`-t`/`--theme=NAME_OR_ID`) parameter to `theme push`/`theme pull` commands
25
+ * [#1871](https://github.com/Shopify/shopify-cli/pull/1871): Add a new `--live-reload` parameter to the `theme serve` command
26
+
27
+ ### Changed
28
+ - [#1929](https://github.com/Shopify/shopify-cli/pull/1929): Rename `--registration-id` to `--extension-id` in `shopify extension push`.
29
+
30
+ ## Version 2.8.0
31
+ ### Fixed
32
+ * [#1879](https://github.com/Shopify/shopify-cli/pull/1879): Disambiguate -s as store option
33
+
34
+ ## Version 2.7.4
35
+ ### Added
36
+ * [#1825](https://github.com/Shopify/shopify-cli/pull/1825): Support passing the connection information through arguments
37
+
38
+ ### Fixed
39
+ * [#1852](https://github.com/Shopify/shopify-cli/pull/1852): Fix `shopify --help` to include `extension` commands
40
+ * [#1853](https://github.com/Shopify/shopify-cli/pull/1853): Fix javy installation failures from MacOS universal ruby installations
41
+ * [#1851](https://github.com/Shopify/shopify-cli/pull/1851): Improve `shopify theme push --live` confirmation message to show current live theme
42
+ * [#1850](https://github.com/Shopify/shopify-cli/pull/1850): Fix `shopify extension` commands timeout when organization has too many apps
43
+ * [#1860](https://github.com/Shopify/shopify-cli/pull/1860): Fix `theme serve` hot reload when there are many tabs active
44
+
2
45
  ## Version 2.7.3
3
46
  ### Added
4
47
  * [#1826](https://github.com/Shopify/shopify-cli/pull/1826): Support using `script.config.yml` file for script configuration
5
48
  * [#1843](https://github.com/Shopify/shopify-cli/pull/1826): Support using javy on Apple ARM processors
49
+ * [#1847](https://github.com/Shopify/shopify-cli/pull/1847): `shopify script connect` command.
6
50
 
7
51
  ### Fixed
8
52
  * [#1811](https://github.com/Shopify/shopify-cli/pull/1811): Update theme-check to 1.9.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify-cli (2.7.3)
4
+ shopify-cli (2.10.0)
5
5
  bugsnag (~> 6.22)
6
6
  listen (~> 3.7.0)
7
7
  theme-check (~> 1.9.0)
data/RELEASING.md CHANGED
@@ -23,21 +23,22 @@
23
23
  ```
24
24
 
25
25
  9. Open a PR for the branch, get necessary approvals from code owners and merge into main branch. Note that the PR title will be the release note in Shipit, so make sure it mentions the release
26
- 10. Deploy using Shipit
26
+ 10. Deploy to RubyGems using [Shipit](https://shipit.shopify.io/shopify/shopify-cli/rubygems)
27
27
  11. Update your `main` branch to the latest version
28
28
  ```
29
29
  $ git checkout main
30
30
  $ git pull
31
31
  ```
32
32
 
33
- 12. On local machine and _AFTER_ gem has been published to https://rubygems.org, run
33
+ 12. On local machine and _AFTER_ gem has been published to https://rubygems.org/gems/shopify-cli, run
34
34
  ```
35
35
  $ rake package
36
36
  ```
37
37
  This will generate the `.deb`, `.rpm` and brew formula files, which will be located in `packaging/builds/X.Y.Z/`.
38
38
 
39
39
  13. Clone the `Shopify/homebrew-shopify` repository (if not already cloned), and then
40
- * create a branch named `release_X_Y_Z_of_shopify-cli`
40
+ * update your `master` branch to the latest version: `git checkout master && git pull`
41
+ * create a new branch: `git checkout -b release_X_Y_Z_of_shopify-cli`
41
42
  * update the brew formula in `shopify-cli.rb` with the generated formula in `packaging/builds/X.Y.Z/` in the `Shopify/shopify-cli` repo (from the `rake package` step above)
42
43
  * commit the change and create a PR on the [Shopify Homebrew repository](https://github.com/Shopify/homebrew-shopify)
43
44
  * when PR is approved, merge into main branch
data/dev.yml CHANGED
@@ -9,9 +9,9 @@ up:
9
9
  - ruby: 2.7.5
10
10
  - homebrew:
11
11
  - dpkg:
12
- version: 1.20.9
12
+ version: 1.21.1
13
13
  - rpm:
14
- version: 4.16.1.3
14
+ version: 4.17.0
15
15
  - bundler
16
16
  - docker
17
17
 
data/ext/javy/javy.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "rbconfig"
2
1
  require "open-uri"
3
2
  require "zlib"
4
3
  require "open3"
@@ -6,7 +5,7 @@ require "digest/sha2"
6
5
 
7
6
  module Javy
8
7
  ROOT = __dir__
9
- BIN_FOLDER = File.join(ROOT, "bin")
8
+ BIN_FOLDER = File.join(ShopifyCLI.cache_dir, "javy", "bin")
10
9
  HASH_FOLDER = File.join(ROOT, "hashes")
11
10
  VERSION = File.read(File.join(ROOT, "version")).strip
12
11
  TARGET = File.join(BIN_FOLDER, "javy-#{VERSION}")
@@ -162,9 +161,9 @@ module Javy
162
161
  end
163
162
  end
164
163
 
165
- Platform = Struct.new(:ruby_config) do
166
- def initialize(ruby_config = RbConfig::CONFIG)
167
- super(ruby_config)
164
+ Platform = Struct.new(:ruby_platform) do
165
+ def initialize(ruby_platform = RUBY_PLATFORM)
166
+ super(ruby_platform)
168
167
  end
169
168
 
170
169
  def to_s
@@ -172,7 +171,7 @@ module Javy
172
171
  end
173
172
 
174
173
  def os
175
- case ruby_config.fetch("host_os")
174
+ case ruby_platform
176
175
  when /linux/
177
176
  "linux"
178
177
  when /darwin/
@@ -183,10 +182,10 @@ module Javy
183
182
  end
184
183
 
185
184
  def cpu
186
- case ruby_config.fetch("host_cpu")
187
- when "x64", "x86_64"
185
+ case ruby_platform
186
+ when /x64/, /x86_64/
188
187
  "x86_64"
189
- when "arm"
188
+ when /arm/
190
189
  "arm"
191
190
  else
192
191
  raise InstallationError.cpu_unsupported
@@ -0,0 +1,27 @@
1
+ query GetExtensionRegistrations($api_key: String!, $type: String) {
2
+ app(apiKey: $api_key) {
3
+ id
4
+ title
5
+ apiKey
6
+ apiSecretKeys{
7
+ secret
8
+ }
9
+ appType
10
+ extensionRegistrations(specificationIdentifier: $type) {
11
+ id
12
+ type
13
+ uuid
14
+ title
15
+ draftVersion {
16
+ registrationId
17
+ context
18
+ lastUserInteractionAt
19
+ location
20
+ validationErrors { field message }
21
+ id
22
+ uuid
23
+ versionTag
24
+ }
25
+ }
26
+ }
27
+ }
@@ -13,7 +13,6 @@ module Extension
13
13
  end
14
14
 
15
15
  class Command < ShopifyCLI::Command::ProjectCommand
16
- hidden_feature
17
16
  autoload :ExtensionCommand, Project.project_filepath("commands/extension_command")
18
17
 
19
18
  subcommand :Create, "create", Project.project_filepath("commands/create")
@@ -41,7 +40,6 @@ module Extension
41
40
  autoload :FindNpmPackages, Project.project_filepath("tasks/find_npm_packages")
42
41
  autoload :GetExtensions, Project.project_filepath("tasks/get_extensions")
43
42
  autoload :GetProduct, Project.project_filepath("tasks/get_product")
44
- autoload :RunExtensionCommand, Project.project_filepath("tasks/run_extension_command")
45
43
  autoload :MergeServerConfig, Project.project_filepath("tasks/merge_server_config")
46
44
  autoload :FindPackageFromJson, Project.project_filepath("tasks/find_package_from_json.rb")
47
45
  autoload :EnsureResourceUrl, Project.project_filepath("tasks/ensure_resource_url.rb")
@@ -53,6 +51,28 @@ module Extension
53
51
  autoload :ValidationErrorConverter, Project.project_filepath("tasks/converters/validation_error_converter")
54
52
  autoload :AppConverter, Project.project_filepath("tasks/converters/app_converter")
55
53
  autoload :ProductConverter, Project.project_filepath("tasks/converters/product_converter")
54
+ autoload :ExecuteCommands, Project.project_filepath("cli/execute_commands")
55
+ end
56
+
57
+ module ExecuteCommands
58
+ autoload :Base, Project.project_filepath("tasks/execute_commands/base")
59
+ autoload :Build, Project.project_filepath("tasks/execute_commands/build")
60
+ autoload :Create, Project.project_filepath("tasks/execute_commands/create")
61
+ autoload :Serve, Project.project_filepath("tasks/execute_commands/serve")
62
+
63
+ class << self
64
+ def build(*args)
65
+ Build.new(*args).call
66
+ end
67
+
68
+ def create(*args)
69
+ Create.new(*args).call
70
+ end
71
+
72
+ def serve(*args)
73
+ Serve.new(*args).call
74
+ end
75
+ end
56
76
  end
57
77
  end
58
78
 
@@ -121,4 +141,9 @@ module Extension
121
141
  autoload :ExtensionProjectKeys, Project.project_filepath("extension_project_keys")
122
142
  autoload :ExtensionProject, Project.project_filepath("extension_project")
123
143
  autoload :Errors, Project.project_filepath("errors")
144
+
145
+ module Loaders
146
+ autoload :Project, Extension::Project.project_filepath("loaders/project")
147
+ autoload :SpecificationHandler, Extension::Project.project_filepath("loaders/specification_handler")
148
+ end
124
149
  end
@@ -24,16 +24,16 @@ module Extension
24
24
  private
25
25
 
26
26
  def run_new_flow(project)
27
- output = Tasks::RunExtensionCommand.new(
28
- type: project.specification_identifier.downcase,
29
- command: "build",
30
- config_file_name: specification_handler.server_config_file,
31
- context: @ctx,
32
- ).call
33
-
34
- @ctx.puts(output)
35
- rescue => error
36
- raise ShopifyCLI::Abort, error.message
27
+ Tasks::ExecuteCommands
28
+ .build(
29
+ context: @ctx,
30
+ config_file_path: specification_handler.server_config_path,
31
+ type: project.specification_identifier.downcase
32
+ )
33
+ .then { |output| @ctx.puts(output) }
34
+ .unwrap do |error|
35
+ raise ShopifyCLI::Abort, error.message unless error.nil?
36
+ end
37
37
  end
38
38
 
39
39
  def run_legacy_flow
@@ -53,12 +53,11 @@ module Extension
53
53
  end
54
54
 
55
55
  def use_new_create_flow(form)
56
- Tasks::RunExtensionCommand.new(
56
+ Tasks::ExecuteCommands.create(
57
57
  root_dir: form.directory_name,
58
58
  template: form.template,
59
59
  type: form.type.identifier.downcase,
60
- command: "create"
61
- ).call
60
+ )
62
61
  @ctx.chdir(form.directory_name)
63
62
  write_env_file(form)
64
63
  rescue => error
@@ -3,17 +3,40 @@ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  class Command
6
- class Push < ExtensionCommand
6
+ class Push < ShopifyCLI::Command::SubCommand
7
7
  prerequisite_task ensure_project_type: :extension
8
8
 
9
+ options do |parser, flags|
10
+ parser.on("--api-key=API_KEY") { |api_key| flags[:api_key] = api_key.gsub('"', "") }
11
+ parser.on("--api-secret=API_SECRET") { |api_secret| flags[:api_secret] = api_secret.gsub('"', "") }
12
+ parser.on("--extension-id=EXTENSION_ID") do |registration_id|
13
+ flags[:registration_id] = registration_id.gsub('"', "")
14
+ end
15
+ end
16
+
9
17
  TIME_DISPLAY_FORMAT = "%B %d, %Y %H:%M:%S %Z"
10
18
 
11
19
  def call(args, name)
12
- Command::Register.new(@ctx).call(args, name) unless project.registered?
20
+ project = Extension::Loaders::Project.load(
21
+ context: @ctx,
22
+ directory: Dir.pwd,
23
+ api_key: options.flags[:api_key],
24
+ api_secret: options.flags[:api_secret],
25
+ registration_id: options.flags[:registration_id]
26
+ )
27
+ specification_handler = Extension::Loaders::SpecificationHandler.load(project: project, context: @ctx)
28
+ register_if_necessary(project: project, args: args, name: name)
29
+
13
30
  Command::Build.new(@ctx).call(args, name) unless specification_handler.specification.options[:skip_build]
14
31
  CLI::UI::Frame.open(@ctx.message("push.frame_title")) do
15
- updated_draft_version = update_draft
16
- show_message(updated_draft_version)
32
+ updated_draft_version = update_draft(project: project, specification_handler: specification_handler)
33
+ show_message(updated_draft_version, project: project)
34
+ end
35
+ end
36
+
37
+ def register_if_necessary(project:, args:, name:)
38
+ if ShopifyCLI::Environment.interactive? && !project.registered?
39
+ Command::Register.new(@ctx).call(args, name)
17
40
  end
18
41
  end
19
42
 
@@ -23,11 +46,16 @@ module Extension
23
46
 
24
47
  private
25
48
 
26
- def show_message(draft)
27
- draft.validation_errors.empty? ? output_success_messages(draft) : output_validation_errors(draft)
49
+ def show_message(draft, project:)
50
+ if draft.validation_errors.empty?
51
+ output_success_messages(draft,
52
+ project: project)
53
+ else
54
+ output_validation_errors(draft)
55
+ end
28
56
  end
29
57
 
30
- def output_success_messages(draft)
58
+ def output_success_messages(draft, project:)
31
59
  @ctx.puts(@ctx.message("push.success_confirmation", project.title, format_time(draft.last_user_interaction_at)))
32
60
  @ctx.puts(@ctx.message("push.success_info", draft.location))
33
61
  end
@@ -51,7 +79,7 @@ module Extension
51
79
  yield
52
80
  end
53
81
 
54
- def update_draft
82
+ def update_draft(project:, specification_handler:)
55
83
  with_waiting_text do
56
84
  Tasks::UpdateDraft.call(
57
85
  context: @ctx,
@@ -74,7 +74,7 @@ module Extension
74
74
  end
75
75
 
76
76
  def registered?
77
- property_present?("api_key") && property_present?("secret") && registration_id?
77
+ registration_id?
78
78
  end
79
79
 
80
80
  def title
@@ -9,7 +9,7 @@ module Extension
9
9
  property! :specification_handler, accepts: Extension::Models::SpecificationHandlers::Default
10
10
  property :argo_runtime, accepts: -> (runtime) { runtime.class < Features::Runtimes::Base }
11
11
  property! :context, accepts: ShopifyCLI::Context
12
- property! :port, accepts: Integer, default: 39351
12
+ property! :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
13
13
  property :tunnel_url, accepts: String, default: nil
14
14
  property! :js_system, accepts: ->(jss) { jss.respond_to?(:call) }, default: ShopifyCLI::JsSystem
15
15
  property :resource_url, accepts: String, default: nil
@@ -95,15 +95,16 @@ module Extension
95
95
  end
96
96
 
97
97
  def new_serve_flow
98
- Tasks::RunExtensionCommand.new(
98
+ Tasks::ExecuteCommands.serve(
99
99
  type: specification_handler.specification.identifier,
100
- command: "serve",
101
100
  context: context,
101
+ config_file_path: specification_handler.server_config_path,
102
102
  port: port,
103
- config_file_name: specification_handler.server_config_file,
104
103
  resource_url: resource_url,
105
104
  tunnel_url: tunnel_url
106
- ).call
105
+ ).unwrap do |error|
106
+ raise error unless error.nil?
107
+ end
107
108
  end
108
109
 
109
110
  def supports_development_server?
@@ -34,8 +34,12 @@ module Extension
34
34
  end
35
35
 
36
36
  def load_registrations(type)
37
- ctx.puts(@ctx.message("connect.loading_extensions"))
38
- registrations = Tasks::GetExtensions.call(context: ctx, type: type)
37
+ registrations = []
38
+ loading_extensions = @ctx.message("connect.loading_extensions")
39
+
40
+ CLI::UI::Spinner.spin(loading_extensions) do |_spinner|
41
+ registrations += Tasks::GetExtensions.call(context: ctx, type: type)
42
+ end
39
43
 
40
44
  registrations.empty? ? abort_no_registrations : registrations
41
45
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Loaders
5
+ module Project
6
+ def self.load(context:, directory:, api_key:, registration_id:, api_secret:)
7
+ env_overrides = {
8
+ "SHOPIFY_API_KEY" => api_key,
9
+ "SHOPIFY_API_SECRET" => api_secret,
10
+ "EXTENSION_ID" => registration_id,
11
+ }.compact
12
+ env =
13
+ begin
14
+ ShopifyCLI::Resources::EnvFile.read(directory, overrides: env_overrides)
15
+ rescue Errno::ENOENT
16
+ ShopifyCLI::Resources::EnvFile.from_hash(env_overrides)
17
+ end
18
+ # This is a somewhat uncomfortable hack we use because `Project::at` is
19
+ # a global cache and we can't rely on this class loading the project
20
+ # first. Long-term we should move away from that global cache.
21
+ project = ExtensionProject.at(directory)
22
+ project.env = env
23
+ project
24
+ rescue SmartProperties::InitializationError, SmartProperties::MissingValueError
25
+ context.abort(context.message("errors.missing_api_key"))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Extension
4
+ module Loaders
5
+ module SpecificationHandler
6
+ def self.load(project:, context:)
7
+ identifier = project.specification_identifier
8
+ Models::LazySpecificationHandler.new(identifier) do
9
+ specifications = Models::Specifications.new(
10
+ fetch_specifications: Tasks::FetchSpecifications.new(api_key: project.app.api_key, context: context)
11
+ )
12
+
13
+ unless specifications.valid?(identifier)
14
+ raise ShopifyCLI::Abort, context.message("errors.unknown_type", project.specification_identifier)
15
+ end
16
+
17
+ specifications[identifier]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -89,6 +89,9 @@ module Extension
89
89
  help: <<~HELP,
90
90
  Push the current extension to Shopify.
91
91
  Usage: {{command:%s extension push}}
92
+ Options:
93
+ {{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).
94
+ {{command:--extension-id=EXTENSION_ID}} The id of the extension's registration.
92
95
  HELP
93
96
  frame_title: "Pushing your extension to Shopify",
94
97
  waiting_text: "Pushing code to Shopify…",
@@ -173,6 +176,7 @@ module Extension
173
176
  errors: {
174
177
  unknown_type: "Unknown extension type %s",
175
178
  package_not_found: "`%s` package not found.",
179
+ missing_api_key: "Missing api_key.",
176
180
  module_not_found: "Unable to find module %s. Ensure your dependencies are up-to-date and try again.",
177
181
  },
178
182
  warnings: {
@@ -6,7 +6,7 @@ module Extension
6
6
  include SmartProperties
7
7
 
8
8
  property! :api_key, accepts: String
9
- property! :secret, accepts: String
9
+ property :secret, accepts: String
10
10
  property :title, accepts: String
11
11
  property :business_name, accepts: String
12
12
  end
@@ -40,7 +40,7 @@ module Extension
40
40
 
41
41
  def serve(context, server_config)
42
42
  CLI::Kit::System.popen3(executable, "serve", "-") do |input, out, err, status|
43
- context.puts("Sending configuration data …")
43
+ context.debug("Sending configuration data to extension development server …")
44
44
  input << server_config.to_yaml
45
45
  input.close
46
46
 
@@ -57,17 +57,15 @@ module Extension
57
57
  private
58
58
 
59
59
  def forward_output_to_user(out, err, ctx)
60
- ctx.puts("Starting monitoring threads …")
60
+ ctx.debug("Starting message processing threads to relay output produced by the extension development server …")
61
61
 
62
62
  Thread.new do
63
- ctx.puts("Ready to process standard output")
64
63
  while (line = out.gets)
65
64
  ctx.puts(line)
66
65
  end
67
66
  end
68
67
 
69
68
  Thread.new do
70
- ctx.puts("Ready to process standard error")
71
69
  while (error = err.gets)
72
70
  ctx.puts(error)
73
71
  end
@@ -103,6 +103,10 @@ module Extension
103
103
  raise NotImplementedError
104
104
  end
105
105
 
106
+ def server_config_path(base_dir = Dir.pwd)
107
+ File.join(base_dir, server_config_file)
108
+ end
109
+
106
110
  def server_config_file
107
111
  "shopifile.yml"
108
112
  end
@@ -9,11 +9,12 @@ module Extension
9
9
  property! :api_key, accepts: String
10
10
  property! :context, accepts: ShopifyCLI::Context
11
11
  property! :hash, accepts: Hash
12
+ property :port, accepts: Integer, default: ShopifyCLI::Constants::Extension::DEFAULT_PORT
12
13
  property! :registration_uuid, accepts: String
13
14
  property :resource_url, accepts: String
14
15
  property! :store, accepts: String
15
16
  property! :title, accepts: String
16
- property :tunnel_url, accepts: String
17
+ property :tunnel_url, accepts: String
17
18
  property! :type, accepts: String
18
19
 
19
20
  def self.call(*args)
@@ -46,6 +47,7 @@ module Extension
46
47
  end
47
48
  server_config = Models::ServerConfig::Root.new(
48
49
  extensions: [extension],
50
+ port: port,
49
51
  public_url: tunnel_url,
50
52
  store: store
51
53
  )
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Base
8
+ include SmartProperties
9
+ property! :type, accepts: Models::DevelopmentServerRequirements::SUPPORTED_EXTENSION_TYPES
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Build < Base
8
+ property! :context, accepts: ShopifyCLI::Context
9
+ property! :config_file_path, accepts: String
10
+
11
+ def call
12
+ ShopifyCLI::Result
13
+ .call(&method(:merge_server_config))
14
+ .then { |server_config| Models::DevelopmentServer.new.build(server_config) }
15
+ end
16
+
17
+ private
18
+
19
+ def merge_server_config
20
+ Tasks::MergeServerConfig.call(
21
+ context: context,
22
+ file_path: config_file_path,
23
+ type: type
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module Extension
5
+ module Tasks
6
+ module ExecuteCommands
7
+ class Create < Base
8
+ property! :template, accepts: Models::ServerConfig::Development::VALID_TEMPLATES
9
+ property! :root_dir, accepts: String
10
+
11
+ def call
12
+ ShopifyCLI::Result.success(generate_config)
13
+ .then { |server_config| Models::DevelopmentServer.new.create(server_config) }
14
+ .unwrap do |error|
15
+ raise error unless error.nil?
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def generate_config
22
+ extension = Models::ServerConfig::Extension.build(
23
+ template: template,
24
+ type: type,
25
+ root_dir: root_dir,
26
+ )
27
+
28
+ Models::ServerConfig::Root.new(extensions: [extension])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end