shopify-cli 2.6.6 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer.json +5 -0
  3. data/.github/DESIGN.md +1 -1
  4. data/.github/ISSUE_TEMPLATE.md +7 -0
  5. data/.vscode/extensions.json +5 -0
  6. data/.vscode/settings.json +9 -0
  7. data/CHANGELOG.md +12 -3
  8. data/CONTRIBUTING.md +1 -29
  9. data/{Dockerfile → Codespace.dockerfile} +0 -0
  10. data/Gemfile.lock +4 -4
  11. data/README.md +20 -99
  12. data/Tests.dockerfile +35 -0
  13. data/assets/logo.png +0 -0
  14. data/dev.yml +0 -3
  15. data/docs/README.md +13 -0
  16. data/docs/contributors/testing.md +27 -0
  17. data/docs/users/installation.md +46 -0
  18. data/{THEMEKIT_MIGRATION.md → docs/users/migrate-from-themekit.md} +1 -1
  19. data/lib/project_types/extension/cli.rb +6 -3
  20. data/lib/project_types/extension/commands/create.rb +5 -6
  21. data/lib/project_types/extension/commands/extension_command.rb +1 -1
  22. data/lib/project_types/extension/features/argo_serve.rb +9 -23
  23. data/lib/project_types/extension/forms/questions/ask_template.rb +1 -5
  24. data/lib/project_types/extension/models/development_server_requirements.rb +2 -3
  25. data/lib/project_types/extension/models/server_config/app.rb +13 -0
  26. data/lib/project_types/extension/models/server_config/development.rb +5 -4
  27. data/lib/project_types/extension/models/server_config/development_renderer.rb +1 -1
  28. data/lib/project_types/extension/models/server_config/development_resource.rb +13 -0
  29. data/lib/project_types/extension/models/server_config/extension.rb +3 -1
  30. data/lib/project_types/extension/models/server_config/root.rb +4 -1
  31. data/lib/project_types/extension/tasks/convert_server_config.rb +65 -0
  32. data/lib/project_types/extension/tasks/ensure_resource_url.rb +39 -0
  33. data/lib/project_types/extension/tasks/merge_server_config.rb +32 -0
  34. data/lib/project_types/extension/tasks/run_extension_command.rb +10 -9
  35. data/lib/project_types/node/cli.rb +0 -16
  36. data/lib/project_types/node/forms/create.rb +5 -5
  37. data/lib/project_types/node/messages/messages.rb +2 -144
  38. data/lib/project_types/php/cli.rb +0 -11
  39. data/lib/project_types/php/forms/create.rb +5 -6
  40. data/lib/project_types/php/messages/messages.rb +2 -161
  41. data/lib/project_types/rails/cli.rb +0 -16
  42. data/lib/project_types/rails/commands/create.rb +1 -1
  43. data/lib/project_types/rails/forms/create.rb +5 -6
  44. data/lib/project_types/rails/messages/messages.rb +6 -151
  45. data/lib/project_types/script/cli.rb +1 -1
  46. data/lib/project_types/script/commands/create.rb +1 -1
  47. data/lib/project_types/script/commands/push.rb +1 -1
  48. data/lib/project_types/theme/cli.rb +1 -1
  49. data/lib/project_types/theme/commands/check.rb +1 -1
  50. data/lib/project_types/theme/commands/delete.rb +1 -1
  51. data/lib/project_types/theme/commands/init.rb +1 -1
  52. data/lib/project_types/theme/commands/language_server.rb +1 -1
  53. data/lib/project_types/theme/commands/package.rb +1 -1
  54. data/lib/project_types/theme/commands/publish.rb +1 -1
  55. data/lib/project_types/theme/commands/pull.rb +1 -1
  56. data/lib/project_types/theme/commands/push.rb +1 -1
  57. data/lib/project_types/theme/commands/serve.rb +9 -3
  58. data/lib/project_types/theme/messages/messages.rb +5 -1
  59. data/lib/shopify_cli/admin_api/populate_resource_command.rb +1 -1
  60. data/lib/shopify_cli/api.rb +7 -2
  61. data/lib/shopify_cli/app_type_detector.rb +24 -20
  62. data/lib/shopify_cli/command/app_sub_command.rb +10 -0
  63. data/lib/shopify_cli/command/project_command.rb +18 -0
  64. data/lib/shopify_cli/command/sub_command.rb +19 -0
  65. data/lib/shopify_cli/command.rb +7 -2
  66. data/lib/shopify_cli/commands/app/connect.rb +22 -0
  67. data/lib/shopify_cli/commands/app/create/node.rb +38 -0
  68. data/lib/shopify_cli/commands/app/create/php.rb +36 -0
  69. data/lib/shopify_cli/commands/app/create/rails.rb +40 -0
  70. data/lib/shopify_cli/commands/app/create.rb +28 -0
  71. data/lib/shopify_cli/commands/app/deploy.rb +49 -0
  72. data/lib/shopify_cli/commands/app/open.rb +19 -0
  73. data/lib/shopify_cli/commands/app/serve.rb +49 -0
  74. data/lib/shopify_cli/commands/app/tunnel.rb +43 -0
  75. data/lib/shopify_cli/commands/app.rb +29 -0
  76. data/lib/shopify_cli/commands/config.rb +2 -2
  77. data/lib/shopify_cli/commands.rb +1 -0
  78. data/lib/shopify_cli/constants.rb +4 -0
  79. data/lib/shopify_cli/exception_reporter.rb +3 -4
  80. data/lib/shopify_cli/git.rb +12 -1
  81. data/lib/shopify_cli/github/issue_url_generator.rb +19 -0
  82. data/lib/shopify_cli/github.rb +5 -0
  83. data/lib/shopify_cli/messages/messages.rb +252 -8
  84. data/lib/shopify_cli/project.rb +5 -1
  85. data/lib/shopify_cli/project_commands.rb +1 -1
  86. data/lib/shopify_cli/services/app/connect_service.rb +25 -0
  87. data/lib/shopify_cli/services/app/create/node_service.rb +153 -0
  88. data/lib/shopify_cli/services/app/create/php_service.rb +152 -0
  89. data/lib/shopify_cli/services/app/create/rails_service.rb +213 -0
  90. data/lib/shopify_cli/services/app/deploy/heroku/node_service.rb +101 -0
  91. data/lib/shopify_cli/services/app/deploy/heroku/php_service.rb +135 -0
  92. data/lib/shopify_cli/services/app/deploy/heroku/rails_service.rb +120 -0
  93. data/lib/shopify_cli/services/app/open_service.rb +19 -0
  94. data/lib/shopify_cli/services/app/serve/node_service.rb +42 -0
  95. data/lib/shopify_cli/services/app/serve/php_service.rb +46 -0
  96. data/lib/shopify_cli/services/app/serve/rails_service.rb +48 -0
  97. data/lib/shopify_cli/services/app/tunnel/auth_service.rb +21 -0
  98. data/lib/shopify_cli/services/app/tunnel/start_service.rb +20 -0
  99. data/lib/shopify_cli/services/app/tunnel/stop_service.rb +20 -0
  100. data/lib/shopify_cli/services.rb +31 -0
  101. data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
  102. data/lib/shopify_cli/theme/dev_server.rb +8 -2
  103. data/lib/shopify_cli/version.rb +1 -1
  104. data/lib/shopify_cli.rb +1 -2
  105. data/shopify-cli.gemspec +1 -1
  106. data/shopify-dev +18 -0
  107. data/utilities/constants.rb +7 -0
  108. data/utilities/docker/container.rb +10 -3
  109. data/utilities/docker.rb +2 -2
  110. data/utilities/utilities.rb +1 -0
  111. metadata +49 -48
  112. data/docs/_config.yml +0 -2
  113. data/docs/app/node/commands/index.md +0 -4
  114. data/docs/app/node/index.md +0 -4
  115. data/docs/app/rails/commands/index.md +0 -4
  116. data/docs/app/rails/index.md +0 -4
  117. data/docs/core/index.md +0 -4
  118. data/docs/getting-started/index.md +0 -4
  119. data/docs/getting-started/install/index.md +0 -4
  120. data/docs/getting-started/migrate/index.md +0 -4
  121. data/docs/getting-started/uninstall/index.md +0 -4
  122. data/docs/getting-started/upgrade/index.md +0 -4
  123. data/docs/help/start-app/index.md +0 -4
  124. data/docs/index.md +0 -4
  125. data/install.sh +0 -7
  126. data/lib/project_types/extension/tasks/converters/server_config_converter.rb +0 -30
  127. data/lib/project_types/extension/tasks/load_server_config.rb +0 -28
  128. data/lib/project_types/node/commands/connect.rb +0 -21
  129. data/lib/project_types/node/commands/create.rb +0 -125
  130. data/lib/project_types/node/commands/deploy/heroku.rb +0 -96
  131. data/lib/project_types/node/commands/deploy.rb +0 -32
  132. data/lib/project_types/node/commands/generate.rb +0 -22
  133. data/lib/project_types/node/commands/open.rb +0 -18
  134. data/lib/project_types/node/commands/serve.rb +0 -45
  135. data/lib/project_types/node/commands/tunnel.rb +0 -41
  136. data/lib/project_types/php/commands/connect.rb +0 -19
  137. data/lib/project_types/php/commands/create.rb +0 -143
  138. data/lib/project_types/php/commands/deploy/heroku.rb +0 -129
  139. data/lib/project_types/php/commands/deploy.rb +0 -32
  140. data/lib/project_types/php/commands/open.rb +0 -16
  141. data/lib/project_types/php/commands/serve.rb +0 -48
  142. data/lib/project_types/php/commands/tunnel.rb +0 -37
  143. data/lib/project_types/rails/commands/connect.rb +0 -21
  144. data/lib/project_types/rails/commands/deploy/heroku.rb +0 -115
  145. data/lib/project_types/rails/commands/deploy.rb +0 -32
  146. data/lib/project_types/rails/commands/generate/webhook.rb +0 -42
  147. data/lib/project_types/rails/commands/generate.rb +0 -60
  148. data/lib/project_types/rails/commands/open.rb +0 -18
  149. data/lib/project_types/rails/commands/serve.rb +0 -51
  150. data/lib/project_types/rails/commands/tunnel.rb +0 -41
  151. data/lib/shopify_cli/sub_command.rb +0 -17
  152. data/shopify.fish +0 -12
  153. data/shopify.sh +0 -11
