shopify-cli 2.6.6 → 2.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer.json +5 -0
  3. data/.github/CODEOWNERS +2 -2
  4. data/.github/DESIGN.md +1 -1
  5. data/.github/ISSUE_TEMPLATE.md +7 -0
  6. data/.github/workflows/shopify.yml +1 -1
  7. data/.gitignore +1 -0
  8. data/.ruby-version +1 -1
  9. data/.vscode/extensions.json +5 -0
  10. data/.vscode/settings.json +9 -0
  11. data/CHANGELOG.md +44 -4
  12. data/CONTRIBUTING.md +1 -29
  13. data/{Dockerfile → Codespace.dockerfile} +2 -2
  14. data/Gemfile.lock +5 -5
  15. data/README.md +20 -99
  16. data/Rakefile +27 -0
  17. data/Tests.dockerfile +35 -0
  18. data/assets/logo.png +0 -0
  19. data/dev.yml +1 -4
  20. data/docs/README.md +13 -0
  21. data/docs/contributors/testing.md +27 -0
  22. data/docs/users/installation.md +46 -0
  23. data/{THEMEKIT_MIGRATION.md → docs/users/migrate-from-themekit.md} +1 -1
  24. data/ext/javy/hashes/javy-arm-macos-v0.1.0.gz.sha256 +1 -0
  25. data/ext/javy/hashes/javy-x86_64-linux-v0.1.0.gz.sha256 +1 -0
  26. data/ext/javy/hashes/javy-x86_64-macos-v0.1.0.gz.sha256 +1 -0
  27. data/ext/javy/hashes/javy-x86_64-windows-v0.1.0.gz.sha256 +1 -0
  28. data/ext/javy/javy.rb +205 -0
  29. data/ext/javy/version +1 -0
  30. data/lib/project_types/extension/cli.rb +6 -3
  31. data/lib/project_types/extension/commands/build.rb +4 -8
  32. data/lib/project_types/extension/commands/create.rb +2 -5
  33. data/lib/project_types/extension/commands/extension_command.rb +1 -1
  34. data/lib/project_types/extension/features/argo_serve.rb +9 -23
  35. data/lib/project_types/extension/forms/questions/ask_template.rb +1 -5
  36. data/lib/project_types/extension/messages/messages.rb +0 -2
  37. data/lib/project_types/extension/models/development_server.rb +2 -2
  38. data/lib/project_types/extension/models/development_server_requirements.rb +2 -3
  39. data/lib/project_types/extension/models/server_config/app.rb +13 -0
  40. data/lib/project_types/extension/models/server_config/development.rb +5 -4
  41. data/lib/project_types/extension/models/server_config/development_renderer.rb +1 -1
  42. data/lib/project_types/extension/models/server_config/development_resource.rb +13 -0
  43. data/lib/project_types/extension/models/server_config/extension.rb +3 -1
  44. data/lib/project_types/extension/models/server_config/root.rb +4 -1
  45. data/lib/project_types/extension/tasks/convert_server_config.rb +65 -0
  46. data/lib/project_types/extension/tasks/ensure_resource_url.rb +39 -0
  47. data/lib/project_types/extension/tasks/merge_server_config.rb +32 -0
  48. data/lib/project_types/extension/tasks/run_extension_command.rb +11 -10
  49. data/lib/project_types/node/cli.rb +0 -16
  50. data/lib/project_types/node/forms/create.rb +5 -5
  51. data/lib/project_types/node/messages/messages.rb +2 -144
  52. data/lib/project_types/php/cli.rb +0 -11
  53. data/lib/project_types/php/forms/create.rb +5 -6
  54. data/lib/project_types/php/messages/messages.rb +2 -161
  55. data/lib/project_types/rails/cli.rb +0 -16
  56. data/lib/project_types/rails/commands/create.rb +3 -5
  57. data/lib/project_types/rails/forms/create.rb +5 -6
  58. data/lib/project_types/rails/messages/messages.rb +6 -151
  59. data/lib/project_types/script/cli.rb +8 -2
  60. data/lib/project_types/script/commands/create.rb +2 -4
  61. data/lib/project_types/script/commands/javy.rb +29 -0
  62. data/lib/project_types/script/commands/push.rb +3 -2
  63. data/lib/project_types/script/config/extension_points.yml +12 -30
  64. data/lib/project_types/script/forms/ask_app.rb +32 -0
  65. data/lib/project_types/script/forms/ask_org.rb +30 -0
  66. data/lib/project_types/script/forms/ask_script_uuid.rb +22 -0
  67. data/lib/project_types/script/forms/run_against_shopify_org.rb +14 -0
  68. data/lib/project_types/script/graphql/app_script_set.graphql +2 -2
  69. data/lib/project_types/script/layers/application/build_script.rb +0 -1
  70. data/lib/project_types/script/layers/application/connect_app.rb +73 -0
  71. data/lib/project_types/script/layers/application/create_script.rb +1 -1
  72. data/lib/project_types/script/layers/application/push_script.rb +1 -1
  73. data/lib/project_types/script/layers/domain/errors.rb +1 -4
  74. data/lib/project_types/script/layers/domain/push_package.rb +3 -3
  75. data/lib/project_types/script/layers/domain/{script_json.rb → script_config.rb} +2 -2
  76. data/lib/project_types/script/layers/domain/script_project.rb +5 -1
  77. data/lib/project_types/script/layers/infrastructure/errors.rb +36 -7
  78. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -4
  79. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -4
  80. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +2 -2
  81. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +104 -27
  82. data/lib/project_types/script/layers/infrastructure/script_service.rb +11 -11
  83. data/lib/project_types/script/messages/messages.rb +21 -4
  84. data/lib/project_types/script/ui/error_handler.rb +31 -21
  85. data/lib/project_types/theme/cli.rb +1 -1
  86. data/lib/project_types/theme/commands/check.rb +1 -1
  87. data/lib/project_types/theme/commands/delete.rb +1 -1
  88. data/lib/project_types/theme/commands/init.rb +1 -1
  89. data/lib/project_types/theme/commands/language_server.rb +1 -1
  90. data/lib/project_types/theme/commands/package.rb +1 -1
  91. data/lib/project_types/theme/commands/publish.rb +1 -1
  92. data/lib/project_types/theme/commands/pull.rb +4 -1
  93. data/lib/project_types/theme/commands/push.rb +5 -1
  94. data/lib/project_types/theme/commands/serve.rb +9 -3
  95. data/lib/project_types/theme/messages/messages.rb +39 -2
  96. data/lib/project_types/theme/ui/sync_progress_bar.rb +2 -2
  97. data/lib/shopify_cli/admin_api/populate_resource_command.rb +1 -1
  98. data/lib/shopify_cli/api.rb +7 -2
  99. data/lib/shopify_cli/app_type_detector.rb +24 -20
  100. data/lib/shopify_cli/command/app_sub_command.rb +10 -0
  101. data/lib/shopify_cli/command/project_command.rb +31 -0
  102. data/lib/shopify_cli/command/sub_command.rb +19 -0
  103. data/lib/shopify_cli/command.rb +7 -2
  104. data/lib/shopify_cli/commands/app/connect.rb +22 -0
  105. data/lib/shopify_cli/commands/app/create/node.rb +36 -0
  106. data/lib/shopify_cli/commands/app/create/php.rb +36 -0
  107. data/lib/shopify_cli/commands/app/create/rails.rb +38 -0
  108. data/lib/shopify_cli/commands/app/create.rb +28 -0
  109. data/lib/shopify_cli/commands/app/deploy.rb +49 -0
  110. data/lib/shopify_cli/commands/app/open.rb +19 -0
  111. data/lib/shopify_cli/commands/app/serve.rb +49 -0
  112. data/lib/shopify_cli/commands/app/tunnel.rb +43 -0
  113. data/lib/shopify_cli/commands/app.rb +29 -0
  114. data/lib/shopify_cli/commands/config.rb +2 -2
  115. data/lib/shopify_cli/commands.rb +1 -0
  116. data/lib/shopify_cli/constants.rb +7 -0
  117. data/lib/shopify_cli/context.rb +10 -0
  118. data/lib/shopify_cli/environment.rb +4 -0
  119. data/lib/shopify_cli/exception_reporter.rb +3 -4
  120. data/lib/shopify_cli/git.rb +14 -1
  121. data/lib/shopify_cli/github/issue_url_generator.rb +19 -0
  122. data/lib/shopify_cli/github.rb +5 -0
  123. data/lib/shopify_cli/identity_auth.rb +18 -0
  124. data/lib/shopify_cli/messages/messages.rb +254 -9
  125. data/lib/shopify_cli/partners_api.rb +1 -8
  126. data/lib/shopify_cli/project.rb +5 -1
  127. data/lib/shopify_cli/project_commands.rb +1 -1
  128. data/lib/shopify_cli/services/app/connect_service.rb +25 -0
  129. data/lib/shopify_cli/services/app/create/node_service.rb +155 -0
  130. data/lib/shopify_cli/services/app/create/php_service.rb +152 -0
  131. data/lib/shopify_cli/services/app/create/rails_service.rb +215 -0
  132. data/lib/shopify_cli/services/app/deploy/heroku/node_service.rb +101 -0
  133. data/lib/shopify_cli/services/app/deploy/heroku/php_service.rb +135 -0
  134. data/lib/shopify_cli/services/app/deploy/heroku/rails_service.rb +120 -0
  135. data/lib/shopify_cli/services/app/open_service.rb +19 -0
  136. data/lib/shopify_cli/services/app/serve/node_service.rb +42 -0
  137. data/lib/shopify_cli/services/app/serve/php_service.rb +46 -0
  138. data/lib/shopify_cli/services/app/serve/rails_service.rb +48 -0
  139. data/lib/shopify_cli/services/app/tunnel/auth_service.rb +21 -0
  140. data/lib/shopify_cli/services/app/tunnel/start_service.rb +20 -0
  141. data/lib/shopify_cli/services/app/tunnel/stop_service.rb +20 -0
  142. data/lib/shopify_cli/services.rb +31 -0
  143. data/lib/shopify_cli/tasks/ensure_authenticated.rb +9 -3
  144. data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +73 -0
  145. data/lib/shopify_cli/theme/dev_server/hot-reload.js +25 -9
  146. data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
  147. data/lib/shopify_cli/theme/dev_server.rb +37 -18
  148. data/lib/shopify_cli/theme/syncer/error_reporter.rb +45 -0
  149. data/lib/shopify_cli/theme/syncer/operation.rb +56 -0
  150. data/lib/shopify_cli/theme/syncer/standard_reporter.rb +32 -0
  151. data/lib/shopify_cli/theme/syncer.rb +40 -39
  152. data/lib/shopify_cli/theme/theme.rb +31 -19
  153. data/lib/shopify_cli/tunnel.rb +26 -22
  154. data/lib/shopify_cli/version.rb +1 -1
  155. data/lib/shopify_cli.rb +1 -2
  156. data/shopify-cli.gemspec +1 -1
  157. data/shopify-dev +18 -0
  158. data/utilities/constants.rb +7 -0
  159. data/utilities/docker/container.rb +10 -3
  160. data/utilities/docker.rb +2 -2
  161. data/utilities/utilities.rb +1 -0
  162. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +1 -1
  163. metadata +66 -50
  164. data/docs/_config.yml +0 -2
  165. data/docs/app/node/commands/index.md +0 -4
  166. data/docs/app/node/index.md +0 -4
  167. data/docs/app/rails/commands/index.md +0 -4
  168. data/docs/app/rails/index.md +0 -4
  169. data/docs/core/index.md +0 -4
  170. data/docs/getting-started/index.md +0 -4
  171. data/docs/getting-started/install/index.md +0 -4
  172. data/docs/getting-started/migrate/index.md +0 -4
  173. data/docs/getting-started/uninstall/index.md +0 -4
  174. data/docs/getting-started/upgrade/index.md +0 -4
  175. data/docs/help/start-app/index.md +0 -4
  176. data/docs/index.md +0 -4
  177. data/install.sh +0 -7
  178. data/lib/project_types/extension/tasks/converters/server_config_converter.rb +0 -30
  179. data/lib/project_types/extension/tasks/load_server_config.rb +0 -28
  180. data/lib/project_types/node/commands/connect.rb +0 -21
  181. data/lib/project_types/node/commands/create.rb +0 -125
  182. data/lib/project_types/node/commands/deploy/heroku.rb +0 -96
  183. data/lib/project_types/node/commands/deploy.rb +0 -32
  184. data/lib/project_types/node/commands/generate.rb +0 -22
  185. data/lib/project_types/node/commands/open.rb +0 -18
  186. data/lib/project_types/node/commands/serve.rb +0 -45
  187. data/lib/project_types/node/commands/tunnel.rb +0 -41
  188. data/lib/project_types/php/commands/connect.rb +0 -19
  189. data/lib/project_types/php/commands/create.rb +0 -143
  190. data/lib/project_types/php/commands/deploy/heroku.rb +0 -129
  191. data/lib/project_types/php/commands/deploy.rb +0 -32
  192. data/lib/project_types/php/commands/open.rb +0 -16
  193. data/lib/project_types/php/commands/serve.rb +0 -48
  194. data/lib/project_types/php/commands/tunnel.rb +0 -37
  195. data/lib/project_types/rails/commands/connect.rb +0 -21
  196. data/lib/project_types/rails/commands/deploy/heroku.rb +0 -115
  197. data/lib/project_types/rails/commands/deploy.rb +0 -32
  198. data/lib/project_types/rails/commands/generate/webhook.rb +0 -42
  199. data/lib/project_types/rails/commands/generate.rb +0 -60
  200. data/lib/project_types/rails/commands/open.rb +0 -18
  201. data/lib/project_types/rails/commands/serve.rb +0 -51
  202. data/lib/project_types/rails/commands/tunnel.rb +0 -41
  203. data/lib/project_types/script/tasks/ensure_env.rb +0 -106
  204. data/lib/shopify_cli/sub_command.rb +0 -17
  205. data/shopify.fish +0 -12
  206. data/shopify.sh +0 -11
