shopify-cli 2.2.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +0 -4
  4. data/.github/workflows/shopify.yml +104 -0
  5. data/.gitignore +3 -0
  6. data/.rubocop.yml +14 -14
  7. data/.rubocop_todo.yml +3 -3
  8. data/CHANGELOG.md +30 -0
  9. data/CONTRIBUTING.md +23 -0
  10. data/Dockerfile +17 -0
  11. data/Gemfile +1 -0
  12. data/Gemfile.lock +67 -24
  13. data/RELEASING.md +1 -1
  14. data/Rakefile +75 -18
  15. data/bin/console +11 -0
  16. data/bin/shopify +16 -4
  17. data/dev.yml +14 -1
  18. data/ext/shopify-cli/extconf.rb +2 -0
  19. data/ext/shopify-extensions/extconf.rb +21 -0
  20. data/ext/shopify-extensions/shopify_extensions.rb +152 -0
  21. data/ext/shopify-extensions/version +1 -0
  22. data/lib/project_types/extension/cli.rb +19 -3
  23. data/lib/project_types/extension/commands/build.rb +32 -3
  24. data/lib/project_types/extension/commands/check.rb +2 -2
  25. data/lib/project_types/extension/commands/connect.rb +1 -1
  26. data/lib/project_types/extension/commands/create.rb +59 -16
  27. data/lib/project_types/extension/commands/extension_command.rb +1 -1
  28. data/lib/project_types/extension/commands/info.rb +1 -1
  29. data/lib/project_types/extension/commands/push.rb +1 -1
  30. data/lib/project_types/extension/commands/register.rb +2 -2
  31. data/lib/project_types/extension/commands/serve.rb +5 -5
  32. data/lib/project_types/extension/commands/tunnel.rb +6 -6
  33. data/lib/project_types/extension/extension_project.rb +4 -4
  34. data/lib/project_types/extension/features/argo.rb +3 -3
  35. data/lib/project_types/extension/features/argo_config.rb +5 -5
  36. data/lib/project_types/extension/features/argo_serve.rb +21 -6
  37. data/lib/project_types/extension/features/argo_setup.rb +1 -1
  38. data/lib/project_types/extension/features/argo_setup_step.rb +1 -1
  39. data/lib/project_types/extension/features/argo_setup_steps.rb +2 -2
  40. data/lib/project_types/extension/forms/connect.rb +2 -2
  41. data/lib/project_types/extension/forms/create.rb +6 -3
  42. data/lib/project_types/extension/forms/questions/ask_app.rb +2 -2
  43. data/lib/project_types/extension/forms/questions/ask_name.rb +1 -1
  44. data/lib/project_types/extension/forms/questions/ask_registration.rb +2 -2
  45. data/lib/project_types/extension/forms/questions/ask_template.rb +44 -0
  46. data/lib/project_types/extension/forms/questions/ask_type.rb +2 -2
  47. data/lib/project_types/extension/messages/message_loading.rb +2 -2
  48. data/lib/project_types/extension/messages/messages.rb +3 -0
  49. data/lib/project_types/extension/models/development_server.rb +78 -0
  50. data/lib/project_types/extension/models/development_server_requirements.rb +35 -0
  51. data/lib/project_types/extension/models/lazy_specification_handler.rb +1 -1
  52. data/lib/project_types/extension/models/server_config/base.rb +31 -0
  53. data/lib/project_types/extension/models/server_config/development.rb +23 -0
  54. data/lib/project_types/extension/models/server_config/development_entries.rb +38 -0
  55. data/lib/project_types/extension/models/server_config/development_renderer.rb +30 -0
  56. data/lib/project_types/extension/models/server_config/extension.rb +35 -0
  57. data/lib/project_types/extension/models/server_config/root.rb +18 -0
  58. data/lib/project_types/extension/models/server_config/user.rb +10 -0
  59. data/lib/project_types/extension/models/specification.rb +1 -1
  60. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +1 -1
  61. data/lib/project_types/extension/models/specification_handlers/default.rb +14 -2
  62. data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +1 -1
  63. data/lib/project_types/extension/models/specifications.rb +4 -4
  64. data/lib/project_types/extension/tasks/choose_next_available_port.rb +2 -2
  65. data/lib/project_types/extension/tasks/configure_features.rb +1 -1
  66. data/lib/project_types/extension/tasks/configure_options.rb +1 -1
  67. data/lib/project_types/extension/tasks/converters/product_converter.rb +1 -1
  68. data/lib/project_types/extension/tasks/converters/server_config_converter.rb +31 -0
  69. data/lib/project_types/extension/tasks/create_extension.rb +2 -2
  70. data/lib/project_types/extension/tasks/fetch_specifications.rb +2 -2
  71. data/lib/project_types/extension/tasks/find_npm_packages.rb +5 -5
  72. data/lib/project_types/extension/tasks/get_app.rb +2 -2
  73. data/lib/project_types/extension/tasks/get_apps.rb +2 -2
  74. data/lib/project_types/extension/tasks/get_extensions.rb +2 -2
  75. data/lib/project_types/extension/tasks/get_product.rb +2 -2
  76. data/lib/project_types/extension/tasks/load_server_config.rb +23 -0
  77. data/lib/project_types/extension/tasks/run_extension_command.rb +81 -0
  78. data/lib/project_types/extension/tasks/update_draft.rb +2 -2
  79. data/lib/project_types/node/cli.rb +3 -3
  80. data/lib/project_types/node/commands/connect.rb +4 -4
  81. data/lib/project_types/node/commands/create.rb +10 -14
  82. data/lib/project_types/node/commands/deploy/heroku.rb +4 -4
  83. data/lib/project_types/node/commands/deploy.rb +3 -3
  84. data/lib/project_types/node/commands/generate.rb +2 -2
  85. data/lib/project_types/node/commands/open.rb +3 -3
  86. data/lib/project_types/node/commands/serve.rb +15 -7
  87. data/lib/project_types/node/commands/tunnel.rb +6 -6
  88. data/lib/project_types/node/forms/create.rb +3 -3
  89. data/lib/project_types/node/messages/messages.rb +3 -0
  90. data/lib/project_types/php/cli.rb +27 -0
  91. data/lib/project_types/php/commands/connect.rb +19 -0
  92. data/lib/project_types/php/commands/create.rb +143 -0
  93. data/lib/project_types/php/commands/deploy/heroku.rb +129 -0
  94. data/lib/project_types/php/commands/deploy.rb +32 -0
  95. data/lib/project_types/php/commands/open.rb +16 -0
  96. data/lib/project_types/php/commands/serve.rb +51 -0
  97. data/lib/project_types/php/commands/tunnel.rb +37 -0
  98. data/lib/project_types/php/forms/create.rb +45 -0
  99. data/lib/project_types/php/messages/messages.rb +191 -0
  100. data/lib/project_types/rails/cli.rb +3 -3
  101. data/lib/project_types/rails/commands/connect.rb +4 -4
  102. data/lib/project_types/rails/commands/create.rb +12 -16
  103. data/lib/project_types/rails/commands/deploy/heroku.rb +4 -4
  104. data/lib/project_types/rails/commands/deploy.rb +3 -3
  105. data/lib/project_types/rails/commands/generate/webhook.rb +3 -3
  106. data/lib/project_types/rails/commands/generate.rb +3 -3
  107. data/lib/project_types/rails/commands/open.rb +3 -3
  108. data/lib/project_types/rails/commands/serve.rb +8 -8
  109. data/lib/project_types/rails/commands/tunnel.rb +6 -6
  110. data/lib/project_types/rails/forms/create.rb +3 -3
  111. data/lib/project_types/rails/gem.rb +1 -1
  112. data/lib/project_types/rails/ruby.rb +1 -1
  113. data/lib/project_types/script/cli.rb +16 -6
  114. data/lib/project_types/script/commands/create.rb +4 -2
  115. data/lib/project_types/script/commands/push.rb +2 -2
  116. data/lib/project_types/script/config/extension_points.yml +30 -29
  117. data/lib/project_types/script/forms/create.rb +1 -1
  118. data/lib/project_types/script/layers/application/create_script.rb +32 -12
  119. data/lib/project_types/script/layers/application/extension_points.rb +4 -4
  120. data/lib/project_types/script/layers/application/push_script.rb +13 -1
  121. data/lib/project_types/script/layers/domain/extension_point.rb +13 -45
  122. data/lib/project_types/script/layers/domain/push_package.rb +0 -12
  123. data/lib/project_types/script/layers/domain/script_project.rb +2 -2
  124. data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +57 -0
  125. data/lib/project_types/script/layers/infrastructure/api_clients/script_service_api_client.rb +35 -0
  126. data/lib/project_types/script/layers/infrastructure/command_runner.rb +1 -1
  127. data/lib/project_types/script/layers/infrastructure/errors.rb +5 -0
  128. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +10 -90
  129. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +76 -11
  130. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -1
  131. data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +33 -0
  132. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +105 -0
  133. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -1
  134. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +6 -6
  135. data/lib/project_types/script/layers/infrastructure/script_service.rb +25 -144
  136. data/lib/project_types/script/layers/infrastructure/script_uploader.rb +27 -0
  137. data/lib/project_types/script/layers/infrastructure/service_locator.rb +20 -0
  138. data/lib/project_types/script/messages/messages.rb +4 -0
  139. data/lib/project_types/script/tasks/ensure_env.rb +7 -7
  140. data/lib/project_types/script/ui/error_handler.rb +84 -76
  141. data/lib/project_types/script/ui/printing_spinner.rb +1 -1
  142. data/lib/project_types/theme/cli.rb +3 -3
  143. data/lib/project_types/theme/commands/check.rb +3 -3
  144. data/lib/project_types/theme/commands/delete.rb +7 -7
  145. data/lib/project_types/theme/commands/init.rb +3 -3
  146. data/lib/project_types/theme/commands/language_server.rb +2 -2
  147. data/lib/project_types/theme/commands/package.rb +2 -2
  148. data/lib/project_types/theme/commands/publish.rb +5 -5
  149. data/lib/project_types/theme/commands/pull.rb +15 -9
  150. data/lib/project_types/theme/commands/push.rb +18 -12
  151. data/lib/project_types/theme/commands/serve.rb +4 -4
  152. data/lib/project_types/theme/forms/confirm_store.rb +1 -1
  153. data/lib/project_types/theme/forms/select.rb +2 -2
  154. data/lib/{shopify-cli → shopify_cli}/admin_api/populate_resource_command.rb +3 -3
  155. data/lib/{shopify-cli → shopify_cli}/admin_api/schema.rb +4 -4
  156. data/lib/{shopify-cli → shopify_cli}/admin_api.rb +27 -27
  157. data/lib/{shopify-cli → shopify_cli}/api.rb +8 -8
  158. data/lib/shopify_cli/command/app_sub_command.rb +16 -0
  159. data/lib/{shopify-cli → shopify_cli}/command.rb +3 -3
  160. data/lib/{shopify-cli → shopify_cli}/commands/config.rb +14 -14
  161. data/lib/{shopify-cli → shopify_cli}/commands/help.rb +4 -4
  162. data/lib/{shopify-cli → shopify_cli}/commands/login.rb +7 -7
  163. data/lib/shopify_cli/commands/logout.rb +39 -0
  164. data/lib/{shopify-cli → shopify_cli}/commands/populate/customer.rb +4 -4
  165. data/lib/{shopify-cli → shopify_cli}/commands/populate/draft_order.rb +4 -4
  166. data/lib/{shopify-cli → shopify_cli}/commands/populate/product.rb +4 -4
  167. data/lib/shopify_cli/commands/populate.rb +23 -0
  168. data/lib/shopify_cli/commands/store.rb +15 -0
  169. data/lib/{shopify-cli → shopify_cli}/commands/switch.rb +5 -5
  170. data/lib/{shopify-cli → shopify_cli}/commands/system.rb +10 -10
  171. data/lib/shopify_cli/commands/version.rb +15 -0
  172. data/lib/{shopify-cli → shopify_cli}/commands/whoami.rb +7 -7
  173. data/lib/shopify_cli/commands.rb +34 -0
  174. data/lib/{shopify-cli → shopify_cli}/connect.rb +3 -3
  175. data/lib/shopify_cli/constants.rb +54 -0
  176. data/lib/{shopify-cli → shopify_cli}/context.rb +6 -6
  177. data/lib/{shopify-cli → shopify_cli}/core/entry_point.rb +7 -7
  178. data/lib/{shopify-cli → shopify_cli}/core/executor.rb +8 -4
  179. data/lib/{shopify-cli → shopify_cli}/core/finalize.rb +1 -1
  180. data/lib/{shopify-cli → shopify_cli}/core/help_resolver.rb +2 -2
  181. data/lib/{shopify-cli → shopify_cli}/core/monorail.rb +8 -8
  182. data/lib/shopify_cli/core.rb +8 -0
  183. data/lib/{shopify-cli → shopify_cli}/db.rb +8 -8
  184. data/lib/shopify_cli/environment.rb +91 -0
  185. data/lib/shopify_cli/exception_reporter/permission_controller.rb +54 -0
  186. data/lib/shopify_cli/exception_reporter.rb +55 -0
  187. data/lib/{shopify-cli → shopify_cli}/feature.rb +8 -8
  188. data/lib/{shopify-cli → shopify_cli}/form.rb +2 -2
  189. data/lib/{shopify-cli → shopify_cli}/git.rb +38 -8
  190. data/lib/{shopify-cli → shopify_cli}/helpers/haikunator.rb +1 -1
  191. data/lib/shopify_cli/helpers.rb +5 -0
  192. data/lib/{shopify-cli → shopify_cli}/heroku.rb +38 -13
  193. data/lib/{shopify-cli → shopify_cli}/http_request.rb +1 -1
  194. data/lib/{shopify-cli → shopify_cli}/identity_auth/servlet.rb +1 -1
  195. data/lib/{shopify-cli → shopify_cli}/identity_auth.rb +24 -31
  196. data/lib/{shopify-cli → shopify_cli}/js_deps.rb +7 -7
  197. data/lib/{shopify-cli → shopify_cli}/js_system.rb +10 -10
  198. data/lib/{shopify-cli → shopify_cli}/lazy_delegator.rb +2 -2
  199. data/lib/{shopify-cli → shopify_cli}/messages/messages.rb +44 -2
  200. data/lib/{shopify-cli → shopify_cli}/method_object.rb +15 -8
  201. data/lib/shopify_cli/migrator/migration.rb +27 -0
  202. data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +13 -0
  203. data/lib/shopify_cli/migrator.rb +48 -0
  204. data/lib/{shopify-cli → shopify_cli}/options.rb +1 -1
  205. data/lib/{shopify-cli → shopify_cli}/packager.rb +8 -8
  206. data/lib/{shopify-cli → shopify_cli}/partners_api/organizations.rb +1 -1
  207. data/lib/{shopify-cli → shopify_cli}/partners_api.rb +16 -40
  208. data/lib/shopify_cli/php_deps.rb +102 -0
  209. data/lib/{shopify-cli → shopify_cli}/process_supervision.rb +23 -21
  210. data/lib/{shopify-cli → shopify_cli}/project.rb +15 -15
  211. data/lib/{shopify-cli → shopify_cli}/project_commands.rb +3 -3
  212. data/lib/{shopify-cli → shopify_cli}/project_type.rb +5 -5
  213. data/lib/{shopify-cli → shopify_cli}/resolve_constant.rb +5 -5
  214. data/lib/{shopify-cli → shopify_cli}/resources/env_file.rb +1 -1
  215. data/lib/shopify_cli/resources.rb +5 -0
  216. data/lib/{shopify-cli → shopify_cli}/result.rb +11 -11
  217. data/lib/{shopify-cli → shopify_cli}/shopifolk.rb +6 -6
  218. data/lib/{shopify-cli → shopify_cli}/sub_command.rb +1 -1
  219. data/lib/{shopify-cli → shopify_cli}/task.rb +1 -1
  220. data/lib/{shopify-cli → shopify_cli}/tasks/confirm_store.rb +3 -3
  221. data/lib/{shopify-cli → shopify_cli}/tasks/create_api_client.rb +4 -4
  222. data/lib/shopify_cli/tasks/ensure_authenticated.rb +13 -0
  223. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_dev_store.rb +5 -5
  224. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_env.rb +3 -3
  225. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_loopback_url.rb +4 -4
  226. data/lib/{shopify-cli → shopify_cli}/tasks/ensure_project_type.rb +3 -3
  227. data/lib/{shopify-cli → shopify_cli}/tasks/select_org_and_shop.rb +8 -8
  228. data/lib/{shopify-cli → shopify_cli}/tasks/update_dashboard_urls.rb +6 -6
  229. data/lib/{shopify-cli → shopify_cli}/tasks.rb +10 -10
  230. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/certificate_manager.rb +5 -5
  231. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/header_hash.rb +5 -1
  232. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/hot-reload.js +0 -0
  233. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/hot_reload.rb +5 -6
  234. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/local_assets.rb +1 -1
  235. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/proxy.rb +15 -3
  236. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/sse.rb +1 -1
  237. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/watcher.rb +1 -1
  238. data/lib/{shopify-cli → shopify_cli}/theme/dev_server/web_server.rb +1 -1
  239. data/lib/{shopify-cli → shopify_cli}/theme/dev_server.rb +3 -3
  240. data/lib/shopify_cli/theme/development_theme.rb +83 -0
  241. data/lib/{shopify-cli → shopify_cli}/theme/file.rb +12 -4
  242. data/lib/{shopify-cli → shopify_cli}/theme/ignore_filter.rb +8 -1
  243. data/lib/{shopify-cli → shopify_cli}/theme/mime_type.rb +1 -1
  244. data/lib/{shopify-cli → shopify_cli}/theme/syncer.rb +7 -7
  245. data/lib/{shopify-cli → shopify_cli}/theme/theme.rb +4 -4
  246. data/lib/{shopify-cli → shopify_cli}/transform_data_structure.rb +4 -4
  247. data/lib/{shopify-cli → shopify_cli}/tunnel.rb +14 -14
  248. data/lib/shopify_cli/version.rb +3 -0
  249. data/lib/shopify_cli.rb +61 -50
  250. data/shopify-cli.gemspec +13 -5
  251. data/utilities/docker.rb +47 -0
  252. data/utilities/utilities.rb +5 -0
  253. metadata +155 -97
  254. data/.github/workflows/build.yml +0 -28
  255. data/lib/project_types/script/layers/infrastructure/languages/rust_project_creator.rb +0 -73
  256. data/lib/project_types/script/layers/infrastructure/languages/rust_task_runner.rb +0 -60
  257. data/lib/shopify-cli/commands/logout.rb +0 -39
  258. data/lib/shopify-cli/commands/populate.rb +0 -23
  259. data/lib/shopify-cli/commands/store.rb +0 -15
  260. data/lib/shopify-cli/commands/version.rb +0 -15
  261. data/lib/shopify-cli/commands.rb +0 -34
  262. data/lib/shopify-cli/core.rb +0 -8
  263. data/lib/shopify-cli/helpers.rb +0 -5
  264. data/lib/shopify-cli/resources.rb +0 -5
  265. data/lib/shopify-cli/tasks/ensure_authenticated.rb +0 -13
  266. data/lib/shopify-cli/theme/development_theme.rb +0 -69
  267. data/lib/shopify-cli/version.rb +0 -3
