shopify-cli 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +13 -13
  6. data/bin/load_shopify.rb +3 -1
  7. data/bin/shopify +2 -0
  8. data/docs/Gemfile.lock +23 -13
  9. data/docs/getting-started/install/index.md +37 -1
  10. data/docs/getting-started/migrate/index.md +34 -1
  11. data/ext/shopify-cli/extconf.rb +40 -20
  12. data/lib/project_types/extension/cli.rb +1 -1
  13. data/lib/project_types/extension/commands/build.rb +1 -1
  14. data/lib/project_types/extension/models/type.rb +1 -0
  15. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  16. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  17. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  18. data/lib/project_types/node/commands/create.rb +4 -4
  19. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  20. data/lib/project_types/node/commands/generate/billing.rb +6 -5
  21. data/lib/project_types/node/commands/generate/page.rb +8 -5
  22. data/lib/project_types/node/commands/generate/webhook.rb +4 -1
  23. data/lib/project_types/node/messages/messages.rb +3 -2
  24. data/lib/project_types/rails/cli.rb +0 -1
  25. data/lib/project_types/rails/commands/create.rb +52 -4
  26. data/lib/project_types/rails/commands/generate.rb +1 -0
  27. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  28. data/lib/project_types/rails/commands/serve.rb +6 -2
  29. data/lib/project_types/rails/gem.rb +61 -6
  30. data/lib/project_types/rails/messages/messages.rb +29 -13
  31. data/lib/project_types/script/cli.rb +2 -3
  32. data/lib/project_types/script/commands/create.rb +5 -9
  33. data/lib/project_types/script/commands/disable.rb +4 -15
  34. data/lib/project_types/script/commands/enable.rb +37 -13
  35. data/lib/project_types/script/commands/push.rb +8 -13
  36. data/lib/project_types/script/config/extension_points.yml +9 -3
  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/application/create_script.rb +7 -6
  40. data/lib/project_types/script/layers/application/disable_script.rb +9 -7
  41. data/lib/project_types/script/layers/application/enable_script.rb +11 -9
  42. data/lib/project_types/script/layers/application/push_script.rb +6 -4
  43. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  44. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +2 -2
  45. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +2 -2
  46. data/lib/project_types/script/layers/infrastructure/errors.rb +2 -0
  47. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -1
  48. data/lib/project_types/script/layers/infrastructure/script_repository.rb +1 -1
  49. data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
  50. data/lib/project_types/script/messages/messages.rb +25 -31
  51. data/lib/project_types/script/script_project.rb +8 -4
  52. data/lib/project_types/script/templates/ts/as-pect.config.js +6 -0
  53. data/lib/project_types/script/ui/error_handler.rb +8 -0
  54. data/lib/project_types/script/ui/printing_spinner.rb +75 -0
  55. data/lib/rubygems_plugin.rb +18 -10
  56. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  57. data/lib/shopify-cli/admin_api/schema.rb +20 -8
  58. data/lib/shopify-cli/command.rb +14 -11
  59. data/lib/shopify-cli/commands.rb +1 -0
  60. data/lib/shopify-cli/commands/config.rb +44 -0
  61. data/lib/shopify-cli/commands/connect.rb +8 -69
  62. data/lib/shopify-cli/commands/create.rb +2 -2
  63. data/lib/shopify-cli/commands/help.rb +1 -1
  64. data/lib/shopify-cli/commands/system.rb +22 -13
  65. data/lib/shopify-cli/context.rb +38 -1
  66. data/lib/shopify-cli/core.rb +0 -1
  67. data/lib/shopify-cli/core/entry_point.rb +1 -1
  68. data/lib/shopify-cli/core/executor.rb +3 -5
  69. data/lib/shopify-cli/core/monorail.rb +1 -1
  70. data/lib/shopify-cli/db.rb +1 -1
  71. data/lib/shopify-cli/feature.rb +97 -0
  72. data/lib/shopify-cli/heroku.rb +21 -5
  73. data/lib/shopify-cli/js_deps.rb +2 -2
  74. data/lib/shopify-cli/js_system.rb +2 -2
  75. data/lib/shopify-cli/messages/messages.rb +37 -12
  76. data/lib/shopify-cli/partners_api/organizations.rb +7 -7
  77. data/lib/shopify-cli/process_supervision.rb +60 -21
  78. data/lib/shopify-cli/project.rb +14 -6
  79. data/lib/shopify-cli/project_type.rb +5 -7
  80. data/lib/shopify-cli/sub_command.rb +1 -0
  81. data/lib/shopify-cli/task.rb +2 -2
  82. data/lib/shopify-cli/tasks.rb +11 -4
  83. data/lib/shopify-cli/tasks/ensure_env.rb +72 -16
  84. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +4 -3
  85. data/lib/shopify-cli/tunnel.rb +44 -14
  86. data/lib/shopify-cli/version.rb +1 -1
  87. data/lib/shopify_cli.rb +36 -9
  88. data/shopify-cli.gemspec +4 -1
  89. data/vendor/deps/cli-kit/REVISION +1 -1
  90. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  91. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  92. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  93. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  94. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  95. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  96. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  97. data/vendor/deps/cli-ui/REVISION +1 -1
  98. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  99. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  100. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  101. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  102. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  103. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  104. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  105. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  106. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  107. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  108. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  109. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  110. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  111. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  112. data/vendor/gen/lib/gen.rb +39 -0
  113. data/vendor/gen/lib/gen/commands.rb +18 -0
  114. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  115. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  116. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  117. data/vendor/gen/lib/gen/generator.rb +165 -0
  118. data/vendor/gen/template/.gitignore +2 -0
  119. data/vendor/gen/template/Gemfile +10 -0
  120. data/vendor/gen/template/README.md +1 -0
  121. data/vendor/gen/template/bin/testunit +23 -0
  122. data/vendor/gen/template/bin/update-deps +97 -0
  123. data/vendor/gen/template/dev-gems.yml +3 -0
  124. data/vendor/gen/template/dev-vendor.yml +4 -0
  125. data/vendor/gen/template/exe/__app__-gems +17 -0
  126. data/vendor/gen/template/exe/__app__-vendor +18 -0
  127. data/vendor/gen/template/lib/__app__.rb +33 -0
  128. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  129. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  130. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  131. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  132. data/vendor/gen/template/test/example_test.rb +17 -0
  133. data/vendor/gen/template/test/test_helper.rb +22 -0
  134. metadata +28 -6
  135. data/Vagrantfile +0 -17
  136. data/lib/project_types/script/forms/enable.rb +0 -24
  137. data/lib/project_types/script/forms/push.rb +0 -19
  138. data/lib/project_types/script/forms/script_form.rb +0 -66