@@ -3,18 +3,24 @@ require "shopify_cli/theme/dev_server"
3
3
 
4
4
  module Theme
5
5
  class Command
6
- class Serve < ShopifyCLI::SubCommand
6
+ class Serve < ShopifyCLI::Command::SubCommand
7
+ DEFAULT_HTTP_HOST = "127.0.0.1"
8
+
7
9
  options do |parser, flags|
8
- parser.on("--bind=HOST") { |bind| flags[:bind] = bind.to_s }
10
+ parser.on("--host=HOST") { |host| flags[:host] = host.to_s }
9
11
  parser.on("--port=PORT") { |port| flags[:port] = port.to_i }
10
12
  parser.on("--poll") { flags[:poll] = true }
11
13
  end
12
14
 
13
15
  def call(*)
14
16
  flags = options.flags.dup
15
- ShopifyCLI::Theme::DevServer.start(@ctx, ".", **flags) do |syncer|
17
+ host = flags[:host] || DEFAULT_HTTP_HOST
18
+ ShopifyCLI::Theme::DevServer.start(@ctx, ".", host: host, **flags) do |syncer|
16
19
  UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delay_low_priority_files: true)
17
20
  end
21
+ rescue ShopifyCLI::Theme::DevServer::AddressBindingError
22
+ raise ShopifyCLI::Abort,
23
+ ShopifyCLI::Context.message("theme.serve.error.address_binding_error", ShopifyCLI::TOOL_NAME)
18
24
  end
