shopify-cli 1.0.3 → 1.1.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +20 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +13 -13
  7. data/bin/load_shopify.rb +3 -1
  8. data/bin/shopify +2 -0
  9. data/docs/Gemfile.lock +23 -13
  10. data/docs/getting-started/index.md +3 -2
  11. data/docs/getting-started/install/index.md +55 -9
  12. data/docs/getting-started/uninstall/index.md +1 -1
  13. data/docs/getting-started/upgrade/index.md +8 -4
  14. data/ext/shopify-cli/extconf.rb +40 -20
  15. data/lib/project_types/extension/models/type.rb +1 -0
  16. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  17. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  18. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  19. data/lib/project_types/node/commands/create.rb +4 -4
  20. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  21. data/lib/project_types/node/commands/generate/billing.rb +7 -5
  22. data/lib/project_types/node/commands/generate/page.rb +9 -5
  23. data/lib/project_types/node/commands/generate/webhook.rb +5 -1
  24. data/lib/project_types/node/commands/serve.rb +5 -5
  25. data/lib/project_types/node/messages/messages.rb +5 -1
  26. data/lib/project_types/rails/commands/create.rb +56 -5
  27. data/lib/project_types/rails/commands/generate.rb +1 -0
  28. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  29. data/lib/project_types/rails/commands/serve.rb +11 -7
  30. data/lib/project_types/rails/gem.rb +61 -6
  31. data/lib/project_types/rails/messages/messages.rb +32 -12
  32. data/lib/project_types/script/commands/create.rb +1 -5
  33. data/lib/project_types/script/commands/disable.rb +1 -2
  34. data/lib/project_types/script/commands/enable.rb +5 -5
  35. data/lib/project_types/script/commands/push.rb +1 -6
  36. data/lib/project_types/script/config/extension_points.yml +4 -4
  37. data/lib/project_types/script/errors.rb +8 -0
  38. data/lib/project_types/script/forms/create.rb +1 -1
  39. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  40. data/lib/project_types/script/layers/infrastructure/errors.rb +1 -0
  41. data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
  42. data/lib/project_types/script/messages/messages.rb +19 -48
  43. data/lib/project_types/script/ui/error_handler.rb +4 -0
  44. data/lib/rubygems_plugin.rb +18 -10
  45. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  46. data/lib/shopify-cli/command.rb +12 -6
  47. data/lib/shopify-cli/commands/connect.rb +7 -75
  48. data/lib/shopify-cli/commands/create.rb +1 -1
  49. data/lib/shopify-cli/commands/system.rb +21 -12
  50. data/lib/shopify-cli/context.rb +68 -0
  51. data/lib/shopify-cli/core/entry_point.rb +4 -1
  52. data/lib/shopify-cli/core/executor.rb +3 -5
  53. data/lib/shopify-cli/core/monorail.rb +1 -1
  54. data/lib/shopify-cli/db.rb +1 -1
  55. data/lib/shopify-cli/git.rb +1 -1
  56. data/lib/shopify-cli/heroku.rb +21 -5
  57. data/lib/shopify-cli/js_deps.rb +2 -2
  58. data/lib/shopify-cli/js_system.rb +2 -2
  59. data/lib/shopify-cli/messages/messages.rb +27 -20
  60. data/lib/shopify-cli/process_supervision.rb +60 -21
  61. data/lib/shopify-cli/project.rb +14 -6
  62. data/lib/shopify-cli/project_type.rb +3 -2
  63. data/lib/shopify-cli/sub_command.rb +1 -0
  64. data/lib/shopify-cli/task.rb +2 -2
  65. data/lib/shopify-cli/tasks.rb +11 -4
  66. data/lib/shopify-cli/tasks/ensure_env.rb +74 -17
  67. data/lib/shopify-cli/tunnel.rb +22 -7
  68. data/lib/shopify-cli/version.rb +1 -1
  69. data/lib/shopify_cli.rb +35 -9
  70. data/shopify-cli.gemspec +4 -1
  71. data/vendor/deps/cli-kit/REVISION +1 -1
  72. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  73. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  74. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  75. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  76. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  77. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  78. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  79. data/vendor/deps/cli-ui/REVISION +1 -1
  80. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  81. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  82. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  83. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  84. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  85. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  86. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  87. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  88. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  89. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  90. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  91. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  92. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  93. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  94. data/vendor/gen/lib/gen.rb +39 -0
  95. data/vendor/gen/lib/gen/commands.rb +18 -0
  96. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  97. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  98. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  99. data/vendor/gen/lib/gen/generator.rb +165 -0
  100. data/vendor/gen/template/.gitignore +2 -0
  101. data/vendor/gen/template/Gemfile +10 -0
  102. data/vendor/gen/template/README.md +1 -0
  103. data/vendor/gen/template/bin/testunit +23 -0
  104. data/vendor/gen/template/bin/update-deps +97 -0
  105. data/vendor/gen/template/dev-gems.yml +3 -0
  106. data/vendor/gen/template/dev-vendor.yml +4 -0
  107. data/vendor/gen/template/exe/__app__-gems +17 -0
  108. data/vendor/gen/template/exe/__app__-vendor +18 -0
  109. data/vendor/gen/template/lib/__app__.rb +33 -0
  110. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  111. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  112. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  113. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  114. data/vendor/gen/template/test/example_test.rb +17 -0
  115. data/vendor/gen/template/test/test_helper.rb +22 -0
  116. metadata +25 -4
  117. data/Vagrantfile +0 -17
  118. data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -12,21 +12,14 @@ module ShopifyCli