@@ -1,5 +1,6 @@
1
1
  require "rbconfig"
2
2
  require "fileutils"
3
+ require "date"
3
4
 
4
5
  gem = File.expand_path("../../../", __FILE__)
5
6
  exe = File.join(gem, "bin", "shopify")
@@ -56,4 +57,5 @@ else
56
57
  MAKEFILE
57
58
  end
58
59
 
60
+ File.write(installation_date_path, Time.now.to_i.to_s)
59
61
  File.write("Makefile", makefile_content)
@@ -0,0 +1,21 @@
1
+ require_relative "./shopify_extensions"
2
+
3
+ installation_dir = ENV.fetch("SHOPIFY_CLI_EXTENSIONS_INSTALLATION_DIR", __dir__)
4
+
5
+ File.write(File.expand_path("Makefile", installation_dir), <<~MAKEFILE)
6
+ .PHONY: clean
7
+
8
+ clean: ;
9
+
10
+ install: ;
11
+ MAKEFILE
12
+
13
+ begin
14
+ ShopifyExtensions.install(
15
+ target: File.expand_path("shopify-extensions", installation_dir)
16
+ )
17
+ rescue ShopifyExtensions::InstallationError => error
18
+ STDERR.puts(error.message)
19
+ rescue => error
20
+ STDERR.puts("Unable to install shopify-extensions: #{error}")
21
+ end
@@ -0,0 +1,152 @@
1
+ require "rbconfig"
2
+ require "open-uri"
3
+ require "zlib"
4
+ require "open3"
5
+
6
+ module ShopifyExtensions
7
+ def self.install(**args)
8
+ Install.call(**args)
9
+ end
10
+
11
+ class Install
12
+ def self.call(platform: Platform.new, **args)
13
+ new.call(platform: platform, **args)
14
+ end
15
+
16
+ def self.version
17
+ File.read(File.expand_path("../version", __FILE__)).strip
18
+ end
19
+
20
+ def call(platform:, version: self.class.version, target:)
21
+ target = platform.format_path(target.to_s)
22
+
23
+ asset = Asset.new(
24
+ platform: platform,
25
+ version: version,
26
+ owner: "Shopify",
27
+ repository: "shopify-cli-extensions",
28
+ basename: "shopify-extensions"
29
+ )
30
+ downloaded = asset.download(target: target)
31
+ raise InstallationError.asset_not_found(platform: platform, version: version) unless downloaded
32
+
33
+ raise InstallationError.installation_failed unless verify(target, version: version)
34
+ end
35
+
36
+ private
37
+
38
+ def fetch_release_details_for(version:)
39
+ JSON.parse(URI.parse(release_url_for(version: version)).open.read).yield_self(&Release)
40
+ rescue OpenURI::HTTPError
41
+ nil
42
+ end
43
+
44
+ def verify(target, version:)
45
+ return false unless File.executable?(target)
46
+ installed_server_version, exit_code = Open3.capture2(target, "version")
47
+ return false unless exit_code == 0
48
+ return false unless installed_server_version.strip == version.strip
49
+ true
50
+ end
51
+ end
52
+
53
+ class InstallationError < RuntimeError
54
+ def self.installation_failed
55
+ new("Failed to install shopify-extensions properly")
56
+ end
57
+
58
+ def self.asset_not_found(platform:, version:)
59
+ new(format(
60
+ "Unable to download shopify-extensions %{version} for %{os} (%{cpu})",
61
+ version: version,
62
+ os: platform.os,
63
+ cpu: platform.cpu
64
+ ))
65
+ end
66
+ end
67
+
68
+ Asset = Struct.new(:platform, :version, :owner, :repository, :basename, keyword_init: true) do
69
+ def download(target:)
70
+ Dir.chdir(File.dirname(target)) do
71
+ File.open(File.basename(target), "wb") do |target_file|
72
+ decompress(url.open, target_file)
73
+ end
74
+ File.chmod(0755, target)
75
+ end
76
+
77
+ true
78
+ rescue OpenURI::HTTPError
79
+ false
80
+ end
81
+
82
+ def url
83
+ URI.parse(format(
84
+ "https://github.com/%{owner}/%{repository}/releases/download/%{version}/%{filename}",
85
+ owner: owner,
86
+ repository: repository,
87
+ version: version,
88
+ filename: filename
89
+ ))
90
+ end
91
+
92
+ def filename
93
+ format(
94
+ "%{basename}-%{os}-%{cpu}.%{extension}",
95
+ basename: basename,
96
+ os: platform.os,
97
+ cpu: platform.cpu,
98
+ extension: platform.os == "windows" ? "exe.gz" : "gz"
99
+ )
100
+ end
101
+
102
+ private
103
+
104
+ def decompress(source, target)
105
+ zlib = Zlib::GzipReader.new(source)
106
+ target << zlib.read
107
+ ensure
108
+ zlib.close
109
+ end
110
+ end
111
+
112
+ Platform = Struct.new(:ruby_config) do
113
+ def initialize(ruby_config = RbConfig::CONFIG)
114
+ super(ruby_config)
115
+ end
116
+
117
+ def format_path(path)
118
+ case os
119
+ when "windows"
120
+ File.extname(path) != ".exe" ? path + ".exe" : path
121
+ else
122
+ path
123
+ end
124
+ end
125
+
126
+ def to_s
127
+ format("%{os}-%{cpu}", os: os, cpu: cpu)
128
+ end
129
+
130
+ def os
131
+ case ruby_config.fetch("host_os")
132
+ when /linux/
133
+ "linux"
134
+ when /darwin/
135
+ "darwin"
136
+ else
137
+ "windows"
138
+ end
139
+ end
140
+
141
+ def cpu
142
+ case ruby_config.fetch("host_cpu")
143
+ when /arm.*64/
144
+ "arm64"
145
+ when /64/
146
+ "amd64"
147
+ else
148
+ "386"
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1 @@
1
+ v0.1.0
@@ -3,7 +3,7 @@
3
3
  module Extension
