shopify-cli 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) 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/.github/PULL_REQUEST_TEMPLATE.md +15 -4
  6. data/.github/workflows/shopify.yml +3 -6
  7. data/.vscode/extensions.json +5 -0
  8. data/.vscode/settings.json +9 -0
  9. data/CHANGELOG.md +98 -104
  10. data/CONTRIBUTING.md +1 -21
  11. data/Codespace.dockerfile +35 -0
  12. data/Gemfile +2 -0
  13. data/Gemfile.lock +9 -5
  14. data/README.md +20 -99
  15. data/RELEASING.md +17 -30
  16. data/Rakefile +0 -5
  17. data/Tests.dockerfile +35 -0
  18. data/assets/logo.png +0 -0
  19. data/dev.yml +0 -3
  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/lib/project_types/extension/cli.rb +7 -3
  25. data/lib/project_types/extension/commands/create.rb +6 -6
  26. data/lib/project_types/extension/commands/extension_command.rb +1 -1
  27. data/lib/project_types/extension/features/argo.rb +9 -10
  28. data/lib/project_types/extension/features/argo_serve.rb +9 -23
  29. data/lib/project_types/extension/forms/create.rb +1 -1
  30. data/lib/project_types/extension/forms/questions/ask_template.rb +3 -6
  31. data/lib/project_types/extension/messages/messages.rb +1 -0
  32. data/lib/project_types/extension/models/development_server_requirements.rb +2 -3
  33. data/lib/project_types/extension/models/server_config/app.rb +13 -0
  34. data/lib/project_types/extension/models/server_config/development.rb +5 -4
  35. data/lib/project_types/extension/models/server_config/development_renderer.rb +1 -1
  36. data/lib/project_types/extension/models/server_config/development_resource.rb +13 -0
  37. data/lib/project_types/extension/models/server_config/extension.rb +4 -0
  38. data/lib/project_types/extension/models/server_config/root.rb +4 -1
  39. data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +1 -1
  40. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +1 -1
  41. data/lib/project_types/extension/tasks/convert_server_config.rb +65 -0
  42. data/lib/project_types/extension/tasks/ensure_resource_url.rb +39 -0
  43. data/lib/project_types/extension/tasks/find_package_from_json.rb +37 -0
  44. data/lib/project_types/extension/tasks/merge_server_config.rb +32 -0
  45. data/lib/project_types/extension/tasks/run_extension_command.rb +10 -9
  46. data/lib/project_types/node/cli.rb +0 -16
  47. data/lib/project_types/node/forms/create.rb +5 -5
  48. data/lib/project_types/node/messages/messages.rb +2 -149
  49. data/lib/project_types/php/cli.rb +0 -11
  50. data/lib/project_types/php/forms/create.rb +5 -6
  51. data/lib/project_types/php/messages/messages.rb +2 -164
  52. data/lib/project_types/rails/cli.rb +0 -16
  53. data/lib/project_types/rails/commands/create.rb +46 -17
  54. data/lib/project_types/rails/forms/create.rb +5 -7
  55. data/lib/project_types/rails/messages/messages.rb +6 -154
  56. data/lib/project_types/script/cli.rb +1 -1
  57. data/lib/project_types/script/commands/create.rb +5 -6
  58. data/lib/project_types/script/commands/push.rb +1 -1
  59. data/lib/project_types/script/config/extension_points.yml +10 -0
  60. data/lib/project_types/script/errors.rb +0 -18
  61. data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
  62. data/lib/project_types/script/layers/application/build_script.rb +2 -1
  63. data/lib/project_types/script/layers/application/create_script.rb +2 -2
  64. data/lib/project_types/script/layers/application/push_script.rb +15 -1
  65. data/lib/project_types/script/layers/domain/push_package.rb +5 -2
  66. data/lib/project_types/script/layers/domain/script_json.rb +1 -1
  67. data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +0 -4
  68. data/lib/project_types/script/layers/infrastructure/errors.rb +17 -2
  69. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +29 -13
  70. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +29 -13
  71. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -2
  72. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +3 -4
  73. data/lib/project_types/script/layers/infrastructure/script_service.rb +7 -2
  74. data/lib/project_types/script/messages/messages.rb +9 -22
  75. data/lib/project_types/script/ui/error_handler.rb +16 -26
  76. data/lib/project_types/theme/cli.rb +1 -1
  77. data/lib/project_types/theme/commands/check.rb +1 -1
  78. data/lib/project_types/theme/commands/delete.rb +1 -1
  79. data/lib/project_types/theme/commands/init.rb +1 -1
  80. data/lib/project_types/theme/commands/language_server.rb +1 -1
  81. data/lib/project_types/theme/commands/package.rb +1 -1
  82. data/lib/project_types/theme/commands/publish.rb +1 -1
  83. data/lib/project_types/theme/commands/pull.rb +1 -1
  84. data/lib/project_types/theme/commands/push.rb +1 -1
  85. data/lib/project_types/theme/commands/serve.rb +10 -2
  86. data/lib/project_types/theme/messages/messages.rb +10 -0
  87. data/lib/shopify_cli/admin_api/populate_resource_command.rb +1 -1
  88. data/lib/shopify_cli/api.rb +7 -2
  89. data/lib/shopify_cli/app_type_detector.rb +36 -0
  90. data/lib/shopify_cli/command/app_sub_command.rb +10 -0
  91. data/lib/shopify_cli/command/project_command.rb +18 -0
  92. data/lib/shopify_cli/command/sub_command.rb +19 -0
  93. data/lib/shopify_cli/command.rb +13 -3
  94. data/lib/shopify_cli/command_options/command_serve_options.rb +43 -0
  95. data/lib/shopify_cli/command_options.rb +7 -0
  96. data/lib/shopify_cli/commands/app/connect.rb +22 -0
  97. data/lib/shopify_cli/commands/app/create/node.rb +38 -0
  98. data/lib/shopify_cli/commands/app/create/php.rb +36 -0
  99. data/lib/shopify_cli/commands/app/create/rails.rb +40 -0
  100. data/lib/shopify_cli/commands/app/create.rb +28 -0
  101. data/lib/shopify_cli/commands/app/deploy.rb +49 -0
  102. data/lib/shopify_cli/commands/app/open.rb +19 -0
  103. data/lib/shopify_cli/commands/app/serve.rb +49 -0
  104. data/lib/shopify_cli/commands/app/tunnel.rb +43 -0
  105. data/lib/shopify_cli/commands/app.rb +29 -0
  106. data/lib/shopify_cli/commands/config.rb +2 -2
  107. data/lib/shopify_cli/commands/login.rb +3 -3
  108. data/lib/shopify_cli/commands/reporting.rb +38 -0
  109. data/lib/shopify_cli/commands/switch.rb +1 -1
  110. data/lib/shopify_cli/commands.rb +2 -0
  111. data/lib/shopify_cli/constants.rb +11 -3
  112. data/lib/shopify_cli/core/monorail.rb +9 -20
  113. data/lib/shopify_cli/environment.rb +15 -1
  114. data/lib/shopify_cli/exception_reporter.rb +29 -16
  115. data/lib/shopify_cli/git.rb +12 -1
  116. data/lib/shopify_cli/github/issue_url_generator.rb +19 -0
  117. data/lib/shopify_cli/github.rb +5 -0
  118. data/lib/shopify_cli/messages/messages.rb +295 -22
  119. data/lib/shopify_cli/migrator/migration.rb +1 -1
  120. data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +1 -1
  121. data/lib/shopify_cli/migrator/migrations/1633691650_merge_reporting_configuration.rb +41 -0
  122. data/lib/shopify_cli/migrator.rb +9 -11
  123. data/lib/shopify_cli/project.rb +5 -1
  124. data/lib/shopify_cli/project_commands.rb +1 -1
  125. data/lib/shopify_cli/reporting_configuration_controller.rb +64 -0
  126. data/lib/shopify_cli/services/app/connect_service.rb +25 -0
  127. data/lib/shopify_cli/services/app/create/node_service.rb +153 -0
  128. data/lib/shopify_cli/services/app/create/php_service.rb +152 -0
  129. data/lib/shopify_cli/services/app/create/rails_service.rb +213 -0
  130. data/lib/shopify_cli/services/app/deploy/heroku/node_service.rb +101 -0
  131. data/lib/shopify_cli/services/app/deploy/heroku/php_service.rb +135 -0
  132. data/lib/shopify_cli/services/app/deploy/heroku/rails_service.rb +120 -0
  133. data/lib/shopify_cli/services/app/open_service.rb +19 -0
  134. data/lib/shopify_cli/services/app/serve/node_service.rb +42 -0
  135. data/lib/shopify_cli/services/app/serve/php_service.rb +46 -0
  136. data/lib/shopify_cli/services/app/serve/rails_service.rb +48 -0
  137. data/lib/shopify_cli/services/app/tunnel/auth_service.rb +21 -0
  138. data/lib/shopify_cli/services/app/tunnel/start_service.rb +20 -0
  139. data/lib/shopify_cli/services/app/tunnel/stop_service.rb +20 -0
  140. data/lib/shopify_cli/services/base_service.rb +13 -0
  141. data/lib/shopify_cli/services/reporting_service.rb +16 -0
  142. data/lib/shopify_cli/services.rb +37 -0
  143. data/lib/shopify_cli/theme/dev_server/local_assets.rb +1 -1
  144. data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -2
  145. data/lib/shopify_cli/theme/dev_server.rb +9 -2
  146. data/lib/shopify_cli/version.rb +1 -1
  147. data/lib/shopify_cli.rb +5 -2
  148. data/shopify-cli.gemspec +2 -13
  149. data/shopify-dev +18 -0
  150. data/utilities/constants.rb +7 -0
  151. data/utilities/docker/container.rb +104 -0
  152. data/utilities/docker.rb +45 -3
  153. data/utilities/utilities.rb +1 -0
  154. metadata +63 -54
  155. data/Dockerfile +0 -17
  156. data/docs/_config.yml +0 -2
  157. data/docs/app/node/commands/index.md +0 -4
  158. data/docs/app/node/index.md +0 -4
  159. data/docs/app/rails/commands/index.md +0 -4
  160. data/docs/app/rails/index.md +0 -4
  161. data/docs/core/index.md +0 -4
  162. data/docs/getting-started/index.md +0 -4
  163. data/docs/getting-started/install/index.md +0 -4
  164. data/docs/getting-started/migrate/index.md +0 -4
  165. data/docs/getting-started/uninstall/index.md +0 -4
  166. data/docs/getting-started/upgrade/index.md +0 -4
  167. data/docs/help/start-app/index.md +0 -4
  168. data/docs/index.md +0 -4
  169. data/ext/shopify-cli/extconf.rb +0 -60
  170. data/install.sh +0 -7
  171. data/lib/project_types/extension/tasks/converters/server_config_converter.rb +0 -31
  172. data/lib/project_types/extension/tasks/load_server_config.rb +0 -23
  173. data/lib/project_types/node/commands/connect.rb +0 -21
  174. data/lib/project_types/node/commands/create.rb +0 -125
  175. data/lib/project_types/node/commands/deploy/heroku.rb +0 -96
  176. data/lib/project_types/node/commands/deploy.rb +0 -32
  177. data/lib/project_types/node/commands/generate.rb +0 -22
  178. data/lib/project_types/node/commands/open.rb +0 -18
  179. data/lib/project_types/node/commands/serve.rb +0 -54
  180. data/lib/project_types/node/commands/tunnel.rb +0 -41
  181. data/lib/project_types/php/commands/connect.rb +0 -19
  182. data/lib/project_types/php/commands/create.rb +0 -143
  183. data/lib/project_types/php/commands/deploy/heroku.rb +0 -129
  184. data/lib/project_types/php/commands/deploy.rb +0 -32
  185. data/lib/project_types/php/commands/open.rb +0 -16
  186. data/lib/project_types/php/commands/serve.rb +0 -51
  187. data/lib/project_types/php/commands/tunnel.rb +0 -37
  188. data/lib/project_types/rails/commands/connect.rb +0 -21
  189. data/lib/project_types/rails/commands/deploy/heroku.rb +0 -115
  190. data/lib/project_types/rails/commands/deploy.rb +0 -32
  191. data/lib/project_types/rails/commands/generate/webhook.rb +0 -42
  192. data/lib/project_types/rails/commands/generate.rb +0 -60
  193. data/lib/project_types/rails/commands/open.rb +0 -18
  194. data/lib/project_types/rails/commands/serve.rb +0 -52
  195. data/lib/project_types/rails/commands/tunnel.rb +0 -41
  196. data/lib/project_types/script/graphql/app_script_update_or_create.graphql +0 -0
  197. data/lib/shopify_cli/exception_reporter/permission_controller.rb +0 -54
  198. data/lib/shopify_cli/sub_command.rb +0 -17
  199. data/shopify.fish +0 -12
  200. data/shopify.sh +0 -11
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyCLI
4
+ module Migrator
5
+ module Migrations
6
+ # Before this migration, users configured automatic usage and error
7
+ # reporting independenty. We changed it to be a single configuration
8
+ # in the environment's configuration and therefore we need a migration
9
+ # to merge the configurations.
10
+ class MergeReportingConfiguration
11
+ def self.run
12
+ analytics_enabled = ShopifyCLI::Config.get_bool(
13
+ Constants::Config::Sections::Analytics::NAME,
14
+ Constants::Config::Sections::Analytics::Fields::ENABLED,
15
+ default: false
16
+ )
17
+ error_reporting_enabled = ShopifyCLI::Config.get_bool(
18
+ "error-tracking",
19
+ "automatic-reporting",
20
+ default: false
21
+ )
22
+ # Because we are merging configuration options, both need
23
+ # to be true to for the new flag to be true. Otherwise,
24
+ # we delete them and let the CLI prompt the user again.
25
+ should_merge_be_true = analytics_enabled && error_reporting_enabled
26
+
27
+ unless should_merge_be_true
28
+ ShopifyCLI::Config.unset(
29
+ Constants::Config::Sections::Analytics::NAME,
30
+ Constants::Config::Sections::Analytics::Fields::ENABLED
31
+ )
32
+ ShopifyCLI::Config.unset(
33
+ "error-tracking",
34
+ "automatic-reporting"
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -9,23 +9,21 @@ module ShopifyCLI
9
9
  migrations_directory: File.expand_path("migrator/migrations", __dir__)
10
10
  )