@@ -5,22 +5,6 @@ module Rails
5
5
  register_messages(Rails::Messages::MESSAGES)
6
6
  end
7
7
 
8
- # define/autoload project specific Commands
9
- class Command < ShopifyCLI::ProjectCommands
10
- subcommand :Connect, "connect", Project.project_filepath("commands/connect")
11
- subcommand :Create, "create", Project.project_filepath("commands/create")
12
- subcommand :Deploy, "deploy", Project.project_filepath("commands/deploy")
13
- subcommand :Generate, "generate", Project.project_filepath("commands/generate")
14
- subcommand :Open, "open", Project.project_filepath("commands/open")
15
- subcommand :Serve, "serve", Project.project_filepath("commands/serve")
16
- subcommand :Tunnel, "tunnel", Project.project_filepath("commands/tunnel")
17
- end
18
- ShopifyCLI::Commands.register("Rails::Command", "rails")
19
-
20
- # define/autoload project specific Tasks
21
- module Tasks
22
- end
23
-
24
8
  # define/autoload project specific Forms
25
9
  module Forms
26
10
  autoload :Create, Project.project_filepath("forms/create")
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Rails
3
3
  class Command
4
- class Create < ShopifyCLI::SubCommand
4
+ class Create < ShopifyCLI::Command::AppSubCommand
5
5
  unless ShopifyCLI::Environment.acceptance_test?