@@ -8,6 +8,7 @@ module ShopifyCli
8
8
  cmd = new(@ctx)
9
9
  args = cmd.options.parse(@_options, args[1..-1] || [])
10
10
  return call_help(parent_command, command_name) if cmd.options.help
11
+ run_prerequisites
11
12
  cmd.call(args, command_name)
12
13
  end
13
14
  end
@@ -2,9 +2,9 @@ require 'shopify_cli'
2
2
 
3
3
  module ShopifyCli
4
4
  class Task
5
- def self.call(*args)
5
+ def self.call(*args, **kwargs)
6
6
  task = new
7
- task.call(*args)
7
+ task.call(*args, **kwargs)
8
8
  end
9
9
  end
10
10
  end
@@ -12,15 +12,22 @@ module ShopifyCli
12
12
  end
13
13
 
14
14
  def [](name)
15
- @tasks[name]
15
+ class_or_proc = @tasks[name]
16
+ if class_or_proc.is_a?(Class)
17
+ class_or_proc
18
+ elsif class_or_proc.respond_to?(:call)
19
+ class_or_proc.call
20
+ else
21
+ class_or_proc
22
+ end
16
23
  end
17
24
  end
18
25
 
19
26
  Registry = TaskRegistry.new
20
27
 
21
- def self.register(task, name, path)
22
- autoload(task, path)
23
- Registry.add(const_get(task), name)
28
+ def self.register(task, name, path = nil)
29
+ autoload(task, path) if path
30
+ Registry.add(-> () { const_get(task) }, name)
24
31
  end
25
32
 
26
33
  register :CreateApiClient, :create_api_client, 'shopify-cli/tasks/create_api_client'
@@ -3,28 +3,84 @@ require 'shopify_cli'
3
3
  module ShopifyCli
4
4
  module Tasks
5
5
  class EnsureEnv < ShopifyCli::Task
6
- def call(ctx)
6
+ def call(ctx, regenerate: false, required: [:api_key, :secret])
7
7
  @ctx = ctx