4
4
  class PackageResolutionFailed < RuntimeError; end
5
5
 
6
- class Project < ShopifyCli::ProjectType
6
+ class Project < ShopifyCLI::ProjectType
7
7
  hidden_feature
8
8
 
9
9
  require Project.project_filepath("messages/messages")
@@ -12,7 +12,7 @@ module Extension
12
12
  register_messages(Extension::Messages::MessageLoading.load)
13
13
  end
14
14
 
15
- class Command < ShopifyCli::ProjectCommands
15
+ class Command < ShopifyCLI::ProjectCommands
16
16
  hidden_feature
17
17
  autoload :ExtensionCommand, Project.project_filepath("commands/extension_command")
18
18
 
@@ -26,7 +26,7 @@ module Extension
26
26
  subcommand :Tunnel, "tunnel", Project.project_filepath("commands/tunnel")
27
27
  subcommand :Check, "check", Project.project_filepath("commands/check")
28
28
  end
29
- ShopifyCli::Commands.register("Extension::Command", "extension")
29
+ ShopifyCLI::Commands.register("Extension::Command", "extension")
30
30
 
31
31
  module Tasks
32
32
  autoload :UserErrors, Project.project_filepath("tasks/user_errors")
@@ -41,6 +41,8 @@ module Extension
41
41
  autoload :FindNpmPackages, Project.project_filepath("tasks/find_npm_packages")
