shopify-cli 2.7.1 → 2.7.2

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 (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