11
11
  baseline_date = last_migration_date
12
- unless baseline_date.nil?
13
- migrations = migrations(migrations_directory: migrations_directory)
14
- .select { |m|
15
- m.date > baseline_date.to_i
16
- }
17
- .each { |m| m.run }
12
+ unless baseline_date.nil?
13
+ migrations(migrations_directory: migrations_directory)
14
+ .select do |m|
15
+ m.date > baseline_date.to_i
16
+ end
17
+ .each(&:run)
18
18
  end
19
19
 
20
20
  store_last_migration_date
21
21
  end
22
22
 
23
- private
24
-
25
23
  def self.store_last_migration_date
26
24
  ShopifyCLI::DB.set(ShopifyCLI::Constants::StoreKeys::LAST_MIGRATION_DATE => Time.now.to_i)
27
25
  end
28
-
26
+
29
27
  def self.last_migration_date
30
28
  ShopifyCLI::DB.get(ShopifyCLI::Constants::StoreKeys::LAST_MIGRATION_DATE)
31
29
  end
@@ -35,7 +33,7 @@ module ShopifyCLI
35
33
  file_name = File.basename(file_path).gsub(".rb", "")
36
34
  file_name_components = file_name.split("_")
37
35
  date_timestamp = file_name_components[0].to_i