42
42
  autoload :GetExtensions, Project.project_filepath("tasks/get_extensions")
43
43
  autoload :GetProduct, Project.project_filepath("tasks/get_product")
44
+ autoload :RunExtensionCommand, Project.project_filepath("tasks/run_extension_command")
45
+ autoload :LoadServerConfig, Project.project_filepath("tasks/load_server_config")
44
46
 
45
47
  module Converters
46
48
  autoload :RegistrationConverter, Project.project_filepath("tasks/converters/registration_converter")
@@ -48,6 +50,7 @@ module Extension
48
50
  autoload :ValidationErrorConverter, Project.project_filepath("tasks/converters/validation_error_converter")
49
51
  autoload :AppConverter, Project.project_filepath("tasks/converters/app_converter")
50
52
  autoload :ProductConverter, Project.project_filepath("tasks/converters/product_converter")
53
+ autoload :ServerConfigConverter, Project.project_filepath("tasks/converters/server_config_converter")
51
54
  end
52
55
  end
53
56
 
@@ -55,6 +58,7 @@ module Extension
55
58
  module Questions
56
59
  autoload :AskApp, Project.project_filepath("forms/questions/ask_app")
57
60
  autoload :AskName, Project.project_filepath("forms/questions/ask_name")
61
+ autoload :AskTemplate, Project.project_filepath("forms/questions/ask_template")
58
62
  autoload :AskType, Project.project_filepath("forms/questions/ask_type")