12
12
  @ctx.puts prod_warning if [:rails, :node].include?(Project.current_project_type)
13
13
  end
14
14
 
15
- env_data = begin
16
- Resources::EnvFile.parse_external_env
17
- rescue Errno::ENOENT
18
- {}
19
- end
20
-
21
- org = fetch_org
22
- id = org['id']
23
- app = get_app(id, org['apps'])
24
- shop = get_shop(org['stores'], id)
25
-
26
- write_env(app, shop, env_data[:scopes], env_data[:extra])
27
- write_cli_yml(project_type, id) unless Project.has_current?
15
+ org = ShopifyCli::Tasks::EnsureEnv.call(@ctx, regenerate: true)
16
+ write_cli_yml(project_type, org['id']) unless Project.has_current?
17
+ api_key = Project.current(force_reload: true).env['api_key']
18
+ @ctx.puts(@ctx.message('core.connect.connected', get_app(org['apps'], api_key).first["title"]))
19
+ end
28
20
 
29
- @ctx.puts(@ctx.message('core.connect.connected', app['title']))
21
+ def get_app(apps, api_key)
22
+ apps.select { |app| app["apiKey"] == api_key }
30
23
  end
31
24
 
32
25
  def ask_project_type
@@ -37,67 +30,6 @@ module ShopifyCli
37
30
  end
38
31
  end
39
32
 
40
- def fetch_org
41
- orgs = PartnersAPI::Organizations.fetch_with_app(@ctx)
42
- org_id = if orgs.count == 1
43
- orgs.first["id"]
44
- else
45
- CLI::UI::Prompt.ask(@ctx.message('core.connect.organization_select')) do |handler|
46
- orgs.each do |org|
47
- handler.option(
48
- ctx.message('core.partners_api.org_name_and_id', org['businessName'], org['id'])
49
- ) { org["id"] }
50
- end
51
- end
52
- end
53
- org = orgs.find { |o| o["id"] == org_id }
54
- org
55
- end
56
-
57
- def get_app(org_id, apps)
58
- if apps.count == 1
59
- apps.first
60
- elsif apps.count == 0
61
- @ctx.puts(@ctx.message('core.connect.no_apps'))
62
- title = CLI::UI::Prompt.ask(@ctx.message('core.connect.app_name'))
63
- type = CLI::UI::Prompt.ask(@ctx.message('core.connect.app_type.select')) do |handler|
64
- handler.option(@ctx.message('core.connect.app_type.select_public')) { 'public' }
65
- handler.option(@ctx.message('core.connect.app_type.select_custom')) { 'custom' }
66
- end
67
- ShopifyCli::Tasks::CreateApiClient.call(@ctx, org_id: org_id, title: title, type: type)
68
- else
69
- CLI::UI::Prompt.ask(@ctx.message('core.connect.app_select')) do |handler|
70
- apps.each { |app| handler.option(app["title"]) { app } }
71
- end
72
- end
73
- end
74
-
75
- def get_shop(shops, id)
76
- if shops.count == 1
77
- shop = shops.first["shopDomain"]
78
- elsif shops.count == 0
79
- @ctx.puts(@ctx.message('core.connect.no_development_stores', id))
80
- else
81
- shop = CLI::UI::Prompt.ask(@ctx.message('core.connect.development_store_select')) do |handler|
82
- shops.each { |s| handler.option(s["shopName"]) { s["shopDomain"] } }
83
- end
84
- end
85
- shop
86
- end
87
-
88
- def write_env(app, shop, scopes, extra)
89
- scopes = 'write_products,write_customers,write_draft_orders' if scopes.nil?
90
- extra = {} if extra.nil?
91
-
92
- Resources::EnvFile.new(
93
- api_key: app["apiKey"],
94
- secret: app["apiSecretKeys"].first["secret"],
95
- shop: shop,
96
- scopes: scopes,
97
- extra: extra,
98
- ).write(@ctx)
99
- end
100
-
101
33
  def write_cli_yml(project_type, org_id)
