shopify-cli 1.0.4 → 1.2.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +21 -1
  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/cli.rb +1 -0
  16. data/lib/project_types/extension/features/argo_config.rb +60 -0
  17. data/lib/project_types/extension/messages/messages.rb +3 -0
  18. data/lib/project_types/extension/models/type.rb +1 -0
  19. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +5 -2
  20. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  21. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  22. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  23. data/lib/project_types/node/commands/create.rb +4 -4
  24. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  25. data/lib/project_types/node/commands/generate/billing.rb +7 -5
  26. data/lib/project_types/node/commands/generate/page.rb +9 -5
  27. data/lib/project_types/node/commands/generate/webhook.rb +5 -1
  28. data/lib/project_types/node/commands/serve.rb +5 -5
  29. data/lib/project_types/node/messages/messages.rb +5 -1
  30. data/lib/project_types/rails/commands/create.rb +56 -5
  31. data/lib/project_types/rails/commands/generate.rb +1 -0
  32. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  33. data/lib/project_types/rails/commands/serve.rb +11 -7
  34. data/lib/project_types/rails/gem.rb +61 -6
  35. data/lib/project_types/rails/messages/messages.rb +32 -12
  36. data/lib/project_types/script/commands/create.rb +1 -5
  37. data/lib/project_types/script/commands/disable.rb +1 -2
  38. data/lib/project_types/script/commands/enable.rb +5 -5
  39. data/lib/project_types/script/commands/push.rb +1 -6
  40. data/lib/project_types/script/config/extension_points.yml +4 -4
  41. data/lib/project_types/script/errors.rb +8 -0
  42. data/lib/project_types/script/forms/create.rb +1 -1
  43. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  44. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +36 -1
  45. data/lib/project_types/script/layers/infrastructure/errors.rb +8 -0
  46. data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
  47. data/lib/project_types/script/messages/messages.rb +22 -48
  48. data/lib/project_types/script/ui/error_handler.rb +12 -0
  49. data/lib/rubygems_plugin.rb +18 -10
  50. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  51. data/lib/shopify-cli/command.rb +12 -6
  52. data/lib/shopify-cli/commands/connect.rb +7 -75
  53. data/lib/shopify-cli/commands/create.rb +1 -1
  54. data/lib/shopify-cli/commands/system.rb +21 -12
  55. data/lib/shopify-cli/context.rb +68 -0
  56. data/lib/shopify-cli/core/entry_point.rb +4 -1
  57. data/lib/shopify-cli/core/executor.rb +3 -5
  58. data/lib/shopify-cli/core/monorail.rb +1 -1
  59. data/lib/shopify-cli/db.rb +1 -1
  60. data/lib/shopify-cli/git.rb +1 -1
  61. data/lib/shopify-cli/heroku.rb +21 -5
  62. data/lib/shopify-cli/js_deps.rb +2 -2
  63. data/lib/shopify-cli/js_system.rb +2 -2
  64. data/lib/shopify-cli/messages/messages.rb +35 -25
  65. data/lib/shopify-cli/process_supervision.rb +60 -21
  66. data/lib/shopify-cli/project.rb +17 -9
  67. data/lib/shopify-cli/project_type.rb +3 -2
  68. data/lib/shopify-cli/sub_command.rb +1 -0
  69. data/lib/shopify-cli/task.rb +2 -2
  70. data/lib/shopify-cli/tasks.rb +11 -4
  71. data/lib/shopify-cli/tasks/ensure_env.rb +74 -17
  72. data/lib/shopify-cli/tunnel.rb +22 -7
  73. data/lib/shopify-cli/version.rb +1 -1
  74. data/lib/shopify_cli.rb +35 -9
  75. data/shopify-cli.gemspec +4 -1
  76. data/vendor/deps/cli-kit/REVISION +1 -1
  77. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  78. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  79. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  80. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  81. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  82. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  83. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  84. data/vendor/deps/cli-ui/REVISION +1 -1
  85. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  86. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  87. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  88. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  89. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  90. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  91. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  92. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  93. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  94. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  95. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  96. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  97. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  98. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  99. data/vendor/gen/lib/gen.rb +39 -0
  100. data/vendor/gen/lib/gen/commands.rb +18 -0
  101. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  102. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  103. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  104. data/vendor/gen/lib/gen/generator.rb +165 -0
  105. data/vendor/gen/template/.gitignore +2 -0
  106. data/vendor/gen/template/Gemfile +10 -0
  107. data/vendor/gen/template/README.md +1 -0
  108. data/vendor/gen/template/bin/testunit +23 -0
  109. data/vendor/gen/template/bin/update-deps +97 -0
  110. data/vendor/gen/template/dev-gems.yml +3 -0
  111. data/vendor/gen/template/dev-vendor.yml +4 -0
  112. data/vendor/gen/template/exe/__app__-gems +17 -0
  113. data/vendor/gen/template/exe/__app__-vendor +18 -0
  114. data/vendor/gen/template/lib/__app__.rb +33 -0
  115. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  116. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  117. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  118. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  119. data/vendor/gen/template/test/example_test.rb +17 -0
  120. data/vendor/gen/template/test/test_helper.rb +22 -0
  121. metadata +26 -4
  122. data/Vagrantfile +0 -17
  123. data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -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
 