6
6
  prerequisite_task :ensure_authenticated
7
7
  end
@@ -3,8 +3,7 @@ require "uri"
3
3
  module Rails
4
4
  module Forms
5
5
  class Create < ShopifyCLI::Form
6
- attr_accessor :name
7
- flag_arguments :title, :organization_id, :shop_domain, :type, :db
6
+ flag_arguments :name, :organization_id, :shop_domain, :type, :db
8
7
  VALID_DB_TYPES = ["sqlite3",
9
8
  "mysql",
10
9
  "postgresql",
@@ -18,7 +17,7 @@ module Rails
18
17
  "jdbc"]
19
18
 
20
19
  def ask
21
- self.title ||= CLI::UI::Prompt.ask(ctx.message("rails.forms.create.app_name"))
20
+ self.name ||= CLI::UI::Prompt.ask(ctx.message("rails.forms.create.app_name"))
22
21
  self.name = format_name
23
22
  self.type = ask_type
24
23
  res = ShopifyCLI::Tasks::SelectOrgAndShop.call(ctx, organization_id: organization_id, shop_domain: shop_domain)
@@ -30,13 +29,13 @@ module Rails
30
29
  private
31
30
 
32
31
  def format_name
33
- name = title.downcase.split(" ").join("_")
32
+ formatted_name = name.downcase.split(" ").join("_")
34
33
 