102
34
  ShopifyCli::Project.write(
103
35
  @ctx,
@@ -32,7 +32,7 @@ module ShopifyCli
32
32
  end
33
33
 
34
34
  def self.help
35
- project_types = all_visible_type.map(&:project_type).join(" | ")
35
+ project_types = all_visible_type.map(&:project_type).sort.join(" | ")
36
36
  ShopifyCli::Context.message('core.create.help', ShopifyCli::TOOL_NAME, project_types)
37
37
  end
38
38
 
@@ -36,11 +36,13 @@ module ShopifyCli
36
36
  cli_constants_extra = %w(
37
37
  PROJECT_TYPES_DIR
38
38
  TEMP_DIR
39
- CACHE_DIR
40
- TOOL_CONFIG_PATH
41
- LOG_FILE
42
- DEBUG_LOG_FILE
43
39
  )
40
+ cli_path_methods = [
41
+ :cache_dir,
42
+ :tool_config_path,
43
+ :log_file,
44
+ :debug_log_file,
45
+ ]
44
46
 
45
47
  cli_constants += cli_constants_extra if show_all_details
46
48
 
@@ -48,6 +50,12 @@ module ShopifyCli
48
50
  cli_constants.each do |s|
49
51
  @ctx.puts(" " + @ctx.message('core.system.const', s, ShopifyCli.const_get(s.to_sym)) + "\n")
50
52
  end
53
+
54
+ if show_all_details
55
+ cli_path_methods.each do |m|
56
+ @ctx.puts(" " + @ctx.message('core.system.const', m.upcase, ShopifyCli.send(m)) + "\n")
57
+ end
58
+ end
51
59
  end
52
60
 
53
61
  def display_cli_ruby(_show_all_details)
@@ -60,13 +68,14 @@ module ShopifyCli
60
68
  end
61
69
 
62
70
  def display_utility_commands(_show_all_details)
63
- commands = %w(git curl tar unzip)
71
+ commands = %w(git curl tar)
64
72
 
65
73
  @ctx.puts("\n" + @ctx.message('core.system.command_header'))
66
74
  commands.each do |s|
67
- output, status = @ctx.capture2e('which', s)
68
- if status.success?
69
- @ctx.puts(" " + @ctx.message('core.system.command_with_path', s, output))
75
+ cmd_path = @ctx.which(s)
76
+
77
+ if !cmd_path.nil?
78
+ @ctx.puts(" " + @ctx.message('core.system.command_with_path', s, cmd_path))
70
79
  else
71
80
  @ctx.puts(" " + @ctx.message('core.system.command_not_found', s))
72
81
  end
@@ -74,7 +83,7 @@ module ShopifyCli
74
83
  end
75
84
 
76
85
  def display_ngrok
77
- ngrok_location = File.join(ShopifyCli::CACHE_DIR, 'ngrok')
86
+ ngrok_location = File.join(ShopifyCli.cache_dir, @ctx.windows? ? 'ngrok.exe' : 'ngrok')
78
87
  if File.exist?(ngrok_location)
79
88
  @ctx.puts(" " + @ctx.message('core.system.ngrok_available', ngrok_location))
80
89
  else
@@ -94,11 +103,11 @@ module ShopifyCli
94
103
  def display_project(project_type, commands)
95
104
  @ctx.puts("\n" + @ctx.message('core.system.project.header', project_type))
96
105
  commands.each do |s|
97
- output, status = @ctx.capture2e('which', s)
98
- if status.success?
106
+ cmd_path = @ctx.which(s)
107
+ if !cmd_path.nil?
99
108
  version_output, _ = @ctx.capture2e(s, '--version')
100
109
  version = version_output.match(/(\d+\.[^\s]+)/)[0]
101
- @ctx.puts(" " + @ctx.message('core.system.project.command_with_path', s, output.strip, version.strip))
110
+ @ctx.puts(" " + @ctx.message('core.system.project.command_with_path', s, cmd_path.strip, version.strip))
102
111
  else
103
112
  @ctx.puts(" " + @ctx.message('core.system.project.command_not_found', s))
104
113
  end
@@ -2,6 +2,8 @@
2
2
  require 'shopify_cli'
3
3
  require 'fileutils'
4
4
  require 'rbconfig'
5
+ require 'net/http'
6
+ require 'json'
5
7
 
6
8
  module ShopifyCli
7
9
  ##
@@ -11,6 +13,11 @@ module ShopifyCli
11
13
  # resoures.
12
14
  #
13
15
  class Context
16
+ GEM_LATEST_URI = URI.parse('https://rubygems.org/api/v1/versions/shopify-cli/latest.json')
17
+ VERSION_CHECK_SECTION = 'versioncheck'
18
+ LAST_CHECKED_AT_FIELD = 'last_checked_at'
19
+ VERSION_CHECK_INTERVAL = 86400
20
+
14
21
  class << self
15
22
  attr_reader :messages
16
23
 
@@ -56,6 +63,7 @@ module ShopifyCli
56
63
  host = uname
57
64
  return :mac if /darwin/.match(host)
58
65
  return :linux if /linux/.match(host)
66
+ return :windows if /mingw32/.match(host)
59
67
  end
60
68
 
61
69
  # will return true if the cli is running on an apple computer.
@@ -68,6 +76,11 @@ module ShopifyCli
68
76
  os == :linux
69
77
  end
70
78
 
79
+ # will return true if the cli is running on Windows
80
+ def windows?
81
+ os == :windows
82
+ end
83
+
71
84
  # will return true if the cli is being run from an installation, and not a
72
85
  # development instance. The gem installation will not have a 'test' directory.
73
86
  # See `#development?` for checking for development environment.
@@ -418,6 +431,45 @@ module ShopifyCli
418
431
  end
419
432
  end
420
433
 
434
+ # Checks if the given command exists in the system
435
+ #
436
+ # #### Parameters
437
+ # - `cmd`: The command to test
438
+ #
439
+ # #### Returns
440
+ # The path of the executable if it is found
441
+ #
442
+ # @todo This is currently a duplicate of CLI::Kit::System.which() - we should make that method public when we make
443
+ # Kit changes and make this a wrapper instead.
444
+ def which(cmd)
445
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
446
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
447
+ exts.each do |ext|
448
+ exe = File.join(File.expand_path(path), "#{cmd}#{ext}")
449
+ return exe if File.executable?(exe) && !File.directory?(exe)
450
+ end
451
+ end
452
+
453
+ nil
454
+ end
455
+
456
+ # Checks if there's a newer version of the CLI available and returns version string if
457
+ # this should be conveyed to the user (i.e., if it's been over 24 hours since last check)
458
+ #
459
+ # #### Parameters
460
+ #
461
+ # #### Returns
462
+ # - `version`: string of newer version available, IFF new version is available AND it's time to inform user,
463
+ # : nil otherwise
464
+ #
465
+ def new_version
466
+ if (time_of_last_check + VERSION_CHECK_INTERVAL) < (now = Time.now.to_i)
467
+ update_time_of_last_check(now)
468
+ latest_version = retrieve_latest_gem_version
469
+ latest_version unless latest_version == ShopifyCli::VERSION
470
+ end
471
+ end
472
+
421
473
  private
422
474
 
423
475
  def ctx_path(fname)
@@ -428,5 +480,21 @@ module ShopifyCli
428
480
  File.join(root, fname)
429
481
  end
430
482
  end
483
+
484
+ def retrieve_latest_gem_version
485
+ response = Net::HTTP.get_response(GEM_LATEST_URI)
486
+ latest = JSON.parse(response.body)
487
+ latest["version"]
488
+ rescue
489
+ nil
490
+ end
491
+
492
+ def time_of_last_check
493
+ (val = ShopifyCli::Config.get(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD)) ? val.to_i : 0
494
+ end
495
+
496
+ def update_time_of_last_check(time)
497
+ ShopifyCli::Config.set(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD, time)
498
+ end
431
499
  end
432
500
  end
@@ -28,6 +28,9 @@ module ShopifyCli
28
28
  ctx.puts(
29
29
  ctx.message('core.warning.development_version', File.join(ShopifyCli::ROOT, 'bin', ShopifyCli::TOOL_NAME))
30
30
  )
31
+ else
32
+ new_version = ctx.new_version
33
+ ctx.puts(ctx.message('core.warning.new_version', ShopifyCli::VERSION, new_version)) unless new_version.nil?
31
34
  end
32
35
 
33
36
  ProjectType.load_type(Project.current_project_type)
@@ -35,7 +38,7 @@ module ShopifyCli
35
38
  task_registry = ShopifyCli::Tasks::Registry
36
39
 
37
40
  command, command_name, args = ShopifyCli::Resolver.call(args)
38
- executor = ShopifyCli::Core::Executor.new(ctx, task_registry, log_file: ShopifyCli::LOG_FILE)
41
+ executor = ShopifyCli::Core::Executor.new(ctx, task_registry, log_file: ShopifyCli.log_file)
39
42
  ShopifyCli::Core::Monorail.log(command_name, args) do
40
43
  executor.call(command, command_name, args)
41
44
  end
@@ -3,16 +3,14 @@ require 'shopify_cli'
3
3
  module ShopifyCli
4
4
  module Core
5
5
  class Executor < CLI::Kit::Executor
6
- def initialize(ctx, task_registry, *args)
6
+ def initialize(ctx, task_registry, *args, **kwargs)
7
7
  @ctx = ctx || ShopifyCli::Context.new
8
8
  @task_registry = task_registry || ShopifyCli::Tasks::TaskRegistry.new
9
- super(*args)
9
+ super(*args, **kwargs)
10
10
  end
11
11
 
12
12
  def call(command, command_name, args)
13
- command.prerequisite_tasks.each do |task, _|
14
- @task_registry[task]&.call(@ctx)
15
- end
13
+ command.task_registry = @task_registry
16
14
  command.ctx = @ctx
17
15
  super
18
16
  end
@@ -99,7 +99,7 @@ module ShopifyCli
99
99
  success: err.nil?,
100
100
  error_message: err,
101
101
  uname: RbConfig::CONFIG["host"],
102
- cli_version: ShopifyCli::Git.sha(dir: ShopifyCli::ROOT),
102
+ cli_version: ShopifyCli::VERSION,
103
103
  ruby_version: RUBY_VERSION,
104
104
  }.tap do |payload|