8
- Resources::EnvFile.read(ctx.root)
9
- rescue Errno::ENOENT
10
- ask
8
+ env_data =
9
+ begin
10
+ Resources::EnvFile.parse_external_env
11
+ rescue Errno::ENOENT
12
+ {}
13
+ end
14
+
15
+ return {} if !regenerate && required.all? { |property| env_data[property] }
16
+
17
+ org = fetch_org
18
+ write_env(env_data, org)
19
+ org
20
+ end
21
+
22
+ private
23
+
24
+ def fetch_org
25
+ orgs = PartnersAPI::Organizations.fetch_with_app(@ctx)
26
+ org_id = if orgs.count == 1
27
+ orgs.first["id"]
28
+ else
29
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.organization_select')) do |handler|
30
+ orgs.each do |org|
31
+ handler.option(
32
+ @ctx.message('core.partners_api.org_name_and_id', org['businessName'], org['id'])
33
+ ) { org["id"] }
34
+ end
35
+ end
36
+ end
37
+ orgs.find { |o| o["id"] == org_id }
38
+ end
39
+
40
+ def get_app(org_id, apps)
41
+ if apps.count == 1
42
+ apps.first
43
+ elsif apps.count == 0
44
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_apps'))
45
+ title = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_name'))
46
+ type = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_type.select')) do |handler|
47
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_public')) { 'public' }
48
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_custom')) { 'custom' }
49
+ end
50
+ ShopifyCli::Tasks::CreateApiClient.call(@ctx, org_id: org_id, title: title, type: type)
51
+ else
52
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_select')) do |handler|
53
+ apps.each { |app| handler.option(app["title"]) { app } }
54
+ end
55
+ end
56
+ end
57
+
58
+ def get_shop(shops, id)
59
+ if shops.count == 1
60
+ shop = shops.first["shopDomain"]
61
+ elsif shops.count == 0
62
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_development_stores', id))
63
+ else
64
+ shop = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.development_store_select')) do |handler|
65
+ shops.each { |s| handler.option(s["shopName"]) { s["shopDomain"] } }
66
+ end
67
+ end
68
+ shop
11
69
  end
12
70
 
13
- def ask
14
- api_key = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_key_question'))
15
- api_secret = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_secret_key_question'))
16
- shop = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.development_store_question'))
71
+ def write_env(env_data, org)
72
+ id = org['id']
73
+ app = get_app(id, org['apps'])
17
74
 