@@ -16,23 +16,7 @@ module ShopifyCli
16
16
  already_connected_warning: "{{yellow:! This app appears to be already connected}}",
17
17
  connected: "{{v}} Project now connected to {{green:%s}}",
18
18
  project_type_select: "What type of project would you like to connect?",
19
- organization_select: "To which partner organization does this project belong?",
20
- app_select: "To which app does this project belong?",
21
- no_development_stores: <<~MESSAGE,
22
- No development stores available.
23
- Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
24
- MESSAGE
25
- development_store_select: "Which development store would you like to use?",
26
19
  cli_yml_saved: ".shopify-cli.yml saved to project root",
27
-
28
- no_apps: 'You have no apps to connect to, creating a new app.',
29
- app_name: "App name",
30
- app_type: {
31
- select: "What type of app are you building?",
32
- select_public: "Public: An app built for a wide merchant audience.",
33
- select_custom: "Custom: An app custom built for a single client.",
34
- selected: "App type {{green:%s}}",
35
- },
36
20
  },
37
21
 
38
22
  context: {
@@ -200,11 +184,14 @@ module ShopifyCli
200
184
  {{x}} You are not in a Shopify app project
201
185
  {{yellow:{{*}}}}{{reset: Run}}{{cyan: shopify create}}{{reset: to create your app}}
202
186
  MESSAGE
203
- cli_yaml: {
204
- not_hash: "{{x}} .shopify-cli.yml was not a proper YAML file. Expecting a hash.",
205
- invalid: "{{x}} %s contains invalid YAML: %s",
206
- not_found: "{{x}} %s not found",
207
- },
187
+ },
188
+ },
189
+
190
+ yaml: {
191
+ error: {
192
+ not_hash: "{{x}} %s was not a proper YAML file. Expecting a hash.",
193
+ invalid: "{{x}} %s contains invalid YAML: %s",
194
+ not_found: "{{x}} %s not found",
208
195
  },
209
196
  },
210
197
 
@@ -254,9 +241,21 @@ module ShopifyCli
254
241
 