59
63
  autoload :AskRegistration, Project.project_filepath("forms/questions/ask_registration")
60
64
  end
@@ -87,6 +91,16 @@ module Extension
87
91
  autoload :Default, Project.project_filepath("models/specification_handlers/default")
88
92
  end
89
93
 
94
+ module ServerConfig
95
+ autoload :Base, Project.project_filepath("models/server_config/base")
96
+ autoload :Development, Project.project_filepath("models/server_config/development")
97
+ autoload :DevelopmentEntries, Project.project_filepath("models/server_config/development_entries")
98
+ autoload :DevelopmentRenderer, Project.project_filepath("models/server_config/development_renderer")
99
+ autoload :Extension, Project.project_filepath("models/server_config/extension")
100
+ autoload :Root, Project.project_filepath("models/server_config/root")
101
+ autoload :User, Project.project_filepath("models/server_config/user")
102
+ end
103
+
90
104
  autoload :App, Project.project_filepath("models/app")
91
105
  autoload :Registration, Project.project_filepath("models/registration")
92
106
  autoload :Version, Project.project_filepath("models/version")
@@ -96,6 +110,8 @@ module Extension
96
110
  autoload :LazySpecificationHandler, Project.project_filepath("models/lazy_specification_handler")
97
111
  autoload :NpmPackage, Project.project_filepath("models/npm_package")