105
105
  payload[:metadata] = JSON.dump(metadata) unless metadata.empty?
@@ -14,7 +14,7 @@ module ShopifyCli
14
14
 
15
15
  attr_reader :db # :nodoc:
16
16
 
17
- def initialize(path: File.join(ShopifyCli::CACHE_DIR, ".db.pstore")) # :nodoc:
17
+ def initialize(path: File.join(ShopifyCli.cache_dir, ".db.pstore")) # :nodoc:
18
18
  @db = PStore.new(path)
19
19
  end
20
20
 
@@ -125,13 +125,13 @@ module ShopifyCli
125
125
 
126
126
  success = Open3.popen3('git', *git_command, '--progress') do |_stdin, _stdout, stderr, thread|
127
127
  while (line = stderr.gets)
128
+ msg << line.chomp
128
129
  next unless line.strip.start_with?('Receiving objects:')
129
130
  percent = (line.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
130
131
  bar.tick(set_percent: percent)
131
132
  next
132
133
  end
133
134
 
134
- msg << stderr
135
135
  thread.value
136
136
  end.success?
137
137
 
@@ -3,7 +3,7 @@ module ShopifyCli
3
3
  DOWNLOAD_URLS = {
4
4
  linux: 'https://cli-assets.heroku.com/heroku-linux-x64.tar.gz',
5
5
  mac: 'https://cli-assets.heroku.com/heroku-darwin-x64.tar.gz',
6
- windows: 'https://cli-assets.heroku.com/heroku-win32-x64.tar.gz',
6
+ windows: 'https://cli-assets.heroku.com/heroku-x64.exe',
7
7
  }
8
8
 
9
9
  def initialize(ctx)
@@ -36,7 +36,7 @@ module ShopifyCli
36
36
  def download
37
37
  return if installed?
38
38
 
39
- result = @ctx.system('curl', '-o', download_path, DOWNLOAD_URLS[@ctx.os], chdir: ShopifyCli::CACHE_DIR)
39
+ result = @ctx.system('curl', '-o', download_path, DOWNLOAD_URLS[@ctx.os], chdir: ShopifyCli.cache_dir)
40
40
  @ctx.abort(@ctx.message('core.heroku.error.download')) unless result.success?
41
41
  @ctx.abort(@ctx.message('core.heroku.error.download')) unless File.exist?(download_path)
42
42
  end
@@ -44,7 +44,11 @@ module ShopifyCli
44
44
  def install
45
45
  return if installed?
46
46
 
47
- result = @ctx.system('tar', '-xf', download_path, chdir: ShopifyCli::CACHE_DIR)
47
+ result = if @ctx.windows?
48
+ @ctx.system("\"#{download_path}\"")
49
+ else
50
+ @ctx.system('tar', '-xf', download_path, chdir: ShopifyCli.cache_dir)
51
+ end
48
52
  @ctx.abort(@ctx.message('core.heroku.error.install')) unless result.success?
49
53
 
50
54
  @ctx.rm(download_path)
@@ -70,7 +74,7 @@ module ShopifyCli
70
74
  end
71
75
 
72
76
  def download_path
73
- File.join(ShopifyCli::CACHE_DIR, download_filename)
77
+ File.join(ShopifyCli.cache_dir, download_filename)
74
78
  end
75
79
 
76
80
  def git_remote
@@ -79,9 +83,21 @@ module ShopifyCli
79
83
  end
80
84
 
81
85
  def heroku_command
82
- local_path = File.join(ShopifyCli::CACHE_DIR, 'heroku', 'bin', 'heroku').to_s
86
+ local_path = File.join(ShopifyCli.cache_dir, 'heroku', 'bin', 'heroku').to_s
83
87
  if File.exist?(local_path)
84
88
  local_path
89
+ elsif @ctx.windows?
90
+ # Check if Heroku exists in the Windows registry and run it from there
91
+ require 'win32/registry'
92
+ begin
93
+ windows_path = Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\heroku') do |reg|
94
+ reg[''] # This reads the 'Default' registry key
95
+ end
96
+
97
+ File.join(windows_path, 'bin', 'heroku').to_s
98
+ rescue
99
+ 'heroku'
100
+ end
85
101
  else
86
102
  'heroku'
87
103
  end
@@ -69,7 +69,7 @@ module ShopifyCli
69
69
  deps = parse_dependencies
70
70
  errors = nil
71
71
 
72
- spinner_title = ctx.message('core.js_deps.installing_deps', deps.size)
72
+ spinner_title = ctx.message('core.js_deps.installing', @system.package_manager)
73
73
  success = CLI::UI::Spinner.spin(spinner_title, auto_debrief: false) do |spinner|
74
74
  _, errors, status = CLI::Kit::System.capture3(*cmd, env: @ctx.env, chdir: ctx.root)
75
75
  update_spinner_title_and_status(spinner, status, deps)
@@ -81,7 +81,7 @@ module ShopifyCli
81
81
 
82
82
  def update_spinner_title_and_status(spinner, status, deps)
83
83
  if status.success?
84
- spinner.update_title(ctx.message('core.js_deps.installed_deps', deps.size))
84
+ spinner.update_title(ctx.message('core.js_deps.installed', deps.size))
85
85
  else
86
86
  spinner.update_title(ctx.message('core.js_deps.error.install_spinner_error', deps.size))
87
87
  CLI::UI::Spinner::TASK_FAILED
@@ -64,8 +64,8 @@ module ShopifyCli
64
64
  #
65
65
  def yarn?
66
66
  @has_yarn ||= begin
67
- _, status = CLI::Kit::System.capture2('which', 'yarn')
68
- File.exist?(File.join(ctx.root, 'yarn.lock')) && status.success?
67
+ cmd_path = @ctx.which('yarn')
68
+ File.exist?(File.join(ctx.root, 'yarn.lock')) && !cmd_path.nil?
69
69
  end
70
70
  end
71
71