19
25
 
20
26
  def self.help
@@ -58,6 +58,7 @@ module Theme
58
58
 
59
59
  Options:
60
60
  {{command:-i, --themeid=THEMEID}} Theme ID. Must be an existing theme on your store.
61
+ {{command:-l, --live}} Push to your remote live theme, and update your live store.
61
62
  {{command:-d, --development}} Push to your remote development theme, and create it if needed.
62
63
  {{command:-u, --unpublished}} Create a new unpublished theme and push to it.
63
64
  {{command:-n, --nodelete}} Runs the push command without deleting remote files from Shopify.
@@ -94,10 +95,45 @@ module Theme
94
95
  Options:
95
96
  {{command:--port=PORT}} Local port to serve theme preview from
96
97
  {{command:--poll}} Force polling to detect file changes
97
- {{command:--bind=HOST}} Set which network interface the web server listens on
98
+ {{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
98
99
  HELP
99
- serve: "Viewing theme…",
100
+ viewing_theme: "Viewing theme…",
101
+ syncing_theme: "Syncing theme #%s on %s",
100
102
  open_fail: "Couldn't open the theme",
103
+ operation: {
104
+ status: {
105
+ error: "ERROR",
106
+ synced: "Synced",
107
+ fixed: "Fixed",
108
+ },
109
+ },
110
+ error: {
111
+ address_binding_error: "Couldn't bind to localhost."\
112
+ " To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
113
+ },
114
+ serving: <<~SERVING,
115
+
116
+ Serving %s
117
+
118
+ SERVING
119
+ customize_or_preview: <<~CUSTOMIZE_OR_PREVIEW,
120
+
121
+ Customize this theme in the Online Store Editor:
122
+ {{green:%s}}
123
+
124
+ Share this theme preview:
125
+ {{green:%s}}
126
+
127
+ (Use Ctrl-C to stop)
128
+ CUSTOMIZE_OR_PREVIEW
129
+ ensure_user: <<~ENSURE_USER,
130
+ You are not authorized to edit themes on %s.
131
+ Make sure you are a user of that store, and allowed to edit themes.
132
+ ENSURE_USER
133
+ already_in_use_error: "Error",
134
+ address_already_in_use: "The address \"%s\" is already in use.",
135
+ try_this: "Try this",
136
+ try_port_option: "Use the --port=PORT option to serve the theme in a different port.",
101
137
  },
102
138
  check: {
103
139
  help: <<~HELP,
@@ -153,6 +189,7 @@ module Theme
153
189
 
154
190
  Options:
155
191
  {{command:-i, --themeid=THEMEID}} The Theme ID. Must be an existing theme on your store.
192
+ {{command:-l, --live}} Pull theme files from your remote live theme.
156
193
  {{command:-n, --nodelete}} Runs the pull command without deleting local files.
157
194
 
158
195
  Run without options to select theme from a list.
@@ -6,14 +6,14 @@ module Theme
6
6
  end
7
7
 
8
8
  def progress(method, **args)
9
- @syncer.delay_errors!
9
+ @syncer.lock_io!
10
10
  CLI::UI::Progress.progress do |bar|
11
11
  @syncer.public_send(method, **args) do |left, total|
12
12
  bar.tick(set_percent: 1 - left.to_f / total)
13
13
  end
14
14
  bar.tick(set_percent: 1)
15
15
  end
16
- @syncer.report_errors!
16
+ @syncer.unlock_io!
17
17
  end
18
18
  end
19
19
  end
@@ -3,7 +3,7 @@ require "optparse"
3
3
 
4
4
  module ShopifyCLI
5
5
  class AdminAPI
6
- class PopulateResourceCommand < ShopifyCLI::SubCommand
6
+ class PopulateResourceCommand < ShopifyCLI::Command::SubCommand
7
7
  DEFAULT_COUNT = 5
8
8
 
9
9
  attr_reader :input
@@ -108,9 +108,14 @@ module ShopifyCLI
108
108
  private
109
109
 
110
110
  def default_headers
111
+ sha = ShopifyCLI.sha
112
+ user_agent = "Shopify CLI; v=#{ShopifyCLI::VERSION}"
113
+ sec_ch_ua = user_agent
114
+ sec_ch_ua += " sha=#{sha}" unless sha.nil?
115
+
111
116
  {
112
- "User-Agent" => "Shopify CLI; v=#{ShopifyCLI::VERSION}",
113
- "Sec-CH-UA" => "Shopify CLI; v=#{ShopifyCLI::VERSION} sha=#{ShopifyCLI.sha}",
117
+ "User-Agent" => user_agent,
118
+ "Sec-CH-UA" => sec_ch_ua,
114
119
  "Sec-CH-UA-PLATFORM" => ctx.os.to_s,
115
120
  "X-Request-Id" => SecureRandom.uuid,
116
121
  }.tap do |headers|
@@ -3,30 +3,34 @@ require "json"
3
3
  module ShopifyCLI
4
4
  class AppTypeDetector
5
5
  Error = Class.new(StandardError)
6
+ MissingShopifyCLIYamlError = Class.new(Error)
6
7
  TypeNotFoundError = Class.new(Error)
7
-
8
- def self.detect(project_directory:)
9
- return :node if node?(project_directory: project_directory)
10
- return :rails if rails?(project_directory: project_directory)
11
- return :php if php?(project_directory: project_directory)
12
- raise TypeNotFoundError, "Couldn't detect the project type in directory: #{project_directory}"
13
- end
14
-
15
- def self.node?(project_directory:)
16
- package_json_path = File.join(project_directory, "package.json")
17
- return false unless File.exist?(package_json_path)
18
- package_json = JSON.parse(File.read(package_json_path))
19
- !package_json.dig("scripts", "dev").nil?
8
+ class InvalidTypeError < Error
9
+ attr_reader :project_type
10
+ def initialize(message, project_type:)
11
+ @project_type = project_type
12
+ super(message)
13
+ end
20
14
  end
21
15
 
22
- def self.rails?(project_directory:)
23
- rails_binstub_path = File.join(project_directory, "bin/rails")
24
- File.exist?(rails_binstub_path)
25
- end
16
+ def self.detect(project_directory:)
17
+ require "yaml" # takes 20ms, so deferred as late as possible.
26
18
 
27
- def self.php?(project_directory:)
28
- bootstrap_app_path = File.join(project_directory, "bootstrap/app.php")
29
- File.exist?(bootstrap_app_path)
19
+ shopify_cli_yml_path = File.join(project_directory, Constants::Files::SHOPIFY_CLI_YML)
20
+ unless File.exist?(shopify_cli_yml_path)
21
+ raise MissingShopifyCLIYamlError,
22
+ "#{Constants::Files::SHOPIFY_CLI_YML} was not found in directory #{project_directory}"
23
+ end
24
+ shopify_cli = YAML.load_file(shopify_cli_yml_path)
25
+ case shopify_cli["project_type"]&.to_sym
26
+ when :node, :rails, :php
27
+ shopify_cli["project_type"].to_sym
28
+ when nil
29
+ raise TypeNotFoundError, "Couldn't detect the project type in directory: #{project_directory}"
30
+ else
31
+ raise InvalidTypeError.new("The project found '' is not supported",
32
+ project_type: shopify_cli["project_type"])
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -1,6 +1,16 @@
1
1
  module ShopifyCLI
2
2
  class Command
3
3
  class AppSubCommand < SubCommand
4
+ def detect_app(directory: Dir.pwd)
5
+ AppTypeDetector.detect(project_directory: directory)
6
+ rescue ShopifyCLI::AppTypeDetector::TypeNotFoundError
7
+ raise ShopifyCLI::Abort, @ctx.message("core.app.error.type_not_found", directory)
8
+ rescue ShopifyCLI::AppTypeDetector::MissingShopifyCLIYamlError
9
+ raise ShopifyCLI::Abort, @ctx.message("core.app.error.missing_shopify_cli_yml", directory)
10
+ rescue ShopifyCLI::AppTypeDetector::InvalidTypeError => error
11
+ raise ShopifyCLI::Abort, @ctx.message("core.app.error.invalid_project_type", error.project_type)
12
+ end
13
+
4
14
  class << self
5
15
  def call_help(*)
6
16
  output = help
@@ -0,0 +1,31 @@
1
+ module ShopifyCLI
2
+ class Command
3
+ class ProjectCommand < Command
4
+ def call(*)
5
+ @ctx.puts(self.class.help)
6
+ end
7
+
8
+ class << self
9
+ def help
10
+ project_type = name.split("::")[0].downcase
11
+ ShopifyCLI::Context.message(
12
+ "#{project_type}.help",
13
+ ShopifyCLI::TOOL_NAME,
14
+ available_subcommands
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def available_subcommands
21
+ subcommand_registry
22
+ .resolved_commands
23
+ .reject { |_name, command| command.hidden? }
24
+ .keys
25
+ .sort
26
+ .join(" | ")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require "shopify_cli"
3
+
4
+ module ShopifyCLI
5
+ class Command
6
+ class SubCommand < Command
7
+ class << self
8
+ def call(args, command_name, parent_command)
9
+ cmd = new(@ctx)
10
+ args = cmd.options.parse(@_options, args || [])
11
+ return call_help(parent_command, command_name) if cmd.options.help
12
+ run_prerequisites
13
+
14
+ cmd.call(args, command_name)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,6 +3,10 @@ require "shopify_cli"
3
3
 
4
4
  module ShopifyCLI
5
5
  class Command < CLI::Kit::BaseCommand
6
+ autoload :SubCommand, "shopify_cli/command/sub_command"
7
+ autoload :AppSubCommand, "shopify_cli/command/app_sub_command"
8
+ autoload :ProjectCommand, "shopify_cli/command/project_command"
9
+
6
10
  extend Feature::Set
7
11
 
8
12
  attr_writer :ctx
@@ -11,12 +15,13 @@ module ShopifyCLI
11
15
  class << self
12
16
  attr_writer :ctx, :task_registry
13
17
 
14
- def call(args, command_name)
18
+ def call(args, command_name, *)
15
19
  subcommand, resolved_name = subcommand_registry.lookup_command(args.first)
16
20
  if subcommand
17
21
  subcommand.ctx = @ctx
18
22
  subcommand.task_registry = @task_registry
19
- subcommand.call(args, resolved_name, command_name)
23
+
24
+ subcommand.call(args.drop(1), resolved_name, command_name)
20
25
  else
21
26
  cmd = new(@ctx)
22
27
  cmd.options.parse(@_options, args)
@@ -0,0 +1,22 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Connect < ShopifyCLI::Command::AppSubCommand
5
+ def call(_args, _command_name, *)
6
+ app_type = detect_app(directory: Dir.pwd)
7
+ project = ShopifyCLI::Project.current
8
+
9
+ Services::App::ConnectService.call(
10
+ app_type: app_type,
11
+ project: project,
12
+ context: @ctx
13
+ )
14
+ end
15
+
16
+ def self.help
17
+ ShopifyCLI::Context.message("core.app.connect.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Create
5
+ class Node < ShopifyCLI::Command::AppSubCommand
6
+ prerequisite_task :ensure_authenticated
7
+
8
+ options do |parser, flags|
9
+ parser.on("--name=NAME") { |t| flags[:name] = t }
10
+ parser.on("--organization-id=ID") { |id| flags[:organization_id] = id }
11
+ parser.on("--store-domain=MYSHOPIFYDOMAIN") { |url| flags[:store_domain] = url }
12
+ parser.on("--type=APPTYPE") { |type| flags[:type] = type }
13
+ parser.on("--verbose") { flags[:verbose] = true }
14
+ end
15
+
16
+ def call(*)
17
+ Services::App::Create::NodeService.call(
18
+ name: options.flags[:name],
19
+ organization_id: options.flags[:organization_id],
20
+ store_domain: options.flags[:store_domain],
21
+ type: options.flags[:type],
22
+ verbose: !options.flags[:verbose].nil?,
23
+ context: @ctx
24
+ )
25
+ end
26
+
27
+ class << self
28
+ def help
29
+ ShopifyCLI::Context.message("core.app.create.node.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Create
5
+ class PHP < ShopifyCLI::Command::AppSubCommand
6
+ prerequisite_task :ensure_authenticated
7
+
8
+ options do |parser, flags|
9
+ parser.on("--name=NAME") { |name| flags[:name] = name }
10
+ parser.on("--organization-id=ID") { |organization_id| flags[:organization_id] = organization_id }
11
+ parser.on("--store-domain=MYSHOPIFYDOMAIN") { |url| flags[:store_domain] = url }
12
+ parser.on("--type=APPTYPE") { |type| flags[:type] = type }
13
+ parser.on("--verbose") { flags[:verbose] = true }
14
+ end
15
+
16
+ def call(*)
17
+ Services::App::Create::PHPService.call(
18
+ name: options.flags[:name],
19
+ organization_id: options.flags[:organization_id],
20
+ store_domain: options.flags[:store_domain],
21
+ type: options.flags[:type],
22
+ verbose: !options.flags[:verbose].nil?,
23
+ context: @ctx
24
+ )
25
+ end
26
+
27
+ class << self
28
+ def help
29
+ ShopifyCLI::Context.message("core.app.create.php.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Create
5
+ class Rails < ShopifyCLI::Command::AppSubCommand
6
+ prerequisite_task :ensure_authenticated
7
+
8
+ options do |parser, flags|
9
+ parser.on("--name=NAME") { |t| flags[:name] = t }
10
+ parser.on("--organization-id=ID") { |id| flags[:organization_id] = id }
11
+ parser.on("--store-domain=MYSHOPIFYDOMAIN") { |url| flags[:store_domain] = url }
12
+ parser.on("--type=APPTYPE") { |type| flags[:type] = type }
13
+ parser.on("--db=DB") { |db| flags[:db] = db }
14
+ parser.on("--rails-opts=RAILSOPTS") { |opts| flags[:rails_opts] = opts }
15
+ end
16
+
17
+ def call(*)
18
+ Services::App::Create::RailsService.call(
19
+ name: options.flags[:name],
20
+ organization_id: options.flags[:organization_id],
21
+ store_domain: options.flags[:store_domain],
22
+ type: options.flags[:type],
23
+ db: options.flags[:db],
24
+ rails_opts: options.flags[:rails_opts],
25
+ context: @ctx
26
+ )
27
+ end
28
+
29
+ class << self
30
+ def help
31
+ ShopifyCLI::Context.message("core.app.create.rails.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Create < ShopifyCLI::Command
5
+ subcommand :Rails, "rails", "shopify_cli/commands/app/create/rails"
6
+ subcommand :PHP, "php", "shopify_cli/commands/app/create/php"
7
+ subcommand :Node, "node", "shopify_cli/commands/app/create/node"
8
+
9
+ def call(_args, _command_name)
10
+ @ctx.puts(self.class.help)
11
+ end
12
+
13
+ def self.help
14
+ ShopifyCLI::Context.message("core.app.create.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
15
+ end
16
+
17
+ def self.call_help(*)
18
+ output = help
19
+ if respond_to?(:extended_help)
20
+ output += "\n"
21
+ output += extended_help
22
+ end
23
+ @ctx.puts(output)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Deploy < ShopifyCLI::Command::AppSubCommand
5
+ subcommand :Heroku, "heroku", "shopify_cli/commands/app/deploy/heroku"
6
+
7
+ def call(args, _name)
8
+ platform = args.shift
9
+ case platform
10
+ when "heroku"
11
+ case detect_app
12
+ when :rails
13
+ Services::App::Deploy::Heroku::RailsService.call(
14
+ context: @ctx
15
+ )
16
+ when :php
17
+ Services::App::Deploy::Heroku::PHPService.call(
18
+ context: @ctx
19
+ )
20
+ when :node
21
+ Services::App::Deploy::Heroku::NodeService.call(
22
+ context: @ctx
23
+ )
24
+ end
25
+ when nil
26
+ raise ShopifyCLI::Abort, @ctx.message(
27
+ "core.app.deploy.error.missing_platform",
28
+ ShopifyCLI::TOOL_NAME
29
+ )
30
+ else
31
+ raise ShopifyCLI::Abort, @ctx.message(
32
+ "core.app.deploy.error.invalid_platform",
33
+ platform,
34
+ ShopifyCLI::TOOL_NAME
35
+ )
36
+ end
37
+ end
38
+
39
+ def self.help
40
+ ShopifyCLI::Context.message("core.app.deploy.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
41
+ end
42
+
43
+ def self.extended_help
44
+ ShopifyCLI::Context.message("core.app.deploy.extended_help", ShopifyCLI::TOOL_NAME)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,19 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Open < ShopifyCLI::Command::AppSubCommand
5
+ def call(*)
6
+ project = ShopifyCLI::Project.current
7
+ Services::App::OpenService.call(
8
+ project: project,
9
+ context: @ctx
10
+ )
11
+ end
12
+
13
+ def self.help
14
+ ShopifyCLI::Context.message("core.app.open.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,49 @@
1
+ module ShopifyCLI
2
+ module Commands
3
+ class App
4
+ class Serve < ShopifyCLI::Command::AppSubCommand
5
+ include ShopifyCLI::CommandOptions::CommandServeOptions
6
+
7
+ prerequisite_task :ensure_env, :ensure_dev_store
8
+
9
+ options do |parser, flags|
10
+ parser.on("--host=HOST") do |h|
11
+ flags[:host] = h.gsub('"', "")
12
+ end
13
+ parser.on("--port=PORT") { |port| flags[:port] = port }
14
+ end
15
+
16
+ def call(*)
17
+ case detect_app
18
+ when :rails
19
+ Services::App::Serve::RailsService.call(
20
+ host: host,
21
+ port: port,
22
+ context: @ctx
23
+ )
24
+ when :node
25
+ Services::App::Serve::NodeService.call(
26
+ host: host,
27
+ port: port,
28
+ context: @ctx
29
+ )
30
+ when :php
31
+ Services::App::Serve::PHPService.call(
32
+ host: host,
33
+ port: port,
34
+ context: @ctx
35
+ )
36
+ end
37
+ end
38
+
39
+ def self.help
40
+ ShopifyCLI::Context.message("core.app.serve.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
41
+ end
42
+
43
+ def self.extended_help
44
+ ShopifyCLI::Context.message("app.core.serve.extended_help")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require "project_types/node/cli"
2
+
3
+ module ShopifyCLI
4
+ module Commands
5
+ class App
6
+ class Tunnel < ShopifyCLI::Command::AppSubCommand
7
+ def call(args, _name)
8
+ subcommand = args.shift
9
+ case subcommand
10
+ when "auth"
11
+ token = args.shift
12
+ if token.nil?
13
+ raise ShopifyCLI::Abort, @ctx.message("core.app.tunnel.error.token_argument_missing")
14
+ else
15
+ Services::App::Tunnel::AuthService.call(
16
+ token: token,
17
+ context: @ctx
18
+ )
19
+ end
20
+ when "start"
21
+ Services::App::Tunnel::StartService.call(
22
+ context: @ctx
23
+ )
24
+ when "stop"
25
+ Services::App::Tunnel::StopService.call(
26
+ context: @ctx
27
+ )
28
+ else
29
+ @ctx.puts(self.class.help)
30
+ end
31
+ end
32
+
33
+ def self.help
34
+ ShopifyCLI::Context.message("core.app.tunnel.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
35
+ end
36
+
37
+ def self.extended_help
38
+ ShopifyCLI::Context.message("core.app.tunnel.extended_help", ShopifyCLI::TOOL_NAME)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ require "shopify_cli"
2
+
3
+ module ShopifyCLI
4
+ module Commands
5
+ class App < ShopifyCLI::Command
6
+ subcommand :Connect, "connect", "shopify_cli/commands/app/connect"
7
+ subcommand :Create, "create", "shopify_cli/commands/app/create"
8
+ subcommand :Deploy, "deploy", "shopify_cli/commands/app/deploy"
9
+ subcommand :Open, "open", "shopify_cli/commands/app/open"
10
+ subcommand :Serve, "serve", "shopify_cli/commands/app/serve"
11
+ subcommand :Tunnel, "tunnel", "shopify_cli/commands/app/tunnel"
12
+
13
+ def call(*)
14
+ @ctx.puts(self.class.help)
15
+ end
16
+
17
+ class << self
18
+ def help
19
+ subcommands = subcommand_registry.command_names.join(" | ")
20
+ ShopifyCLI::Context.message("core.app.help", ShopifyCLI::TOOL_NAME, subcommands)
21
+ end
22
+
23
+ def call_help(*)
24
+ @ctx.puts(help)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -16,7 +16,7 @@ module ShopifyCLI
16
16
  ShopifyCLI::Context.message("core.config.help", ShopifyCLI::TOOL_NAME)
17
17
  end
18
18
 
19
- class Feature < ShopifyCLI::SubCommand
19
+ class Feature < ShopifyCLI::Command::SubCommand
20
20
  def self.help
21
21
  ShopifyCLI::Context.message("core.config.feature.help", ShopifyCLI::TOOL_NAME)
22
22
  end
@@ -45,7 +45,7 @@ module ShopifyCLI
45
45
  end
46
46
  end
47
47
 
48
- class Analytics < ShopifyCLI::SubCommand
48
+ class Analytics < ShopifyCLI::Command::SubCommand
49
49
  def self.help
50
50
  ShopifyCLI::Context.message("core.config.analytics.help", ShopifyCLI::TOOL_NAME)
51
51
  end