shopify-cli 2.7.1 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/Gemfile.lock +1 -1
  4. data/lib/project_types/extension/commands/build.rb +3 -8
  5. data/lib/project_types/extension/commands/create.rb +1 -3
  6. data/lib/project_types/extension/messages/messages.rb +0 -2
  7. data/lib/project_types/extension/models/development_server.rb +2 -2
  8. data/lib/project_types/rails/commands/create.rb +1 -3
  9. data/lib/project_types/script/cli.rb +5 -0
  10. data/lib/project_types/script/commands/create.rb +1 -3
  11. data/lib/project_types/script/commands/javy.rb +0 -2
  12. data/lib/project_types/script/commands/push.rb +2 -1
  13. data/lib/project_types/script/config/extension_points.yml +0 -26
  14. data/lib/project_types/script/forms/ask_app.rb +32 -0
  15. data/lib/project_types/script/forms/ask_org.rb +30 -0
  16. data/lib/project_types/script/forms/ask_script_uuid.rb +22 -0
  17. data/lib/project_types/script/forms/run_against_shopify_org.rb +14 -0
  18. data/lib/project_types/script/layers/application/build_script.rb +0 -1
  19. data/lib/project_types/script/layers/application/connect_app.rb +73 -0
  20. data/lib/project_types/script/layers/domain/script_project.rb +4 -0
  21. data/lib/project_types/script/layers/infrastructure/errors.rb +0 -1
  22. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -4
  23. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -4
  24. data/lib/project_types/script/messages/messages.rb +0 -2
  25. data/lib/project_types/script/ui/error_handler.rb +0 -5
  26. data/lib/project_types/theme/commands/pull.rb +3 -0
  27. data/lib/project_types/theme/commands/push.rb +6 -1
  28. data/lib/project_types/theme/commands/serve.rb +1 -1
  29. data/lib/project_types/theme/messages/messages.rb +9 -0
  30. data/lib/project_types/theme/ui/sync_progress_bar.rb +2 -2
  31. data/lib/shopify_cli/command/project_command.rb +20 -7
  32. data/lib/shopify_cli/commands/app/create/node.rb +1 -3
  33. data/lib/shopify_cli/commands/app/create/rails.rb +1 -3
  34. data/lib/shopify_cli/constants.rb +3 -0
  35. data/lib/shopify_cli/context.rb +9 -0
  36. data/lib/shopify_cli/environment.rb +4 -0
  37. data/lib/shopify_cli/identity_auth.rb +18 -0
  38. data/lib/shopify_cli/messages/messages.rb +1 -0
  39. data/lib/shopify_cli/partners_api.rb +1 -8
  40. data/lib/shopify_cli/services/app/serve/node_service.rb +1 -1
  41. data/lib/shopify_cli/services/app/serve/rails_service.rb +1 -1
  42. data/lib/shopify_cli/tasks/ensure_authenticated.rb +9 -3
  43. data/lib/shopify_cli/theme/dev_server.rb +4 -4
  44. data/lib/shopify_cli/theme/syncer/error_reporter.rb +45 -0
  45. data/lib/shopify_cli/theme/syncer/operation.rb +56 -0
  46. data/lib/shopify_cli/theme/syncer/standard_reporter.rb +32 -0
  47. data/lib/shopify_cli/theme/syncer.rb +40 -39
  48. data/lib/shopify_cli/theme/theme.rb +31 -19
  49. data/lib/shopify_cli/tunnel.rb +8 -10
  50. data/lib/shopify_cli/version.rb +1 -1
  51. metadata +10 -3
  52. data/lib/project_types/script/tasks/ensure_env.rb +0 -106
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6009a6f735f27532db922768483b5563cc1a89417742616d0712837f7a4c3f8a
4
- data.tar.gz: 501ee710f57e5ffc27f7f9abfbb23e155a55da8f67127bfe32031c46fa2df08e
3
+ metadata.gz: b15f9181fc2d774f3fcc0c7297881090097c32a873f5586a766a9f1af3ca4771
4
+ data.tar.gz: b05883edae91e131bbe30ea0fcf78fc7b7c31d775299ee37e7ce4b14b14f875a
5
5
  SHA512:
6
- metadata.gz: 783329de6e2b6481c6ebcd747284dcd5e3c81c4303bf82f1d9a22e2e5f9a81aeda51a211c0344636ec03ff17fa1e5aae492fd750540387c85de4204bab8f4327
7
- data.tar.gz: 6af49d1fff422d17362c2e05f68341fc530cd7849f7d375a39ea8cb5abcb5d825ed8a4f04d8f25cc9265c9b2660c57b028be280db23882d58506e7c184b0d4cc
6
+ metadata.gz: fd64941e6aee6553c078d9cb52c9ff97d04f2975d396943cb94b009e862ea14e2be44632534786288fdc71075bea47337d474a63a87d889393ecb159848c5958
7
+ data.tar.gz: 24086b852a37609e95cc6a3f3c639b4d7b32c90b3b8b3db8154dd840f86f72b13b9c09b060e3f6da3dfeaa905e5a0c93c31c607c7ba7d7ea4d0029b80a90025e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  From version 2.6.0, the sections in this file adhere to the [keep a changelog](https://keepachangelog.com/en/1.0.0/) specification.
2
- ## [Unreleased]
2
+ ## Version 2.7.2
3
+ ### Fixed
4
+ * [#1763](https://github.com/Shopify/shopify-cli/pull/1763): Fix: Tunnel --PORT parameter not working in Node.js app.
5
+ * [#1769](https://github.com/Shopify/shopify-cli/pull/1769): Fix `theme push --development --json` to output the proper exit code
6
+ * [#1766](https://github.com/Shopify/shopify-cli/pull/1766): Fix `theme serve` failing with the `--host` property
7
+ * [#1771](https://github.com/Shopify/shopify-cli/pull/1771): Fix `theme push --development --json` to output errors in the STDERR
8
+ * [#1778](https://github.com/Shopify/shopify-cli/pull/1778): Fix ngrok installation check on Windows
9
+ * [#1798](https://github.com/Shopify/shopify-cli/pull/1798): Add `--live` option to the `theme pull` and the `theme push` commands
10
+ * [#1788](https://github.com/Shopify/shopify-cli/pull/1788): Improve `theme serve` errors and add logs for successful operations
11
+ * [#1794](https://github.com/Shopify/shopify-cli/pull/1794): Fix bug where hidden subcommands appear in the help menu.
3
12
 
4
13
  ## Version 2.7.1
5
14
  ### Fixed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify-cli (2.7.1)
4
+ shopify-cli (2.7.2)
5
5
  bugsnag (~> 6.22)
6
6
  listen (~> 3.7.0)
7
7
  theme-check (~> 1.8.0)
@@ -24,21 +24,16 @@ module Extension
24
24
  private
25
25
 
26
26
  def run_new_flow(project)
27
- Tasks::RunExtensionCommand.new(
27
+ output = Tasks::RunExtensionCommand.new(
28
28
  type: project.specification_identifier.downcase,
29
29
  command: "build",
30
30
  config_file_name: specification_handler.server_config_file,
31
31
  context: @ctx,
32
32
  ).call
33
33
 
34
- @ctx.puts(@ctx.message("build.build_success_message"))
34
+ @ctx.puts(output)
35
35
  rescue => error
36
- if error.message.include?("no such file or directory")
37
- @ctx.abort(@ctx.message("build.directory_not_found"))
38
- else
39
- @ctx.debug(error)
40
- @ctx.abort(@ctx.message("build.build_failure_message"))
41
- end
36
+ raise ShopifyCLI::Abort, error.message
42
37
  end
43
38
 
44
39
  def run_legacy_flow
@@ -3,9 +3,7 @@
3
3
  module Extension
4
4
  class Command
5
5
  class Create < ShopifyCLI::Command::SubCommand
6
- unless ShopifyCLI::Environment.acceptance_test?
7
- prerequisite_task :ensure_authenticated
8
- end
6
+ prerequisite_task :ensure_authenticated
9
7
 
10
8
  options do |parser, flags|
11
9
  parser.on("--name=NAME") { |name| flags[:name] = name }
@@ -68,8 +68,6 @@ module Extension
68
68
  HELP
69
69
  frame_title: "Building extension with: %s…",
70
70
  build_failure_message: "Failed to build extension code.",
71
- build_success_message: "Build was successful!",
72
- directory_not_found: "Build directory not found.",
73
71
  },
74
72
  register: {
75
73
  help: <<~HELP,
@@ -33,8 +33,8 @@ module Extension
33
33
  end
34
34
 
35
35
  def build(server_config)
36
- _, error, status = CLI::Kit::System.capture3(executable, "build", "-", stdin_data: server_config.to_yaml)
37
- return if status.success?
36
+ output, error, status = CLI::Kit::System.capture3(executable, "build", "-", stdin_data: server_config.to_yaml)
37
+ return output if status.success?
38
38
  raise DevelopmentServerError, error
39
39
  end
40
40
 
@@ -2,9 +2,7 @@
2
2
  module Rails
3
3
  class Command
4
4
  class Create < ShopifyCLI::Command::AppSubCommand
5
- unless ShopifyCLI::Environment.acceptance_test?
6
- prerequisite_task :ensure_authenticated
7
- end
5
+ prerequisite_task :ensure_authenticated
8
6
 
9
7
  USER_AGENT_CODE = <<~USERAGENT
10
8
  module ShopifyAPI
@@ -19,6 +19,10 @@ module Script
19
19
 
20
20
  # define/autoload project specific Forms
21
21
  module Forms
22
+ autoload :AskOrg, Project.project_filepath("forms/ask_org")
23
+ autoload :AskApp, Project.project_filepath("forms/ask_app")
24
+ autoload :AskScriptUuid, Project.project_filepath("forms/ask_script_uuid")
25
+ autoload :RunAgainstShopifyOrg, Project.project_filepath("forms/run_against_shopify_org")
22
26
  autoload :Create, Project.project_filepath("forms/create")
23
27
  autoload :ScriptForm, Project.project_filepath("forms/script_form")
24
28
  end
@@ -30,6 +34,7 @@ module Script
30
34
  module Layers
31
35
  module Application
32
36
  autoload :BuildScript, Project.project_filepath("layers/application/build_script")
37
+ autoload :ConnectApp, Project.project_filepath("layers/application/connect_app")
33
38
  autoload :CreateScript, Project.project_filepath("layers/application/create_script")
34
39
  autoload :PushScript, Project.project_filepath("layers/application/push_script")
35
40
  autoload :ExtensionPoints, Project.project_filepath("layers/application/extension_points")
@@ -3,9 +3,7 @@
3
3
  module Script
4
4
  class Command
5
5
  class Create < ShopifyCLI::Command::SubCommand
6
- unless ShopifyCLI::Environment.acceptance_test?
7
- prerequisite_task :ensure_authenticated
8
- end
6
+ prerequisite_task :ensure_authenticated
9
7
 
10
8
  options do |parser, flags|
11
9
  parser.on("--name=NAME") { |name| flags[:name] = name }
@@ -7,8 +7,6 @@ module Script
7
7
  class Javy < ShopifyCLI::Command::SubCommand
8
8
  hidden_feature
9
9
 
10
- prerequisite_task ensure_project_type: :script
11
-
12
10
  options do |parser, flags|
13
11
  parser.on("--in=IN") { |in_file| flags[:in_file] = in_file }
14
12
  parser.on("--out=OUT") { |out_file| flags[:out_file] = out_file }
@@ -10,7 +10,8 @@ module Script
10
10
  end
11
11
 
12
12
  def call(_args, _name)
13
- fresh_env = Tasks::EnsureEnv.call(@ctx)
13
+ fresh_env = Layers::Application::ConnectApp.call(ctx: @ctx)
14
+
14
15
  force = options.flags.key?(:force) || !!fresh_env
15
16
 
16
17
  api_key = Layers::Infrastructure::ScriptProjectRepository.new(ctx: @ctx).get.api_key
@@ -1,29 +1,3 @@
1
- discount:
2
- deprecated: true
3
- libraries:
4
- assemblyscript:
5
- package: "@shopify/extension-point-as-discount"
6
- unit_limit_per_order:
7
- beta: true
8
- libraries:
9
- assemblyscript:
10
- package: "@shopify/extension-point-as-unit-limit-per-order"
11
- payment_filter:
12
- deprecated: true
13
- libraries:
14
- assemblyscript:
15
- package: "@shopify/extension-point-as-payment-filter"
16
- shipping_filter:
17
- deprecated: true
18
- libraries:
19
- assemblyscript:
20
- package: "@shopify/extension-point-as-shipping-filter"
21
- tax_filter:
22
- beta: true
23
- libraries:
24
- assemblyscript:
25
- repo: "https://github.com/Shopify/extension-points.git"
26
- package: "@shopify/extension-point-as-tax-filter"
27
1
  payment_methods:
28
2
  domain: 'checkout'
29
3
  libraries:
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskApp < ShopifyCLI::Form
6
+ attr_reader :app
7
+
8
+ def ask
9
+ apps = @xargs.fetch(:apps)
10
+
11
+ unless @xargs[:acting_as_shopify_organization]
12
+ apps = apps.select { |app| app["appType"] == "custom" }
13
+ end
14
+
15
+ raise Errors::NoExistingAppsError if apps.empty?
16
+
17
+ @app =
18
+ if apps.count > 1
19
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.app_select")) do |handler|
20
+ apps.each do |app|
21
+ handler.option(app["title"]) { app }
22
+ end
23
+ end
24
+ else
25
+ apps.first.tap do |app|
26
+ ctx.puts(ctx.message("script.application.ensure_env.app", app["title"]))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskOrg < ShopifyCLI::Form
6
+ attr_reader :org
7
+
8
+ BUSINESS_NAME = "businessName"
9
+ ID = "id"
10
+
11
+ def ask
12
+ orgs = @xargs
13
+ @org =
14
+ if orgs.count == 1
15
+ orgs.first.tap do |org|
16
+ ctx.puts(ctx.message("script.application.ensure_env.organization", org[BUSINESS_NAME], org[ID]))
17
+ end
18
+ elsif orgs.count > 0
19
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.organization_select")) do |handler|
20
+ orgs.each do |org|
21
+ handler.option("#{org[BUSINESS_NAME]} (#{org[ID]})") { org }
22
+ end
23
+ end
24
+ else
25
+ raise Errors::NoExistingOrganizationsError
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class AskScriptUuid < ShopifyCLI::Form
6
+ attr_reader :uuid
7
+ def ask
8
+ scripts = @xargs
9
+
10
+ return if scripts.empty? ||
11
+ !CLI::UI::Prompt.confirm(ctx.message("script.application.ensure_env.ask_connect_to_existing_script"))
12
+
13
+ @uuid =
14
+ CLI::UI::Prompt.ask(ctx.message("script.application.ensure_env.ask_which_script_to_connect_to")) do |handler|
15
+ scripts.each do |script|
16
+ handler.option("#{script["title"]} (#{script["uuid"]})") { script["uuid"] }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Forms
5
+ class RunAgainstShopifyOrg < ShopifyCLI::Form
6
+ attr_reader :response
7
+ def ask
8
+ @ctx.puts(@ctx.message("core.tasks.select_org_and_shop.identified_as_shopify"))
9
+ message = @ctx.message("core.tasks.select_org_and_shop.first_party")
10
+ @response = CLI::UI::Prompt.confirm(message, default: false)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -23,7 +23,6 @@ module Script
23
23
  ctx.puts("\n{{red:#{e.message}}}")
24
24
  end
25
25
  errors = [
26
- Infrastructure::Errors::InvalidBuildScriptError,
27
26
  Infrastructure::Errors::BuildScriptNotFoundError,
28
27
  Infrastructure::Errors::WebAssemblyBinaryNotFoundError,
29
28
  ]
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli"
4
+
5
+ module Script
6
+ module Layers
7
+ module Application
8
+ class ConnectApp
9
+ class << self
10
+ def call(ctx:)
11
+ script_project_repo = Layers::Infrastructure::ScriptProjectRepository.new(ctx: ctx)
12
+ script_project = script_project_repo.get
13
+ return false if script_project.env_valid?
14
+
15
+ if ShopifyCLI::Shopifolk.check && Forms::RunAgainstShopifyOrg.ask(ctx, nil, nil).response
16
+ ShopifyCLI::Shopifolk.act_as_shopify_organization
17
+ end
18
+
19
+ org =
20
+ if partner_proxy_bypass
21
+ stubbed_org
22
+ else
23
+ orgs = ShopifyCLI::PartnersAPI::Organizations.fetch_with_app(ctx)
24
+ Forms::AskOrg.ask(ctx, orgs, nil).org
25
+ end
26
+
27
+ app = Forms::AskApp.ask(
28
+ ctx,
29
+ {
30
+ apps: org["apps"],
31
+ acting_as_shopify_organization: ShopifyCLI::Shopifolk.acting_as_shopify_organization?,
32
+ },
33
+ nil
34
+ ).app
35
+
36
+ script_service = Layers::Infrastructure::ServiceLocator.script_service(ctx: ctx, api_key: app["apiKey"])
37
+ extension_point_type = script_project.extension_point_type
38
+ scripts = script_service.get_app_scripts(extension_point_type: extension_point_type)
39
+
40
+ uuid = Forms::AskScriptUuid.ask(ctx, scripts, nil).uuid
41
+
42
+ script_project_repo.create_env(
43
+ api_key: app["apiKey"],
44
+ secret: app["apiSecretKeys"].first["secret"],
45
+ uuid: uuid
46
+ )
47
+
48
+ true
49
+ end
50
+
51
+ private
52
+
53
+ def partner_proxy_bypass
54
+ !ENV["BYPASS_PARTNERS_PROXY"].nil?
55
+ end
56
+
57
+ def stubbed_org
58
+ {
59
+ "apps" => [
60
+ {
61
+ "appType" => "custom",
62
+ "apiKey" => "stubbed-api-key",
63
+ "apiSecretKeys" => [{ "secret" => "stubbed-api-secret" }],
64
+ "title" => "Fake App (Not connected to Partners)",
65
+ },
66
+ ],
67
+ }
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -43,6 +43,10 @@ module Script
43
43
  !raw_uuid.nil?
44
44
  end
45
45
 
46
+ def env_valid?
47
+ api_key && api_secret && uuid_defined?
48
+ end
49
+
46
50
  private
47
51
 
48
52
  def raw_uuid
@@ -109,7 +109,6 @@ module Script
109
109
  class ScriptProjectAlreadyExistsError < ScriptProjectError; end
110
110
  class TaskRunnerNotFoundError < ScriptProjectError; end
111
111
  class BuildScriptNotFoundError < ScriptProjectError; end
112
- class InvalidBuildScriptError < ScriptProjectError; end
113
112
 
114
113
  class WebAssemblyBinaryNotFoundError < ScriptProjectError
115
114
  def initialize
@@ -98,10 +98,6 @@ module Script
98
98
 
99
99
  raise Errors::BuildScriptNotFoundError,
100
100
  "Build script not found" if build_script.nil?
101
-
102
- unless build_script.start_with?("shopify-scripts")
103
- raise Errors::InvalidBuildScriptError, "Invalid build script"
104
- end
105
101
  end
106
102
 
107
103
  def bytecode
@@ -100,10 +100,6 @@ module Script
100
100
 
101
101
  raise Errors::BuildScriptNotFoundError,
102
102
  "Build script not found" if build_script.nil?
103
-
104
- unless build_script.start_with?("javy")
105
- raise Errors::InvalidBuildScriptError, "Invalid build script"
106
- end
107
103
  end
108
104
 
109
105
  def bytecode
@@ -115,8 +115,6 @@ module Script
115
115
  script_repush_cause: "A version of this script already exists on the app.",
116
116
  script_repush_help: "Use {{cyan:--force}} to replace the existing script.",
117
117
 
118
- invalid_build_script: "The root package.json contains an invalid build command that " \
119
- "is needed to compile your script to WebAssembly.",
120
118
  build_script_not_found: "The root package.json is missing the build command that " \
121
119
  "is needed to compile your script to WebAssembly.",
122
120
  # rubocop:disable Layout/LineLength
@@ -201,11 +201,6 @@ module Script
201
201
  cause_of_error: ShopifyCLI::Context.message("script.error.build_script_not_found"),
202
202
  help_suggestion: ShopifyCLI::Context.message("script.error.build_script_suggestion"),
203
203
  }
204
- when Layers::Infrastructure::Errors::InvalidBuildScriptError
205
- {
206
- cause_of_error: ShopifyCLI::Context.message("script.error.invalid_build_script"),
207
- help_suggestion: ShopifyCLI::Context.message("script.error.build_script_suggestion"),
208
- }
209
204
  when Layers::Infrastructure::Errors::WebAssemblyBinaryNotFoundError
210
205
  {
211
206
  cause_of_error: ShopifyCLI::Context.message("script.error.web_assembly_binary_not_found"),
@@ -9,6 +9,7 @@ module Theme
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 }
12
+ parser.on("-l", "--live") { flags[:live] = true }
12
13
  parser.on("-x", "--ignore=PATTERN") do |pattern|
13
14
  flags[:ignores] ||= []
14
15
  flags[:ignores] << pattern
@@ -21,6 +22,8 @@ module Theme
21
22
 
22
23
  theme = if (theme_id = options.flags[:theme_id])
23
24
  ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
25
+ elsif options.flags[:live]
26
+ ShopifyCLI::Theme::Theme.live(@ctx, root: root)
24
27
  else
25
28
  form = Forms::Select.ask(
26
29
  @ctx,
@@ -10,6 +10,7 @@ module Theme
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 }
13
+ parser.on("-l", "--live") { flags[:live] = true }
13
14
  parser.on("-d", "--development") { flags[:development] = true }
14
15
  parser.on("-u", "--unpublished") { flags[:unpublished] = true }
15
16
  parser.on("-j", "--json") { flags[:json] = true }
@@ -27,6 +28,8 @@ module Theme
27
28
 
28
29
  theme = if (theme_id = options.flags[:theme_id])
29
30
  ShopifyCLI::Theme::Theme.new(@ctx, root: root, id: theme_id)
31
+ elsif options.flags[:live]
32
+ ShopifyCLI::Theme::Theme.live(@ctx, root: root)
30
33
  elsif options.flags[:development]
31
34
  theme = ShopifyCLI::Theme::DevelopmentTheme.new(@ctx, root: root)
32
35
  theme.ensure_exists!
@@ -47,7 +50,8 @@ module Theme
47
50
  form.theme
48
51
  end
49
52
 
50
- if theme.live? && !options.flags[:allow_live]
53
+ is_confirm_required = !options.flags[:allow_live] && !options.flags[:live]
54
+ if theme.live? && is_confirm_required
51
55
  return unless CLI::UI::Prompt.confirm(@ctx.message("theme.push.live"))
52
56
  end
53
57
 
@@ -72,6 +76,7 @@ module Theme
72
76
  @ctx.done(@ctx.message("theme.push.done", theme.preview_url, theme.editor_url))
73
77
  end
74
78
  end
79
+ raise ShopifyCLI::AbortSilent if syncer.has_any_error?
75
80
  rescue ShopifyCLI::API::APIRequestNotFoundError
76
81
  @ctx.abort(@ctx.message("theme.push.theme_not_found", theme.id))
77
82
  ensure
@@ -15,7 +15,7 @@ module Theme
15
15
  def call(*)
16
16
  flags = options.flags.dup
17
17
  host = flags[:host] || DEFAULT_HTTP_HOST
18
- ShopifyCLI::Theme::DevServer.start(@ctx, ".", http_bind: host, **flags) do |syncer|
18
+ ShopifyCLI::Theme::DevServer.start(@ctx, ".", host: host, **flags) do |syncer|
19
19
  UI::SyncProgressBar.new(syncer).progress(:upload_theme!, delay_low_priority_files: true)
20
20
  end
21
21
  rescue ShopifyCLI::Theme::DevServer::AddressBindingError
@@ -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.
@@ -99,6 +100,13 @@ module Theme
99
100
  viewing_theme: "Viewing theme…",
100
101
  syncing_theme: "Syncing theme #%s on %s",
101
102
  open_fail: "Couldn't open the theme",
103
+ operation: {
104
+ status: {
105
+ error: "ERROR",
106
+ synced: "Synced",
107
+ fixed: "Fixed",
108
+ },
109
+ },
102
110
  error: {
103
111
  address_binding_error: "Couldn't bind to localhost."\
104
112
  " To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
@@ -181,6 +189,7 @@ module Theme
181
189
 
182
190
  Options:
183
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.
184
193
  {{command:-n, --nodelete}} Runs the pull command without deleting local files.
185
194
 
186
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
@@ -5,13 +5,26 @@ module ShopifyCLI
5
5
  @ctx.puts(self.class.help)
6
6
  end
7
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
- )
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
15
28
  end
16
29
  end
17
30
  end
@@ -3,9 +3,7 @@ module ShopifyCLI
3
3
  class App
4
4
  class Create
5
5
  class Node < ShopifyCLI::Command::AppSubCommand
6
- unless ShopifyCLI::Environment.acceptance_test?
7
- prerequisite_task :ensure_authenticated
8
- end
6
+ prerequisite_task :ensure_authenticated
9
7
 
10
8
  options do |parser, flags|
11
9
  parser.on("--name=NAME") { |t| flags[:name] = t }
@@ -3,9 +3,7 @@ module ShopifyCLI
3
3
  class App
4
4
  class Create
5
5
  class Rails < ShopifyCLI::Command::AppSubCommand
6
- unless ShopifyCLI::Environment.acceptance_test?
7
- prerequisite_task :ensure_authenticated
8
- end
6
+ prerequisite_task :ensure_authenticated
9
7
 
10
8
  options do |parser, flags|
11
9
  parser.on("--name=NAME") { |t| flags[:name] = t }
@@ -46,6 +46,9 @@ module ShopifyCLI
46
46
  ACCEPTANCE_TEST = "SHOPIFY_CLI_ACCEPTANCE_TEST"
47
47
  DEVELOPMENT = "SHOPIFY_CLI_DEVELOPMENT"
48
48
 
49
+ # Authentication
50
+ AUTH_TOKEN = "SHOPIFY_CLI_AUTH_TOKEN"
51
+
49
52
  # Monorail
50
53
  MONORAIL_REAL_EVENTS = "MONORAIL_REAL_EVENTS"
51
54
  end
@@ -357,6 +357,15 @@ module ShopifyCLI
357
357
  Kernel.puts(CLI::UI.fmt(*args))
358
358
  end
359
359
 
360
+ # a wrapper around $stderr.puts to allow for easy formatting
361
+ #
362
+ # #### Parameters
363
+ # * `text` - a string message to output
364
+ #
365
+ def error(text)
366
+ $stderr.puts(CLI::UI.fmt(text))
367
+ end
368
+
360
369
  # a wrapper around Kernel.warn to allow for easy formatting
361
370
  #
362
371
  # #### Parameters