38
- migration_name = file_name_components[1...].join("_")
36
+ migration_name = file_name_components.drop(1).join("_")
39
37
 
40
38
  Migrator::Migration.new(
41
39
  name: migration_name,
@@ -45,4 +43,4 @@ module ShopifyCLI
45
43
  end
46
44
  end
47
45
  end
48
- end
46
+ end
@@ -81,7 +81,11 @@ module ShopifyCLI
81
81
  #
82
82
  # #### Example
83
83
  #
84
- # type = ShopifyCLI::Project.current_project_type
84
+ # ShopifyCLI::Project.write(
85
+ # @ctx,
86
+ # project_type: "node",
87
+ # organization_id: form_data.organization_id,
88
+ # )
85
89
  #
86
90
  def write(ctx, project_type:, organization_id:, **identifiers)
87
91
  require "yaml" # takes 20ms, so deferred as late as possible.
@@ -1,5 +1,5 @@
1
1
  module ShopifyCLI
2
- class ProjectCommands < Command
2
+ class ProjectCommand < Command
3
3
  def call(*)
4
4
  @ctx.puts(self.class.help)
5
5
  end
@@ -0,0 +1,64 @@
1
+ module ShopifyCLI
2
+ module ReportingConfigurationController
3
+ def self.enable_reporting(enabled)
4
+ ShopifyCLI::Config.set(
5
+ Constants::Config::Sections::Analytics::NAME,
6
+ Constants::Config::Sections::Analytics::Fields::ENABLED,
7
+ enabled
8
+ )
9
+ end
10
+
11
+ def self.reporting_prompted?
12
+ ShopifyCLI::Config.get_section(Constants::Config::Sections::Analytics::NAME).key?(
13
+ Constants::Config::Sections::Analytics::Fields::ENABLED
14
+ )
15
+ end
16
+
17
+ def self.reporting_enabled?
18
+ ShopifyCLI::Config.get_bool(
19
+ Constants::Config::Sections::Analytics::NAME,
20
+ Constants::Config::Sections::Analytics::Fields::ENABLED,
21
+ default: false
22
+ )
23
+ end
24
+
25
+ def self.check_or_prompt_report_automatically(source: :usage, prompt: true, context: ShopifyCLI::Context.new)
26
+ return false if ShopifyCLI::Environment.development? || ShopifyCLI::Environment.test?
27
+
28
+ # If the terminal is not interactive we can't prompt the user.
29
+ return false unless ShopifyCLI::Environment.interactive?
30
+
31
+ if reporting_prompted?
32
+ reporting_enabled?
33
+ elsif prompt
34
+ prompt_user(context: context, source: source)
35
+ else
36
+ false
37
+ end
38
+ end
39
+
40
+ def self.prompt_user(context:, source:)
41
+ enable_automatic_tracking = CLI::UI::Prompt.ask(
42
+ context.message("core.analytics.enable_prompt.#{source}.question")
43
+ ) do |handler|
44
+ handler.option(context.message("core.analytics.enable_prompt.#{source}.yes")) { |_| true }
45
+ handler.option(context.message("core.analytics.enable_prompt.#{source}.no")) { |_| false }
46
+ end
47
+
48
+ ShopifyCLI::Config.set(
49
+ Constants::Config::Sections::Analytics::NAME,
50
+ Constants::Config::Sections::Analytics::Fields::ENABLED,
51
+ enable_automatic_tracking
52
+ )
53
+
54
+ message = if enable_automatic_tracking
55
+ context.message("core.reporting.turned_on_message")
56
+ else
57
+ context.message("core.reporting.turned_off_message", ShopifyCLI::TOOL_NAME)
58
+ end
59
+ context.puts(message)
60
+
61
+ enable_automatic_tracking
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,25 @@
1
+ module ShopifyCLI
2
+ module Services
3
+ module App
4
+ class ConnectService < BaseService
5
+ attr_reader :app_type, :project, :context
6
+
7
+ def initialize(app_type:, project:, context:)
8
+ @app_type = app_type
9
+ @project = project
10
+ @context = context
11
+ super()
12
+ end
13
+
14
+ def call
15
+ unless project&.env.nil?
16
+ context.puts(context.message("core.app.connect.production_warning"))
17
+ end
18
+
19
+ app = ShopifyCLI::Connect.new(context).default_connect(app_type.to_s)
20
+ context.done(context.message("core.app.connect.connected", app))
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,153 @@
1
+ require "semantic/semantic"
2
+
3
+ module ShopifyCLI
4
+ module Services
5
+ module App
6
+ module Create
7
+ class NodeService < BaseService
8
+ attr_reader :context, :name, :organization_id, :store_domain, :type, :verbose
9
+
10
+ def initialize(name:, organization_id:, store_domain:, type:, verbose:, context:)
11
+ @name = name
12
+ @organization_id = organization_id
13
+ @store_domain = store_domain
14
+ @type = type
15
+ @verbose = verbose
16
+ @context = context
17
+ super()
18
+ end
19
+
20
+ def call
21
+ form = form_data({
22
+ name: name,
23
+ organization_id: organization_id,
24
+ shop_domain: store_domain,
25
+ type: type,
26
+ verbose: verbose,
27
+ })
28
+
29
+ check_node
30
+ check_npm
31
+ build(form.name)
32
+
33
+ ShopifyCLI::Project.write(
34
+ context,
35
+ project_type: "node",
36
+ organization_id: form.organization_id,
37
+ )
38
+
39
+ api_client = if ShopifyCLI::Environment.acceptance_test?
40
+ {
41
+ "apiKey" => "public_api_key",
42
+ "apiSecretKeys" => [
43
+ {
44
+ "secret" => "api_secret_key",
45
+ },
46
+ ],
47
+ }
48
+ else
49
+ ShopifyCLI::Tasks::CreateApiClient.call(
50
+ context,
51
+ org_id: form.organization_id,
52
+ title: form.name,
53
+ type: form.type,
54
+ )
55
+ end
56
+
57
+ ShopifyCLI::Resources::EnvFile.new(
58
+ api_key: api_client["apiKey"],
59
+ secret: api_client["apiSecretKeys"].first["secret"],
60
+ shop: form.shop_domain,
61
+ scopes: "write_products,write_customers,write_draft_orders",
62
+ ).write(context)
63
+
64
+ partners_url = ShopifyCLI::PartnersAPI.partners_url_for(form.organization_id, api_client["id"])
65
+
66
+ context.puts(context.message("apps.create.info.created", form.name, partners_url))
67
+ context.puts(context.message("apps.create.info.serve", form.name, ShopifyCLI::TOOL_NAME))
68
+ unless ShopifyCLI::Shopifolk.acting_as_shopify_organization?
69
+ context.puts(context.message("apps.create.info.install", partners_url, form.name))
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def form_data(form_options)
76
+ if ShopifyCLI::Environment.acceptance_test?
77
+ Struct.new(:name, :organization_id, :type, :shop_domain, keyword_init: true).new(
78
+ name: form_options[:name],
79
+ organization_id: form_options[:organization_id] || "123",
80
+ shop_domain: form_options[:shop_domain] || "test.shopify.io",
81
+ type: form_options[:type] || "public",
82
+ )
83
+ else
84
+ Node::Forms::Create.ask(context, [], form_options)
85
+ end
86
+ end
87
+
88
+ def check_node
89
+ cmd_path = context.which("node")
90
+ context.abort(context.message("core.app.create.node.error.node_required")) if cmd_path.nil?
91
+
92
+ version, stat = context.capture2e("node", "-v")
93
+ unless stat.success?
94
+ context.abort(context.message("core.app.create.node.error.node_version_failure"))
95
+ end
96
+
97
+ context.done(context.message("core.app.create.node.node_version", version))
98
+ end
99
+
100
+ def check_npm
101
+ cmd_path = context.which("npm")
102
+ context.abort(context.message("core.app.create.node.error.npm_required")) if cmd_path.nil?
103
+
104
+ version, stat = context.capture2e("npm", "-v")
105
+ context.abort(context.message("core.app.create.node.error.npm_version_failure")) unless stat.success?
106
+
107
+ context.done(context.message("core.app.create.node.npm_version", version))
108
+ end
109
+
110
+ def set_npm_config
111
+ # check available npmrc (either user or system) for production registry
112
+ registry, _ = context.capture2("npm config get @shopify:registry")
113
+ return if registry.include?("https://registry.yarnpkg.com")
114
+
115
+ # available npmrc doesn't have production registry =>
116
+ # set a project-based .npmrc
117
+ context.system(
118
+ "npm",
119
+ "--userconfig",
120
+ "./.npmrc",
121
+ "config",
122
+ "set",
123
+ "@shopify:registry",
124
+ "https://registry.yarnpkg.com",
125
+ chdir: context.root
126
+ )
127
+ end
128
+
129
+ def build(name)
130
+ ShopifyCLI::Git.clone("https://github.com/Shopify/shopify-app-node.git", name)
131
+
132
+ context.root = File.join(context.root, name)
133
+
134
+ set_npm_config
135
+ ShopifyCLI::JsDeps.install(context, verbose)
136
+
137
+ begin
138
+ context.rm_r(".git")
139
+ context.rm_r(".github")
140
+ context.rm(File.join("server", "handlers", "client.js"))
141
+ context.rename(
142
+ File.join("server", "handlers", "client.cli.js"),
143
+ File.join("server", "handlers", "client.js")
144
+ )
145
+ rescue Errno::ENOENT => e
146
+ context.debug(e)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,152 @@
1
+ require "semantic/semantic"
2
+
3
+ module ShopifyCLI
4
+ module Services
5
+ module App
6
+ module Create
7
+ class PHPService < BaseService
8
+ attr_reader :name, :organization_id, :store_domain, :type, :verbose, :context
9
+
10
+ def initialize(name:, organization_id:, store_domain:, type:, verbose:, context:)
11
+ @name = name
12
+ @organization_id = organization_id
13
+ @store_domain = store_domain
14
+ @type = type
15
+ @verbose = verbose
16
+ @context = context
17
+ super()
18
+ end
19
+
20
+ def call
21
+ form = PHP::Forms::Create.ask(context, [], {
22
+ name: name,
23
+ organization_id: organization_id,
24
+ shop_domain: store_domain,
25
+ type: type,
26
+ verbose: verbose,
27
+ })
28
+ return context.puts(self.class.help) if form.nil?
29
+
30
+ check_php
31
+ check_composer
32
+ check_npm
33
+ app_id = build(form)
34
+
35
+ ShopifyCLI::Project.write(
36
+ context,
37
+ project_type: "php",
38
+ organization_id: form.organization_id,
39
+ )
40
+
41
+ partners_url = ShopifyCLI::PartnersAPI.partners_url_for(form.organization_id, app_id)
42
+
43
+ context.puts(context.message("apps.create.info.created", form.name, partners_url))
44
+ context.puts(context.message("apps.create.info.serve", form.name, ShopifyCLI::TOOL_NAME))
45
+ unless ShopifyCLI::Shopifolk.acting_as_shopify_organization?
46
+ context.puts(context.message("apps.create.info.install", partners_url, form.name))
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def check_php
53
+ cmd_path = context.which("php")
54
+ context.abort(context.message("core.app.create.php.error.php_required")) if cmd_path.nil?
55
+
56
+ version, stat = context.capture2e("php", "-r", "echo phpversion();")
57
+ context.abort(context.message("core.app.create.php.error.php_version_failure")) unless stat.success?
58
+
59
+ if ::Semantic::Version.new(version) < ::Semantic::Version.new("7.3.0")
60
+ context.abort(context.message("core.app.create.php.error.php_version_too_low", "7.3"))
61
+ end
62
+
63
+ context.done(context.message("core.app.create.php.php_version", version))
64
+ end
65
+
66
+ def check_composer
67
+ cmd_path = context.which("composer")
68
+ context.abort(context.message("core.app.create.php.error.composer_required")) if cmd_path.nil?
69
+ end
70
+
71
+ def check_npm
72
+ cmd_path = context.which("npm")
73
+ context.abort(context.message("core.app.create.php.error.npm_required")) if cmd_path.nil?
74
+
75
+ version, stat = context.capture2e("npm", "-v")
76
+ context.abort(context.message("core.app.create.php.error.npm_version_failure")) unless stat.success?
77
+
78
+ context.done(context.message("core.app.create.php.npm_version", version))
79
+ end
80
+
81
+ def build(form)
82
+ ShopifyCLI::Git.clone("https://github.com/Shopify/shopify-app-php.git", form.name)
83
+
84
+ context.root = File.join(context.root, form.name)
85
+ context.chdir(context.root)
86
+
87
+ api_client = ShopifyCLI::Tasks::CreateApiClient.call(
88
+ context,
89
+ org_id: form.organization_id,
90
+ title: form.name,
91
+ type: form.type,
92
+ )
93
+
94
+ # Override the example settings with our own
95
+ context.cp(".env.example", ".env")
96
+
97
+ env_file = ShopifyCLI::Resources::EnvFile.read
98
+ env_file.api_key = api_client["apiKey"]
99
+ env_file.secret = api_client["apiSecretKeys"].first["secret"]
100
+ env_file.shop = form.shop_domain
101
+ env_file.host = "localhost"
102
+ env_file.scopes = "write_products,write_draft_orders,write_customers"
103
+ env_file.extra["DB_DATABASE"] = File.join(context.root, env_file.extra["DB_DATABASE"])
104
+ env_file.write(context)
105
+
106
+ ShopifyCLI::PHPDeps.install(context, verbose)
107
+
108
+ set_npm_config
109
+ ShopifyCLI::JsDeps.install(context, verbose)
110
+
111
+ title = context.message("core.app.create.php.app_setting_up")
112
+ success = context.message("core.app.create.php.app_set_up")
113
+ failure = context.message("core.app.create.php.error.app_setup")
114
+ CLI::UI::Frame.open(title, success_text: success, failure_text: failure) do
115
+ FileUtils.touch(env_file.extra["DB_DATABASE"])
116
+ context.system("php", "artisan", "key:generate")
117
+ context.system("php", "artisan", "migrate")
118
+ end
119
+
120
+ begin
121
+ context.rm_r(".git")
122
+ context.rm_r(".github")
123
+ rescue Errno::ENOENT => e
124
+ context.debug(e)
125
+ end
126
+
127
+ api_client["id"]
128
+ end
129
+
130
+ def set_npm_config
131
+ # check available npmrc (either user or system) for production registry
132
+ registry, _ = context.capture2("npm config get @shopify:registry")
133
+ return if registry.include?("https://registry.yarnpkg.com")
134
+
135
+ # available npmrc doesn't have production registry =>
136
+ # set a project-based .npmrc
137
+ context.system(
138
+ "npm",
139
+ "--userconfig",
140
+ "./.npmrc",
141
+ "config",
142
+ "set",
143
+ "@shopify:registry",
144
+ "https://registry.yarnpkg.com",
145
+ chdir: context.root
146
+ )
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end