98
112
  autoload :Product, Project.project_filepath("models/product")
113
+ autoload :DevelopmentServer, Project.project_filepath("models/development_server")
114
+ autoload :DevelopmentServerRequirements, Project.project_filepath("models/development_server_requirements")
99
115
  end
100
116
 
101
117
  autoload :ExtensionProjectKeys, Project.project_filepath("extension_project_keys")
@@ -12,7 +12,36 @@ module Extension
12
12
  NPM_BUILD_COMMAND = %w(run-script build)
13
13
 
14
14
  def call(_args, _command_name)
15
- system = ShopifyCli::JsSystem.new(ctx: @ctx)
15
+ project = ExtensionProject.current(force_reload: true)
16
+ return run_new_flow(project) if supports_development_server?(project.specification_identifier)
17
+ run_legacy_flow
18
+ end
19
+
20
+ def self.help
21
+ ShopifyCLI::Context.new.message("build.help", ShopifyCLI::TOOL_NAME)
22
+ end
23
+
24
+ private
25
+
26
+ def run_new_flow(project)
27
+ Tasks::RunExtensionCommand.new(
28
+ type: project.specification_identifier.downcase,
29
+ command: "build",
30
+ config_file_name: specification_handler.server_config_file,
31
+ ).call
32
+
33
+ @ctx.puts(@ctx.message("build.build_success_message"))
34
+ rescue => error
35
+ if error.message.include?("no such file or directory")
36
+ @ctx.abort(@ctx.message("build.directory_not_found"))
37
+ else
38
+ @ctx.debug(error)
39
+ @ctx.abort(@ctx.message("build.build_failure_message"))
40
+ end
41
+ end
42
+
43
+ def run_legacy_flow
44
+ system = ShopifyCLI::JsSystem.new(ctx: @ctx)
16
45
 
17
46
  CLI::UI::Frame.open(@ctx.message("build.frame_title", system.package_manager)) do
18
47
  success = system.call(yarn: YARN_BUILD_COMMAND, npm: NPM_BUILD_COMMAND)
@@ -20,8 +49,8 @@ module Extension
20
49
  end
21
50
  end
22
51
 
23
- def self.help
24
- ShopifyCli::Context.new.message("build.help", ShopifyCli::TOOL_NAME)
52
+ def supports_development_server?(type)
53
+ Models::DevelopmentServerRequirements.supported?(type)
25
54
  end
26
55
  end
27
56
  end
@@ -4,7 +4,7 @@ require "theme_check"
4
4
  module Extension
5
5
  class Command
6
6
  class Check < ExtensionCommand
7
- class CheckOptions < ShopifyCli::Options
7
+ class CheckOptions < ShopifyCLI::Options
8
8
  def initialize(ctx, theme_check)
9
9
  super()
10
10
  @theme_check = theme_check
@@ -37,7 +37,7 @@ module Extension
37
37
  end
38
38
 
39
39
  def self.help
40
- ShopifyCli::Context.message("check.help", ShopifyCli::TOOL_NAME)
40
+ ShopifyCLI::Context.message("check.help", ShopifyCLI::TOOL_NAME)
41
41
  end
42
42
  end
43
43
  end
@@ -19,7 +19,7 @@ module Extension
19
19
  end
20
20
 
21
21
  def self.help