255
242
  tasks: {
256
243
  ensure_env: {
257
- api_key_question: "What is your Shopify API key?",
258
- api_secret_key_question: "What is your Shopify API secret key?",
259
- development_store_question: "What is your development store URL? (Example: my-dev-store.myshopify.com)",
244
+ organization_select: "To which partner organization does this project belong?",
245
+ no_development_stores: <<~MESSAGE,
246
+ No development stores available.
247
+ Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
248
+ MESSAGE
249
+ development_store_select: "Which development store would you like to use?",
250
+ app_select: "To which app does this project belong?",
251
+ no_apps: 'You have no apps to connect to, creating a new app.',
252
+ app_name: "App name",
253
+ app_type: {
254
+ select: "What type of app are you building?",
255
+ select_public: "Public: An app built for a wide merchant audience.",
256
+ select_custom: "Custom: An app custom built for a single client.",
257
+ selected: "App type {{green:%s}}",
258
+ },
260
259
  },
261
260
  ensure_dev_store: {
262
261
  could_not_verify_store: "Couldn't verify your store %s",
@@ -293,6 +292,8 @@ module ShopifyCli
293
292
  error: {
294
293
  stop: "ngrok tunnel could not be stopped. Try running {{command:killall -9 ngrok}}",
295
294
  url_fetch_failure: "Unable to fetch external url",
295
+ prereq_command_required: "%1$s is required for installing ngrok. Please install %1$s using the appropriate"\
296
+ " package manager for your system.",
296
297
  },
297
298
 
298
299
  not_running: "{{green:x}} ngrok tunnel not running",
@@ -306,6 +307,7 @@ module ShopifyCli
306
307
  stopped: "{{green:x}} ngrok tunnel stopped",
307
308
  timed_out: "{{x}} ngrok tunnel has timed out, restarting ...",
308
309
  will_timeout: "{{*}} This tunnel will timeout in {{red:%s}}",
310
+ prereq_command_location: "%s @ %s",
309
311
  },
310
312
 
311
313
  version: {
@@ -318,7 +320,7 @@ module ShopifyCli
318
320
  warning: {
319
321
  development_version: <<~DEVELOPMENT,
320
322
  {{*}} {{yellow:You are running a development version of the CLI at:}}
321
- {{yellow:%s}}
323
+ {{yellow:%s}}
322
324
 
323
325
  DEVELOPMENT
324
326
 
@@ -329,6 +331,14 @@ module ShopifyCli
329
331
  {{underline:https://shopify.github.io/shopify-app-cli/migrate/}}
330
332
 
331
333
  MESSAGE
334
+
335
+ new_version: <<~MESSAGE,
336
+ {{*}} {{yellow:A new version of the Shopify App CLI is available! You have version %s and the latest version is %s.
337
+
338
+ To upgrade, follow the instructions for the package manager you’re using:
339
+ {{underline:https://shopify.github.io/shopify-app-cli/getting-started/upgrade/}}}}
340
+
341
+ MESSAGE
332
342
  },
333
343
  },
334
344
  }.freeze
@@ -5,13 +5,10 @@ module ShopifyCli
5
5
  # ProcessSupervision wraps a running process spawned by `exec` and keeps track
6
6
  # if its `pid` and keeps a log file for it as well
7
7
  class ProcessSupervision
8
- # is the directory where the pid and logfile are kept
9
- RUN_DIR = File.join(ShopifyCli::CACHE_DIR, 'sv')
10
-
11
8
  # a string or a symbol to identify this process by
12
9
  attr_reader :identifier
13
10
  # process ID for the running process
14
- attr_reader :pid
11
+ attr_accessor :pid
15
12
  # starttime of the process
16
13
  attr_reader :time
17
14
  # filepath to the pidfile for this process
@@ -20,6 +17,11 @@ module ShopifyCli
20
17
  attr_reader :log_path
21
18
 
22
19
  class << self
20
+ def run_dir
21
+ # is the directory where the pid and logfile are kept
22
+ File.join(ShopifyCli.cache_dir, 'sv')
23
+ end
24
+
23
25
  ##
24
26
  # Will find and create a new instance of ProcessSupervision for a running process
25
27
  # if it is currently running. It will return nil if the process is not running.
@@ -34,7 +36,7 @@ module ShopifyCli
34
36
  # will be nil if the process is not running.
35
37
  #
36
38
  def for_ident(identifier)
37
- pid, time = File.read(File.join(RUN_DIR, "#{identifier}.pid")).split(':')
39
+ pid, time = File.read(File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")).split(':')
38
40
  new(identifier, pid: Integer(pid), time: time)
39
41
  rescue Errno::ENOENT
40
42
  nil
@@ -56,15 +58,37 @@ module ShopifyCli
56
58
  #
57
59
  def start(identifier, args)
58
60
  return for_ident(identifier) if running?(identifier)
59
- fork do
60
- pid_file = new(identifier, pid: Process.pid)
61
+
62
+ # Windows doesn't support forking process without extra gems, so we resort to spawning a new child process -
63
+ # that means that it dies along with the original process if it is interrupted. On UNIX, we fork the process so
64
+ # that it doesn't have to be restarted on every run.
65
+ if Context.new.windows?
66
+ pid_file = new(identifier)
67
+
68
+ # Make sure the file exists and is empty, otherwise Windows fails
69
+ File.open(pid_file.log_path, 'w') {}
70
+ pid = Process.spawn(
71
+ *args,
72
+ out: pid_file.log_path,
73
+ err: pid_file.log_path,
74
+ in: Context.new.windows? ? "nul" : "/dev/null",
75
+ )
76
+ pid_file.pid = pid
61
77
  pid_file.write
62
- STDOUT.reopen(pid_file.log_path, "w")
63
- STDERR.reopen(pid_file.log_path, "w")
64
- STDIN.reopen("/dev/null", "r")
65
- Process.setsid
66
- exec(*args)
78
+
79
+ Process.detach(pid)
80
+ else
81
+ fork do
82
+ pid_file = new(identifier, pid: Process.pid)
83
+ pid_file.write
84
+ STDOUT.reopen(pid_file.log_path, "w")
85
+ STDERR.reopen(pid_file.log_path, "w")
86
+ STDIN.reopen("/dev/null", "r")
87
+ Process.setsid
88
+ exec(*args)
89
+ end
67
90
  end
91
+
68
92
  sleep(0.1)
69
93
  for_ident(identifier)
70
94
  end
@@ -104,24 +128,29 @@ module ShopifyCli
104
128
  end
105
129
  end
106
130
 
107
- def initialize(identifier, pid:, time: Time.now.strftime('%s')) # :nodoc:
131
+ def initialize(identifier, pid: nil, time: Time.now.strftime('%s')) # :nodoc:
108
132
  @identifier = identifier
109
133
  @pid = pid
110
134
  @time = time
111
- @pid_path = File.join(RUN_DIR, "#{identifier}.pid")
112
- @log_path = File.join(RUN_DIR, "#{identifier}.log")
135
+ FileUtils.mkdir_p(ShopifyCli::ProcessSupervision.run_dir)
136
+ @pid_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")
137
+ @log_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.log")
113
138
  end
114
139
 
115
140
  ##
116
141
  # will attempt to shutdown a running process
117
142
  #
143
+ # #### Parameters
144
+ #
145
+ # * `ctx` - the context of this command
146
+ #
118
147
  # #### Returns
119
148
  #
120
149
  # * `stopped` - [true, false]
121
150
  #
122
151
  def stop
123
- unlink
124
152
  kill_proc
153
+ unlink
125
154
  true
126
155
  rescue
127
156
  false
@@ -157,7 +186,11 @@ module ShopifyCli
157
186
  end
158
187
 
159
188
  def kill_proc
160
- kill(-pid) # process group
189
+ if Context.new.windows?
190
+ kill(pid)
191
+ else
192
+ kill(-pid) # process group
193
+ end
161
194
  rescue Errno::ESRCH
162
195
  begin
163
196
  kill(pid)
@@ -167,12 +200,18 @@ module ShopifyCli
167
200
  end
168
201
 
169
202
  def kill(id)
170
- Process.kill('TERM', id)
171
- 50.times do
172
- sleep 0.1
173
- break unless stat(id)
203
+ ctx = Context.new
204
+
205
+ # Windows does not handle SIGTERM, go straight to SIGKILL
206
+ unless ctx.windows?
207
+ Process.kill('TERM', id)
208
+ 50.times do
209
+ sleep 0.1
210
+ break unless stat(id)
211
+ end
174
212
  end
175
213
  Process.kill('KILL', id) if stat(id)
214
+ sleep(0.1) if ctx.windows? # Give Windows a second to actually close the process
176
215
  end
177
216
 
178
217
  def stat(id)
@@ -15,6 +15,10 @@ module ShopifyCli
15
15
  # will get an instance of the project that the user is currently operating
16
16
  # on. This is used for access to project resources.
17
17
  #
18
+ # #### Parameters
19
+ #
20
+ # * `force_reload` - whether to force a reload of the project files
21
+ #
18
22
  # #### Returns
19
23
  #
20
24
  # * `project` - a Project instance if the user is currently in the project.
@@ -29,8 +33,8 @@ module ShopifyCli
29
33
  #
30
34
  # project = ShopifyCli::Project.current
31
35
  #
32
- def current
33
- at(Dir.pwd)
36
+ def current(force_reload: false)
37
+ at(Dir.pwd, force_reload: force_reload)
34
38
  end
35
39
 
36
40
  ##
@@ -93,13 +97,17 @@ module ShopifyCli
93
97
 
94
98
  private
95
99
 
96
- def directory(dir)
100
+ def directory(dir, force_reload: false)
101
+ @dir = nil if force_reload
102
+
97
103
  @dir ||= Hash.new { |h, k| h[k] = __directory(k) }
98
104
  @dir[dir]
99
105
  end
100
106
 
101
- def at(dir)
102
- proj_dir = directory(dir)
107
+ def at(dir, force_reload: false)
108
+ @at = nil if force_reload
109
+
110
+ proj_dir = directory(dir, force_reload: force_reload)
103
111
  unless proj_dir
104
112
  raise(ShopifyCli::Abort, Context.message('core.project.error.not_in_project'))
105
113
  end
@@ -109,7 +117,7 @@ module ShopifyCli
109
117
 
110
118
  def __directory(curr)
111
119
  loop do
112
- return nil if curr == '/'
120
+ return nil if curr == '/' || /^[A-Z]:\/$/.match?(curr)
113
121
  file = File.join(curr, '.shopify-cli.yml')
114
122
  return curr if File.exist?(file)
115
123
  curr = File.dirname(curr)
@@ -158,7 +166,7 @@ module ShopifyCli
158
166
  @config ||= begin
159
167
  config = load_yaml_file('.shopify-cli.yml')
160
168
  unless config.is_a?(Hash)
161
- raise ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.not_hash')
169
+ raise ShopifyCli::Abort, Context.message('core.yaml.error.not_hash', '.shopify-cli.yml')
162
170
  end
163
171
 
164
172
  # The app_type key was deprecated in favour of project_type, so replace it
@@ -179,12 +187,12 @@ module ShopifyCli
179
187
  begin
180
188
  YAML.load_file(f)
181
189
  rescue Psych::SyntaxError => e
182
- raise(ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.invalid', relative_path, e.message))
190
+ raise(ShopifyCli::Abort, Context.message('core.yaml.error.invalid', relative_path, e.message))
183
191
  # rescue Errno::EACCES => e
184
192
  # TODO
185
193
  # Dev::Helpers::EaccesHandler.diagnose_and_raise(f, e, mode: :read)
186
194
  rescue Errno::ENOENT
187
- raise ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.not_found', f)
195
+ raise ShopifyCli::Abort, Context.message('core.yaml.error.not_found', f)
188
196
  end
189
197
  end
190
198
  end