35
- if name.include?("shopify")
34
+ if formatted_name.include?("shopify")
36
35
  ctx.abort(ctx.message("rails.forms.create.error.invalid_app_name"))
37
36
  end
38
37
 
39
- name
38
+ formatted_name
40
39
  end
41
40
 
42
41
  def ask_type
@@ -5,8 +5,8 @@ module Rails
5
5
  MESSAGES = {
6
6
  rails: {
7
7
  help: <<~HELP,
8
- Suite of commands for developing Ruby on Rails apps. See {{command:%1$s rails <command> --help}} for usage of each command.
9
- Usage: {{command:%1$s rails [ %2$s ]}}
8
+ Suite of commands for developing Ruby on Rails apps. See {{command:%1$s app rails <command> --help}} for usage of each command.
9
+ Usage: {{command:%1$s app rails [ %2$s ]}}
10
10
  HELP
11
11
 
12
12
  error: {
@@ -21,117 +21,22 @@ module Rails
21
21
  setting_gem_home: "GEM_HOME being set to %s",
22
22
  setting_gem_path: "GEM_PATH being set to %s",
23
23
  },
24
-
25
- connect: {
26
- connected: "Project now connected to {{green:%s}}",
27
- help: <<~HELP,
28
- {{command:%s rails connect}}: Connects an existing Ruby on Rails app to Shopify CLI. Creates a config file.
29
- Usage: {{command:%s rails connect}}
30
- HELP
31
- production_warning: <<~MESSAGE,
32
- {{yellow:! Warning: if you have connected to an {{bold:app in production}}, running {{command:serve}} may update the app URL and cause an outage.
33
- MESSAGE
34
- },
35
-
36
- create: {
37
- help: <<~HELP,
38
- {{command:%s rails create}}: Creates a ruby on rails app.
39
- Usage: {{command:%s rails create}}
40
- Options:
41
- {{command:--name=NAME}} App name. Any string.
42
- {{command:--organization-id=ID}} Partner organization ID. Must be an existing organization.
43
- {{command:--store=MYSHOPIFYDOMAIN }} Development store URL. Must be an existing development store.
44
- {{command:--db=DB}} Database type. Must be one of: mysql, postgresql, sqlite3, oracle, frontbase, ibm_db, sqlserver, jdbcmysql, jdbcsqlite3, jdbcpostgresql, jdbc.
45
- {{command:--rails-opts=RAILSOPTS}} Additional options. Must be string containing one or more valid Rails options, separated by spaces.
46
- HELP
47
-
48
- error: {
49
- invalid_ruby_version: "This project requires a Ruby version ~> 2.5 or Ruby 3.0.",
50
- dir_exists: "Project directory %s already exists. Please use a different name.",
51
- install_failure: "Error installing %s gem",
52
- node_required: "node is required to create a rails project. Download at https://nodejs.org/en/download.",
53
- node_version_failure: "Failed to get the current node version. Please make sure it is installed as " \
54
- "per the instructions at https://nodejs.org/en.",
55
- yarn_required: "yarn is required to create a rails project. Download at " \
56
- "https://classic.yarnpkg.com/en/docs/install.",
57
- yarn_version_failure: "Failed to get the current yarn version. Please make sure it is installed as per " \
58
- "the instructions at https://classic.yarnpkg.com/en/docs/install.",
59
- },
60
-
61
- info: {
62
- open_new_shell: "{{*}} {{yellow:After installing %s, please open a new Command Prompt or PowerShell " \
63
- "window to continue.}}",
64
- },
65
- installing_bundler: "Installing bundler…",
66
- generating_app: "Generating new rails app project in %s…",
67
- adding_shopify_gem: "{{v}} Adding shopify_app gem…",
68
- node_version: "node %s",
69
- yarn_version: "yarn %s",
70
- running_bundle_install: "Running bundle install…",
71
- running_generator: "Running shopify_app generator…",
72
- running_migrations: "Running migrations…",
73
- running_webpacker_install: "Running webpacker:install…",
74
- },
75
-
76
24
  deploy: {
77
25
  help: <<~HELP,
78
26
  Deploy the current Rails project to a hosting service. Heroku ({{underline:https://www.heroku.com}}) is currently the only option, but more will be added in the future.
79
- Usage: {{command:%s rails deploy [ heroku ]}}
27
+ Usage: {{command:%s app rails deploy [ heroku ]}}
80
28
  HELP
81
29
  extended_help: <<~HELP,
82
30
  {{bold:Subcommands:}}
83
31
  {{cyan:heroku}}: Deploys the current Rails project to Heroku.
84
- Usage: {{command:%s rails deploy heroku}}
32
+ Usage: {{command:%s app rails deploy heroku}}
85
33
  HELP
86
-
87
- heroku: {
88
- help: <<~HELP,
89
- Deploy the current Rails project to Heroku
90
- Usage: {{command:%s rails deploy heroku}}
91
- HELP
92
- downloading: "Downloading Heroku CLI…",
93
- downloaded: "Downloaded Heroku CLI",
94
- installing: "Installing Heroku CLI…",
95
- installed: "Installed Heroku CLI",
96
- authenticated_with_account: "{{v}} Authenticated with Heroku as {{green:%s}}",
97
- authenticating: "Authenticating with Heroku…",
98
- authenticated: "{{v}} Authenticated with Heroku",
99
- deploying: "Deploying to Heroku…",
100
- deployed: "{{v}} Deployed to Heroku",
101
- db_check: {
102
- validating: "Validating application…",
103
- checking: "Checking database type…",
104
- validated: "Database type \"%s\" validated for platform \"Heroku\"",
105
- problem: "A problem was encountered while checking your database type.",
106
- sqlite: <<~SQLITE,
107
- Heroku does not support deployment using the SQLite database system.
108
- Change the database type using {{command:rails db:system:change --to=[new_db_type]}}. For more info:
109
- {{underline:https://gorails.com/episodes/rails-6-db-system-change-command}}
110
- SQLITE
111
- },
112
- git: {
113
- checking: "Checking git repo…",
114
- initialized: "Git repo initialized",
115
- what_branch: "What branch would you like to deploy?",
116
- branch_selected: "{{v}} Git branch {{green:%s}} selected for deploy",
117
- },
118
- app: {
119
- no_apps_found: "No existing Heroku app found. What would you like to do?",
120
- name: "What is your Heroku app’s name?",
121
- select: "Specify an existing Heroku app",
122
- selecting: "Selecting Heroku app %s…",
123
- selected: "{{v}} Heroku app {{green:%s}} selected",
124
- create: "Create a new Heroku app",
125
- creating: "Creating new Heroku app…",
126
- created: "{{v}} New Heroku app created",
127
- },
128
- },
129
34
  },
130
35
 
131
36
  generate: {
132
37
  help: <<~HELP,
133
38
  Generate code in your Rails project. Currently supports generating new webhooks.
134
- Usage: {{command:%s rails generate [ webhook ]}}
39
+ Usage: {{command:%s app rails generate [ webhook ]}}
135
40
  HELP
136
41
  extended_help: <<~EXAMPLES,
137
42
  {{bold:Examples:}}
@@ -147,63 +52,13 @@ module Rails
147
52
  webhook: {
148
53
  help: <<~HELP,
149
54
  Generate and register a new webhook that listens for the specified Shopify store event.
150
- Usage: {{command:%s rails generate webhook <type>}}
55
+ Usage: {{command:%s app rails generate webhook <type>}}
151
56
  HELP
152
57
 
153
58
  select: "What type of webhook would you like to create?",
154
59
  selected: "Generating webhook: %s",
155
60
  },
156
61
  },
157
-
158
- open: {
159
- help: <<~HELP,
160
- Open your local development app in the default browser.
161
- Usage: {{command:%s rails open}}
162
- HELP
163
- },
164
-
165
- serve: {
166
- help: <<~HELP,
167
- Start a local development rails server for your project, as well as a public ngrok tunnel to your localhost.
168
- Usage: {{command:%s rails serve}}
169
- HELP
170
- extended_help: <<~HELP,
171
- {{bold:Options:}}
172
- {{cyan:--host=HOST}}: Bypass running tunnel and use custom host. HOST must be HTTPS url.
173
- {{cyan:--port=PORT}}: Use custom port.
174
- HELP
175
-
176
- open_info: <<~MESSAGE,
177
- {{*}} To install and start using your app, open this URL in your browser:
178
- {{green:%s}}
179
- MESSAGE
180
- running_server: "Running server…",
181
- },
182
-
183
- tunnel: {
184
- help: <<~HELP,
185
- Start or stop an http tunnel to your local development app using ngrok.
186
- Usage: {{command:%s rails tunnel [ auth | start | stop ]}}
187
- HELP
188
- extended_help: <<~HELP,
189
- {{bold:Subcommands:}}
190
-
191
- {{cyan:auth}}: Writes an ngrok auth token to ~/.ngrok2/ngrok.yml to connect with an ngrok account. Visit https://dashboard.ngrok.com/signup to sign up.
192
- Usage: {{command:%1$s rails tunnel auth <token>}}
193
-
194
- {{cyan:start}}: Starts an ngrok tunnel, will print the URL for an existing tunnel if already running.
195
- Usage: {{command:%1$s rails tunnel start}}
196
-
197
- {{cyan:stop}}: Stops the ngrok tunnel.
198
- Usage: {{command:%1$s rails tunnel stop}}
199
-
200
- HELP
201
-
202
- error: {
203
- token_argument_missing: "{{x}} {{red:auth requires a token argument}}\n\n",
204
- },
205
- },
206
-
207
62
  forms: {
208
63
  create: {
209
64
  error: {
@@ -9,7 +9,7 @@ module Script
9
9
  end
10
10
 
11
11
  # define/autoload project specific Commands
12
- class Command < ShopifyCLI::ProjectCommands
12
+ class Command < ShopifyCLI::Command::ProjectCommand
13
13
  hidden_feature(feature_set: :script_project)
14
14
  subcommand :Create, "create", Project.project_filepath("commands/create")
15
15
  subcommand :Push, "push", Project.project_filepath("commands/push")
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Script
4
4
  class Command
5
- class Create < ShopifyCLI::SubCommand
5
+ class Create < ShopifyCLI::Command::SubCommand
6
6
  unless ShopifyCLI::Environment.acceptance_test?
7
7
  prerequisite_task :ensure_authenticated
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Script
4
4
  class Command
5
- class Push < ShopifyCLI::SubCommand
5
+ class Push < ShopifyCLI::Command::SubCommand
6
6
  prerequisite_task ensure_project_type: :script
7
7
 
8
8
  options do |parser, flags|
@@ -5,7 +5,7 @@ module Theme
5
5
  register_messages(Theme::Messages::MESSAGES)
6
6
  end
7
7
 
8
- class Command < ShopifyCLI::ProjectCommands
8
+ class Command < ShopifyCLI::Command::ProjectCommand
9
9
  subcommand :Init, "init", Project.project_filepath("commands/init")
10
10
  subcommand :Serve, "serve", Project.project_filepath("commands/serve")
11
11
  subcommand :Pull, "pull", Project.project_filepath("commands/pull")
@@ -3,7 +3,7 @@ require "theme_check"
3
3
 
4
4
  module Theme
5
5
  class Command
6
- class Check < ShopifyCLI::SubCommand
6
+ class Check < ShopifyCLI::Command::SubCommand
7
7
  class Options < ShopifyCLI::Options
8
8
  def initialize(theme_check)
9
9
  super()
@@ -4,7 +4,7 @@ require "shopify_cli/theme/development_theme"
4
4
 
5
5
  module Theme
6
6
  class Command
7
- class Delete < ShopifyCLI::SubCommand
7
+ class Delete < ShopifyCLI::Command::SubCommand
8
8
  options do |parser, flags|
9
9
  parser.on("-d", "--development") { flags[:development] = true }
10
10
  parser.on("-a", "--show-all") { flags[:show_all] = true }
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Theme
4
4
  class Command
5
- class Init < ShopifyCLI::SubCommand
5
+ class Init < ShopifyCLI::Command::SubCommand
6
6
  options do |parser, flags|
7
7
  parser.on("-u", "--clone-url URL") { |url| flags[:clone_url] = url }
8
8
  end
@@ -3,7 +3,7 @@ require "theme_check"
3
3
 
4
4
  module Theme
5
5
  class Command
6
- class LanguageServer < ShopifyCLI::SubCommand
6
+ class LanguageServer < ShopifyCLI::Command::SubCommand
7
7
  def call(*)
8
8
  ThemeCheck::LanguageServer.start
9
9
  end
@@ -4,7 +4,7 @@ require "json"
4
4
 
5
5
  module Theme
6
6
  class Command
7
- class Package < ShopifyCLI::SubCommand
7
+ class Package < ShopifyCLI::Command::SubCommand
8
8
  THEME_DIRECTORIES = %w[
9
9
  assets
10
10
  config
@@ -3,7 +3,7 @@ require "shopify_cli/theme/theme"
3
3
 
4
4
  module Theme
5
5
  class Command
6
- class Publish < ShopifyCLI::SubCommand
6
+ class Publish < ShopifyCLI::Command::SubCommand
7
7
  options do |parser, flags|
8
8
  parser.on("-f", "--force") { flags[:force] = true }
9
9
  end
@@ -5,7 +5,7 @@ require "shopify_cli/theme/syncer"
5
5
 
6
6
  module Theme
7
7
  class Command
8
- class Pull < ShopifyCLI::SubCommand
8
+ class Pull < ShopifyCLI::Command::SubCommand
9
9
  options do |parser, flags|
10
10
  parser.on("-n", "--nodelete") { flags[:nodelete] = true }
11
11
  parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
@@ -6,7 +6,7 @@ require "shopify_cli/theme/syncer"
6
6
 
7
7
  module Theme
8
8
  class Command
9
- class Push < ShopifyCLI::SubCommand
9
+ class Push < ShopifyCLI::Command::SubCommand
10
10
  options do |parser, flags|
11
11
  parser.on("-n", "--nodelete") { flags[:nodelete] = true }
12
12
  parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
@@ -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, ".", http_bind: 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
@@ -94,10 +94,14 @@ module Theme
94
94
  Options:
95
95
  {{command:--port=PORT}} Local port to serve theme preview from
96
96
  {{command:--poll}} Force polling to detect file changes
97
- {{command:--bind=HOST}} Set which network interface the web server listens on
97
+ {{command:--host=HOST}} Set which network interface the web server listens on. The default value is 127.0.0.1.
98
98
  HELP
99
99
  serve: "Viewing theme…",
100
100
  open_fail: "Couldn't open the theme",
101
+ error: {
102
+ address_binding_error: "Couldn't bind to localhost."\
103
+ " To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
104
+ },
101
105
  },
102
106
  check: {
103
107
  help: <<~HELP,
@@ -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,18 @@
1
+ module ShopifyCLI
2
+ class Command
3
+ class ProjectCommand < Command
4
+ def call(*)
5
+ @ctx.puts(self.class.help)
6
+ end
7
+
8
+ def self.help
9
+ project_type = name.split("::")[0].downcase
10
+ ShopifyCLI::Context.message(
11
+ "#{project_type}.help",
12
+ ShopifyCLI::TOOL_NAME,
13
+ subcommand_registry.command_names.join(" | ")
14
+ )
15
+ end
16
+ end
17
+ end
18
+ 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