22
- ShopifyCli::Context.new.message("connect.help", ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
22
+ ShopifyCLI::Context.new.message("connect.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
23
23
  end
24
24
 
25
25
  private
@@ -2,7 +2,11 @@
2
2
 
3
3
  module Extension
4
4
  class Command
5
- class Create < ShopifyCli::SubCommand
5
+ class Create < ShopifyCLI::SubCommand
6
+ DEVELOPMENT_SERVER_SUPPORTED_TYPES = [
7
+ "checkout_ui_extension",
8
+ ]
9
+
6
10
  prerequisite_task :ensure_authenticated
7
11
 
8
12
  options do |parser, flags|
@@ -18,25 +22,15 @@ module Extension
18
22
  @ctx.abort(message_for_extension["create.errors.directory_exists", form.directory_name])
19
23
  end
20
24
 
21
- if form.type.create(form.directory_name, @ctx, getting_started: options.flags[:getting_started])
22
- ExtensionProject.write_cli_file(context: @ctx, type: form.type.identifier)
23
- ExtensionProject.write_env_file(
24
- context: @ctx,
25
- title: form.name,
26
- api_key: form.app.api_key,
27
- api_secret: form.app.secret
28
- )
29
-
30
- @ctx.puts(message_for_extension["create.ready_to_start", form.directory_name, form.name])
31
- @ctx.puts(message_for_extension["create.learn_more", form.type.name])
32
- else
33
- @ctx.puts(message_for_extension["create.try_again"])
34
- end
25
+ ShopifyCLI::Result.success(supports_development_server?(form.type.identifier))
26
+ .then { |supported| create_extension(supported, form) }
27
+ .then { notify_success(form, message_for_extension) }
28
+ .unwrap { |err| @ctx.puts(message_for_extension["create.try_again"]) unless err.nil? }
35
29
  end
36
30
  end
37
31
 
38
32
  def self.help
39
- @ctx.message("create.help", ShopifyCli::TOOL_NAME)
33
+ @ctx.message("create.help", ShopifyCLI::TOOL_NAME)
40
34
  end
41
35
 
42
36
  private
@@ -47,6 +41,55 @@ module Extension
47
41
 
48
42
  yield form, form.type.method(:message_for_extension)
49
43
  end
44
+
45
+ def supports_development_server?(type)
46
+ Models::DevelopmentServerRequirements.supported?(type)
47
+ end
48
+
49
+ def create_extension(supported, form)
50
+ if supported
51
+ use_new_create_flow(form)
52
+ else
53
+ use_legacy_flow(form)
54
+ end
55
+ ShopifyCLI::Result.success(nil)
56
+ end
57
+
58
+ def use_new_create_flow(form)
59
+ Tasks::RunExtensionCommand.new(
60
+ root_dir: form.directory_name,
61
+ template: form.template,
62
+ type: form.type.identifier.downcase,
63
+ command: "create"
64
+ ).call
65
+ @ctx.chdir(form.directory_name)
66
+ write_env_file(form)
67
+ rescue => error
68
+ raise error
69
+ end
70
+
71
+ def use_legacy_flow(form)
72
+ if form.type.create(form.directory_name, @ctx, getting_started: options.flags[:getting_started])
73
+ write_env_file(form)
74
+ else
75
+ raise StandardError
76
+ end
77
+ end
78
+
79
+ def write_env_file(form)
80
+ ExtensionProject.write_cli_file(context: @ctx, type: form.type.identifier)
81
+ ExtensionProject.write_env_file(
82
+ context: @ctx,
83
+ title: form.name,
84
+ api_key: form.app.api_key,
85
+ api_secret: form.app.secret
86
+ )
87
+ end
88
+
89
+ def notify_success(form, msg)
90
+ @ctx.puts(msg["create.ready_to_start", form.directory_name, form.name])
91
+ @ctx.puts(msg["create.learn_more", form.type.name])
92
+ end
50
93
  end
51
94
  end
52
95
  end
@@ -3,7 +3,7 @@ require "shopify_cli"
3
3
 
4
4
  module Extension
5
5
  class Command
6
- class ExtensionCommand < ShopifyCli::SubCommand
6
+ class ExtensionCommand < ShopifyCLI::SubCommand
7
7
  def project
8
8
  @project ||= ExtensionProject.current
9
9
  end
@@ -14,7 +14,7 @@ module Extension
14
14
  end
15
15
 
16
16
  def self.help
17
- ShopifyCli::Context.new.message("info.help", ShopifyCli::TOOL_NAME)
17
+ ShopifyCLI::Context.new.message("info.help", ShopifyCLI::TOOL_NAME)
18
18
  end
19
19
 
20
20
  private
@@ -18,7 +18,7 @@ module Extension
18
18
  end
19
19
 
20
20
  def self.help
21
- ShopifyCli::Context.new.message("push.help", ShopifyCli::TOOL_NAME)
21
+ ShopifyCLI::Context.new.message("push.help", ShopifyCLI::TOOL_NAME)
22
22
  end
23
23
 
24
24
  private
@@ -20,7 +20,7 @@ module Extension
20
20
  end
21
21
 
22
22
  def self.help
23
- ShopifyCli::Context.new.message("register.help", ShopifyCli::TOOL_NAME)
23
+ ShopifyCLI::Context.new.message("register.help", ShopifyCLI::TOOL_NAME)
24
24
  end
25
25
 
26
26
  private
@@ -60,7 +60,7 @@ module Extension
60
60
 
61
61
  def abort_not_registered
62
62
  @ctx.puts(@ctx.message("register.confirm_abort"))
63
- raise ShopifyCli::AbortSilent
63
+ raise ShopifyCLI::AbortSilent
64
64
  end
65
65
  end
66
66
  end
@@ -29,7 +29,7 @@ module Extension
29
29
  resource_url: options.flags[:resource_url]
30
30
  )
31
31
 
32
- ShopifyCli::Result
32
+ ShopifyCLI::Result
33
33
  .success(config)
34
34
  .then(&method(:find_available_port))
35
35
  .then(&method(:start_tunnel_if_required))
@@ -38,7 +38,7 @@ module Extension
38
38
  end
39
39
 
40
40
  def self.help
41
- ShopifyCli::Context.new.message("serve.help", ShopifyCli::TOOL_NAME)
41
+ ShopifyCLI::Context.new.message("serve.help", ShopifyCLI::TOOL_NAME)
42
42
  end
43
43
 
44
44
  private
@@ -66,12 +66,12 @@ module Extension
66
66
  end
67
67
 
68
68
  def can_start_tunnel?(runtime_configuration)
69
- return true if ShopifyCli::Tunnel.urls.empty?
70
- ShopifyCli::Tunnel.running_on?(runtime_configuration.port)
69
+ return true if ShopifyCLI::Tunnel.urls.empty?
70
+ ShopifyCLI::Tunnel.running_on?(runtime_configuration.port)
71
71
  end
72
72
 
73
73
  def start_tunnel(runtime_configuration)
74
- tunnel_url = ShopifyCli::Tunnel.start(@ctx, port: runtime_configuration.port)
74
+ tunnel_url = ShopifyCLI::Tunnel.start(@ctx, port: runtime_configuration.port)
75
75
  runtime_configuration.tap { |c| c.tunnel_url = tunnel_url }
76
76
  end
77
77
 
@@ -21,25 +21,25 @@ module Extension
21
21
 
22
22
  case subcommand
23
23
  when AUTH_SUBCOMMAND then authorize(args)
24
- when START_SUBCOMMAND then ShopifyCli::Tunnel.start(@ctx, port: port)
25
- when STOP_SUBCOMMAND then ShopifyCli::Tunnel.stop(@ctx)
24
+ when START_SUBCOMMAND then ShopifyCLI::Tunnel.start(@ctx, port: port)
25
+ when STOP_SUBCOMMAND then ShopifyCLI::Tunnel.stop(@ctx)
26
26
  when STATUS_SUBCOMMAND then status
27
27
  else @ctx.puts(self.class.help)
28
28
  end
29
29
  end
30
30
 
31
31
  def self.help
32
- ShopifyCli::Context.message("tunnel.help", ShopifyCli::TOOL_NAME)
32
+ ShopifyCLI::Context.message("tunnel.help", ShopifyCLI::TOOL_NAME)
33
33
  end
34
34
 
35
35
  def self.extended_help
36
- ShopifyCli::Context.message("tunnel.extended_help", ShopifyCli::TOOL_NAME, DEFAULT_PORT)
36
+ ShopifyCLI::Context.message("tunnel.extended_help", ShopifyCLI::TOOL_NAME, DEFAULT_PORT)
37
37
  end
38
38
 
39
39
  private
40
40
 
41
41
  def status
42
- tunnel_urls = ShopifyCli::Tunnel.urls
42
+ tunnel_urls = ShopifyCLI::Tunnel.urls
43
43
  tunnel_url = tunnel_urls.find { |url| url.start_with?("https://") }
44
44
  tunnel_url = tunnel_urls.first if tunnel_url.nil?
45
45
 
@@ -65,7 +65,7 @@ module Extension
65
65
  @ctx.puts(@ctx.message("tunnel.missing_token"))
66
66
  @ctx.puts("#{self.class.help}\n#{self.class.extended_help}")
67
67
  else
68
- ShopifyCli::Tunnel.auth(@ctx, token)
68
+ ShopifyCLI::Tunnel.auth(@ctx, token)
69
69
  end
70
70
  end
71
71
  end
@@ -3,10 +3,10 @@ require "shopify_cli"
3
3
  require "securerandom"
4
4
 
5
5
  module Extension
6
- class ExtensionProject < ShopifyCli::Project
6
+ class ExtensionProject < ShopifyCLI::Project
7
7
  class << self
8
8
  def write_cli_file(context:, type:)
9
- ShopifyCli::Project.write(
9
+ ShopifyCLI::Project.write(
10
10
  context,
11
11
  project_type: :extension,
12
12
  organization_id: nil,
@@ -42,7 +42,7 @@ module Extension
42
42
  resource_url: nil,
43
43
  shop: nil
44
44
  )
45
- ShopifyCli::Resources::EnvFile.new(
45
+ ShopifyCLI::Resources::EnvFile.new(
46
46
  api_key: api_key,
47
47
  secret: api_secret,
48
48
  shop: shop,
@@ -134,7 +134,7 @@ module Extension
134
134
 
135
135
  def validate_env_present
136
136
  return if env
137
- raise ShopifyCli::Abort, "Missing .env file. Run `shopify extension connect` to generate an .env file."
137
+ raise ShopifyCLI::Abort, "Missing .env file. Run `shopify extension connect` to generate an .env file."
138
138
  end
139
139
 
140
140
  def integer?(value)
@@ -24,7 +24,7 @@ module Extension
24
24
  end
25
25
 
26
26
  def config(context)
27
- js_system = ShopifyCli::JsSystem.new(ctx: context)
27
+ js_system = ShopifyCLI::JsSystem.new(ctx: context)
28
28
  if js_system.package_manager == "yarn"
29
29
  run_yarn_install(context, js_system)
30
30
  run_yarn_run_script(context, js_system)
@@ -42,9 +42,9 @@ module Extension
42
42
  end
43
43
 
44
44
  def renderer_package(context)
45
- js_system = ShopifyCli::JsSystem.new(ctx: context)
45
+ js_system = ShopifyCLI::JsSystem.new(ctx: context)
46
46
  Tasks::FindNpmPackages
47
- .exactly_one_of(renderer_package_name, js_system: js_system)
47
+ .exactly_one_of(renderer_package_name, js_system: js_system, production_only: true)
48
48
  .unwrap { |err| raise err }
49
49
  rescue Extension::PackageResolutionFailed
50
50
  context.abort(
@@ -21,7 +21,7 @@ module Extension
21
21
  return {} if config.nil?
22
22
 
23
23
  unless config.is_a?(Hash)
24
- raise ShopifyCli::Abort, ShopifyCli::Context.message("core.yaml.error.not_hash", CONFIG_FILE_NAME)
24
+ raise ShopifyCLI::Abort, ShopifyCLI::Context.message("core.yaml.error.not_hash", CONFIG_FILE_NAME)
25
25
  end
26
26
 
27
27
  config.transform_keys!(&:to_sym)
@@ -30,8 +30,8 @@ module Extension
30
30
  config
31
31
  rescue Psych::SyntaxError => e
32
32
  raise(
33
- ShopifyCli::Abort,
34
- ShopifyCli::Context.message("core.yaml.error.invalid", CONFIG_FILE_NAME, e.message)
33
+ ShopifyCLI::Abort,
34
+ ShopifyCLI::Context.message("core.yaml.error.invalid", CONFIG_FILE_NAME, e.message)
35
35
  )
36
36
  end
37
37
  end
@@ -45,8 +45,8 @@ module Extension
45
45
 
46
46
  unless unpermitted_keys.empty?
47
47
  raise(
48
- ShopifyCli::Abort,
49
- ShopifyCli::Context.message(
48
+ ShopifyCLI::Abort,
49
+ ShopifyCLI::Context.message(
50
50
  "features.argo.config.unpermitted_keys",
51
51
  CONFIG_FILE_NAME,
52
52
  unpermitted_keys.map { |k| "\n- #{k}" }.join