18
- shop.gsub!(/https?\:\/\//, '')
75
+ env_data[:shop] = get_shop(org['stores'], id)
76
+ env_data[:api_key] = app["apiKey"]
77
+ env_data[:secret] = app["apiSecretKeys"].first["secret"]
78
+ env_data[:scopes] = 'write_products,write_customers,write_draft_orders' if env_data[:scopes].nil?
79
+ env_data[:extra] = {} if env_data[:extra].nil?
19
80
 
20
- env = Resources::EnvFile.new(
21
- api_key: api_key,
22
- secret: api_secret,
23
- shop: shop,
24
- host: ShopifyCli::Tunnel.start(@ctx),
25
- scopes: 'write_products,write_customers,write_draft_orders',
81
+ Resources::EnvFile.new(
82
+ env_data
26
83
  ).write(@ctx)
27
- env
28
84
  end
29
85
  end
30
86
  end
@@ -28,16 +28,17 @@ module ShopifyCli
28
28
  end
29
29
 
30
30
  def construct_redirect_urls(urls, new_url, callback_url)
31
- urls.map do |url|
31
+ new_urls = urls.map do |url|
32
32
  if (match = url.match(NGROK_REGEX))
33
33
  "#{new_url}#{match[2]}"
34
34
  else
35
35
  url
36
36
  end
37
37
  end
38
- if urls.grep(/#{new_url}#{callback_url}/).empty?
39
- urls.push("#{new_url}#{callback_url}")
38
+ if new_urls.grep(/#{new_url}#{callback_url}/).empty?
39
+ new_urls.push("#{new_url}#{callback_url}")
40
40
  end
41
+ new_urls.uniq
41
42
  end
42
43
  end
43
44
  end
@@ -21,6 +21,7 @@ module ShopifyCli
21
21
  DOWNLOAD_URLS = {
22
22
  mac: 'https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip',
23
23
  linux: 'https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip',
24
+ windows: 'https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip',
24
25
  }
25
26
 
26
27
  NGROK_TUNNELS_URI = URI.parse('http://localhost:4040/api/tunnels')
@@ -62,14 +63,19 @@ module ShopifyCli
62
63
  #
63
64
  def start(ctx, port: PORT)
64
65
  install(ctx)
65
- process = ShopifyCli::ProcessSupervision.start(:ngrok, ngrok_command(port))
66
- log = fetch_url(ctx, process.log_path)
67
- if log.account
68
- ctx.puts(ctx.message('core.tunnel.start_with_account', log.url, log.account))
66
+ url, account, seconds_remaining = start_ngrok(ctx, port)
67
+ if account
68
+ ctx.puts(ctx.message('core.tunnel.start_with_account', url, account))
69
69
  else
70
- ctx.puts(ctx.message('core.tunnel.start', log.url))
70
+ if seconds_remaining <= 0
71
+ ctx.puts(ctx.message('core.tunnel.timed_out'))
72
+ url, _account, seconds_remaining = restart_ngrok(ctx, port)
73
+ end
74
+ ctx.puts(ctx.message('core.tunnel.start', url))
75
+ ctx.puts(ctx.message('core.tunnel.will_timeout', seconds_to_hm(seconds_remaining)))
76
+ ctx.puts(ctx.message('core.tunnel.signup_suggestion', ShopifyCli::TOOL_NAME))
71
77
  end
72
- log.url
78
+ url
73
79
  end
74
80
 
75
81
  ##
@@ -83,7 +89,7 @@ module ShopifyCli
83
89
  #
84
90
  def auth(ctx, token)
85
91
  install(ctx)
86
- ctx.system(File.join(ShopifyCli::CACHE_DIR, 'ngrok'), 'authtoken', token)
92
+ ctx.system(File.join(ShopifyCli.cache_dir, 'ngrok'), 'authtoken', token)
87
93
  end
88
94
 
89
95
  ##
@@ -117,14 +123,19 @@ module ShopifyCli
117
123
  private
118
124
 
119
125
  def install(ctx)
120
- return if File.exist?(File.join(ShopifyCli::CACHE_DIR, 'ngrok'))
126
+ return if File.exist?(File.join(ShopifyCli.cache_dir, ctx.windows? ? 'ngrok.exe' : 'ngrok'))
121
127
  spinner = CLI::UI::SpinGroup.new
122
128
  spinner.add('Installing ngrok...') do
123
- zip_dest = File.join(ShopifyCli::CACHE_DIR, 'ngrok.zip')
129
+ zip_dest = File.join(ShopifyCli.cache_dir, 'ngrok.zip')
124
130
  unless File.exist?(zip_dest)
125
- ctx.system('curl', '-o', zip_dest, DOWNLOAD_URLS[ctx.os], chdir: ShopifyCli::CACHE_DIR)
131
+ ctx.system('curl', '-o', zip_dest, DOWNLOAD_URLS[ctx.os], chdir: ShopifyCli.cache_dir)
126
132
  end
127
- ctx.system('unzip', '-u', zip_dest, chdir: ShopifyCli::CACHE_DIR)
133
+ args = if ctx.linux?
134
+ %W(unzip -u #{zip_dest})
135
+ else
136
+ %W(tar -xf #{zip_dest})
137
+ end
138
+ ctx.system(*args, chdir: ShopifyCli.cache_dir)
128
139
  ctx.rm(zip_dest)
129
140
  end
130
141
  spinner.wait
@@ -138,13 +149,30 @@ module ShopifyCli
138
149
  end
139
150
 
140
151
  def ngrok_command(port)
141
- "exec #{File.join(ShopifyCli::CACHE_DIR, 'ngrok')} http -log=stdout -log-level=debug #{port}"
152
+ "#{File.join(ShopifyCli.cache_dir, 'ngrok')} http -inspect=false -log=stdout -log-level=debug #{port}"
153
+ end
154
+
155
+ def seconds_to_hm(seconds)
156
+ format("%d hours %d minutes", seconds / 3600, seconds / 60 % 60)
142
157
  end
143
158
 
159
+ def start_ngrok(ctx, port)
160
+ process = ShopifyCli::ProcessSupervision.start(:ngrok, ngrok_command(port))
161
+ log = fetch_url(ctx, process.log_path)
162
+ seconds_remaining = (process.time.to_i + log.timeout) - Time.now.to_i
163
+ [log.url, log.account, seconds_remaining]
164
+ end
165
+
166
+ def restart_ngrok(ctx, port)
167
+ unless ShopifyCli::ProcessSupervision.stop(:ngrok)
168
+ ctx.abort(ctx.message('core.tunnel.error.stop'))
169
+ end
170
+ start_ngrok(ctx, port)
171
+ end
144
172
  class LogParser # :nodoc:
145
173
  TIMEOUT = 10
146
174
 
147
- attr_reader :url, :account
175
+ attr_reader :url, :account, :timeout
148
176
 
149
177
  def initialize(log_path)
150
178
  @log_path = log_path
@@ -173,7 +201,9 @@ module ShopifyCli
173
201
  end
174
202
 
175
203
  def parse_account
176
- @account, _ = @log.match(/AccountName:([\w\s]+) SessionDuration/)&.captures
204
+ account, timeout, _ = @log.match(/AccountName:([\w\s\d@._\-]*) SessionDuration:([\d]+) PlanName/)&.captures
205
+ @account = account&.empty? ? nil : account
206
+ @timeout = timeout&.empty? ? 0 : timeout.to_i
177
207
  end
178
208
 
179
209
  def error
@@ -1,3 +1,3 @@
1
1
  module ShopifyCli
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -44,10 +44,6 @@ module ShopifyCli
44
44
  ROOT = File.expand_path('../..', __FILE__)
45
45
  PROJECT_TYPES_DIR = File.join(ROOT, 'lib', 'project_types')
46
46
  TEMP_DIR = File.join(ROOT, '.tmp')
47
- CACHE_DIR = File.join(File.expand_path(ENV.fetch('XDG_CACHE_HOME', '~/.cache')), TOOL_NAME)
48
- TOOL_CONFIG_PATH = File.join(File.expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config')), TOOL_NAME)
49
- LOG_FILE = File.join(TOOL_CONFIG_PATH, 'logs', 'log.log')
50
- DEBUG_LOG_FILE = File.join(TOOL_CONFIG_PATH, 'logs', 'debug.log')
51
47
 
52
48
  # programmer emoji if default install location, else wrench emoji
53
49
  EMOJI = ROOT == '/opt/shopify' ? "\u{1f469}\u{200d}\u{1f4bb}" : "\u{1f527}"
@@ -82,7 +78,7 @@ module ShopifyCli
82
78
  # ShopifyCli::Config
83
79
  autocall(:Config) { CLI::Kit::Config.new(tool_name: TOOL_NAME) }
84
80
  # ShopifyCli::Logger
85
- autocall(:Logger) { CLI::Kit::Logger.new(debug_log_file: DEBUG_LOG_FILE) }
81
+ autocall(:Logger) { CLI::Kit::Logger.new(debug_log_file: ShopifyCli.debug_log_file) }
86
82
  # ShopifyCli::Resolver
87
83
  autocall(:Resolver) do
88
84
  ShopifyCli::Core::HelpResolver.new(
@@ -93,7 +89,7 @@ module ShopifyCli
93
89
  # ShopifyCli::ErrorHandler
94
90
  autocall(:ErrorHandler) do
95
91
  CLI::Kit::ErrorHandler.new(
96
- log_file: ShopifyCli::LOG_FILE,
92
+ log_file: ShopifyCli.log_file,
97
93
  exception_reporter: nil,
98
94
  )
99
95
  end
@@ -105,6 +101,7 @@ module ShopifyCli
105
101
  autoload :Context, 'shopify-cli/context'
106
102
  autoload :Core, 'shopify-cli/core'
107
103
  autoload :DB, 'shopify-cli/db'
104
+ autoload :Feature, 'shopify-cli/feature'
108
105
  autoload :Form, 'shopify-cli/form'
109
106
  autoload :Git, 'shopify-cli/git'
110
107
  autoload :Helpers, 'shopify-cli/helpers'
@@ -126,7 +123,37 @@ module ShopifyCli
126
123
 
127
124
  require 'shopify-cli/messages/messages'
128
125
  Context.load_messages(ShopifyCli::Messages::MESSAGES)
129
- end
130
126
 
131
- # Make sure the cache dir always exists
132
- FileUtils.mkdir_p(ShopifyCli::CACHE_DIR)
127
+ def self.cache_dir
128
+ cache_dir = if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
129
+ TEMP_DIR
130
+ elsif ENV['LOCALAPPDATA'].nil?
131
+ File.join(File.expand_path(ENV.fetch('XDG_CACHE_HOME', '~/.cache')), TOOL_NAME)
132
+ else
133
+ File.join(File.expand_path(ENV['LOCALAPPDATA']), TOOL_NAME)
134
+ end
135
+
136
+ # Make sure the cache dir always exists
137
+ @cache_dir_exists ||= FileUtils.mkdir_p(cache_dir)
138
+
139
+ cache_dir
140
+ end
141
+
142
+ def self.tool_config_path
143
+ if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
144
+ TEMP_DIR
145
+ elsif ENV['APPDATA'].nil?
146
+ File.join(File.expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config')), TOOL_NAME)
147
+ else
148
+ File.join(File.expand_path(ENV['APPDATA']), TOOL_NAME)
149
+ end
150
+ end
151
+
152
+ def self.log_file
153
+ File.join(tool_config_path, 'logs', 'log.log')
154
+ end
155
+
156
+ def self.debug_log_file
157
+ File.join(tool_config_path, 'logs', 'debug.log')
158
+ end
159
+ end
@@ -26,7 +26,10 @@ Gem::Specification.new do |spec|
26
26
  # Specify which files should be added to the gem when it is released.
27
27
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
28
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
- %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features|packaging)/}) }
29
+ %x(git ls-files -z).split("\x0").reject do |f|
30
+ f.match(%r{^(test|spec|features|packaging)/}) ||
31
+ f.match(%r{^bin/(update-deps|shopify.bat)$})
32
+ end
30
33
  end
31
34
  spec.bindir = "bin"
32
35
  spec.require_paths = ["lib", "vendor"]
@@ -1 +1 @@
1
- fc25a17dff9d3130bb705659c002282ef7827932
1
+ 1013aa5c5664e7034ca3f02fd2e0513361b07e95 (dirty)
@@ -51,7 +51,7 @@ module CLI
51
51
  # 1. rescue Abort or Bug
52
52
  # 2. Print a contextualized error message
53
53
  # 3. Re-raise AbortSilent or BugSilent respectively.
54
- GenericAbort = Class.new(Exception)
54
+ GenericAbort = Class.new(Exception) # rubocop:disable Lint/InheritException
55
55
  Abort = Class.new(GenericAbort)
56
56
  Bug = Class.new(GenericAbort)
57
57
  BugSilent = Class.new(GenericAbort)
@@ -11,8 +11,8 @@ module CLI
11
11
  def const_missing(const)
12
12
  block = begin
13
13
  @autocalls.fetch(const)
14
- rescue KeyError
15
- return super
14
+ rescue KeyError
15
+ return super
16
16
  end
17
17
  const_set(const, block.call)
18
18
  end
@@ -22,11 +22,11 @@ module CLI
22
22
  end
23
23
 
24
24
  def handle_exception(error)
25
- if notify_with = exception_for_submission(error)
25
+ if (notify_with = exception_for_submission(error))
26
26
  logs = begin
27
27
  File.read(@log_file)
28
- rescue => e
29
- "(#{e.class}: #{e.message})"
28
+ rescue => e
29
+ "(#{e.class}: #{e.message})"
30
30
  end
31
31
  exception_reporter.report(notify_with, logs)
32
32
  end
@@ -56,7 +56,7 @@ module CLI
56
56
  # if it was `exit 30`, translate the exit code to 1, and submit nothing.
57
57
  # 30 is used to signal normal failures that are not indicative of bugs.
58
58
  # However, users should see it presented as 1.
59
- exit 1
59
+ exit(1)
60
60
  else
61
61
  # A weird termination status happened. `error.exception "message"` will maintain backtrace
62
62
  # but allow us to set a message
@@ -83,7 +83,7 @@ module CLI
83
83
 
84
84
  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
85
85
  rescue Interrupt
86
- $stderr.puts(format_error_message("Interrupt"))
86
+ stderr_puts_message('Interrupt')
87
87
  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
88
88
  rescue Errno::ENOSPC
89
89
  message = if @tool_name
@@ -91,10 +91,16 @@ module CLI
91
91
  else
92
92
  "Your disk is full - free space is required to operate"
93
93
  end
94
- $stderr.puts(format_error_message(message))
94
+ stderr_puts_message(message)
95
95
  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
96
96
  end
97
97
 
98
+ def stderr_puts_message(message)
99
+ $stderr.puts(format_error_message(message))
100
+ rescue Errno::EPIPE
101
+ nil
102
+ end
103
+
98
104
  def exception_reporter
99
105
  if @exception_reporter_or_proc.respond_to?(:report)
100
106
  @exception_reporter_or_proc