shopify-cli 1.0.1 → 1.1.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 (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