shopify-cli 1.0.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/CHANGELOG.md +20 -0
  4. data/bin/load_shopify.rb +3 -1
  5. data/bin/shopify +2 -0
  6. data/docs/core/index.md +16 -0
  7. data/docs/getting-started/index.md +3 -2
  8. data/docs/getting-started/install/index.md +55 -9
  9. data/docs/getting-started/uninstall/index.md +1 -1
  10. data/docs/getting-started/upgrade/index.md +8 -4
  11. data/ext/shopify-cli/extconf.rb +40 -20
  12. data/lib/project_types/extension/cli.rb +6 -1
  13. data/lib/project_types/extension/commands/register.rb +1 -1
  14. data/lib/project_types/extension/features/argo/admin.rb +20 -0
  15. data/lib/project_types/extension/features/argo/base.rb +129 -0
  16. data/lib/project_types/extension/features/argo/checkout.rb +20 -0
  17. data/lib/project_types/extension/features/argo_config.rb +60 -0
  18. data/lib/project_types/extension/messages/messages.rb +11 -2
  19. data/lib/project_types/extension/models/type.rb +4 -0
  20. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +6 -3
  21. data/lib/project_types/extension/models/types/product_subscription.rb +24 -0
  22. data/lib/project_types/node/commands/create.rb +4 -4
  23. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  24. data/lib/project_types/node/commands/generate/billing.rb +7 -5
  25. data/lib/project_types/node/commands/generate/page.rb +9 -5
  26. data/lib/project_types/node/commands/generate/webhook.rb +5 -1
  27. data/lib/project_types/node/commands/serve.rb +5 -5
  28. data/lib/project_types/node/messages/messages.rb +5 -1
  29. data/lib/project_types/rails/commands/create.rb +56 -5
  30. data/lib/project_types/rails/commands/generate.rb +1 -0
  31. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  32. data/lib/project_types/rails/commands/serve.rb +11 -7
  33. data/lib/project_types/rails/gem.rb +61 -6
  34. data/lib/project_types/rails/messages/messages.rb +32 -12
  35. data/lib/project_types/script/config/extension_points.yml +4 -4
  36. data/lib/project_types/script/forms/create.rb +1 -1
  37. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +36 -1
  38. data/lib/project_types/script/layers/infrastructure/errors.rb +7 -0
  39. data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
  40. data/lib/project_types/script/messages/messages.rb +12 -37
  41. data/lib/project_types/script/ui/error_handler.rb +13 -5
  42. data/lib/rubygems_plugin.rb +18 -10
  43. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  44. data/lib/shopify-cli/commands/config.rb +33 -1
  45. data/lib/shopify-cli/commands/connect.rb +1 -1
  46. data/lib/shopify-cli/commands/system.rb +9 -8
  47. data/lib/shopify-cli/context.rb +68 -0
  48. data/lib/shopify-cli/core/entry_point.rb +3 -0
  49. data/lib/shopify-cli/git.rb +1 -1
  50. data/lib/shopify-cli/heroku.rb +18 -2
  51. data/lib/shopify-cli/js_deps.rb +2 -2
  52. data/lib/shopify-cli/js_system.rb +24 -7
  53. data/lib/shopify-cli/messages/messages.rb +39 -11
  54. data/lib/shopify-cli/process_supervision.rb +52 -15
  55. data/lib/shopify-cli/project.rb +17 -9
  56. data/lib/shopify-cli/tunnel.rb +19 -4
  57. data/lib/shopify-cli/version.rb +1 -1
  58. data/lib/shopify_cli.rb +6 -2
  59. data/shopify-cli.gemspec +4 -1
  60. data/vendor/deps/cli-kit/REVISION +1 -1
  61. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  62. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  63. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  64. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  65. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  66. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  67. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  68. data/vendor/deps/cli-ui/REVISION +1 -1
  69. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  70. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  71. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  72. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  73. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  74. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  75. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  76. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  77. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  78. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  79. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  80. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  81. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  82. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  83. data/vendor/gen/lib/gen.rb +39 -0
  84. data/vendor/gen/lib/gen/commands.rb +18 -0
  85. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  86. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  87. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  88. data/vendor/gen/lib/gen/generator.rb +165 -0
  89. data/vendor/gen/template/.gitignore +2 -0
  90. data/vendor/gen/template/Gemfile +10 -0
  91. data/vendor/gen/template/README.md +1 -0
  92. data/vendor/gen/template/bin/testunit +23 -0
  93. data/vendor/gen/template/bin/update-deps +97 -0
  94. data/vendor/gen/template/dev-gems.yml +3 -0
  95. data/vendor/gen/template/dev-vendor.yml +4 -0
  96. data/vendor/gen/template/exe/__app__-gems +17 -0
  97. data/vendor/gen/template/exe/__app__-vendor +18 -0
  98. data/vendor/gen/template/lib/__app__.rb +33 -0
  99. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  100. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  101. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  102. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  103. data/vendor/gen/template/test/example_test.rb +17 -0
  104. data/vendor/gen/template/test/test_helper.rb +22 -0
  105. metadata +30 -6
  106. data/Vagrantfile +0 -17
  107. data/lib/project_types/extension/features/argo.rb +0 -48
  108. data/lib/project_types/extension/models/types/subscription_management.rb +0 -20
  109. data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -8,7 +8,7 @@ module ShopifyCli
8
8
  # a string or a symbol to identify this process by
9
9
  attr_reader :identifier
10
10
  # process ID for the running process
11
- attr_reader :pid
11
+ attr_accessor :pid
12
12
  # starttime of the process
13
13
  attr_reader :time
14
14
  # filepath to the pidfile for this process
@@ -58,15 +58,37 @@ module ShopifyCli
58
58
  #
59
59
  def start(identifier, args)
60
60
  return for_ident(identifier) if running?(identifier)
61
- fork do
62
- 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
63
77
  pid_file.write
64
- STDOUT.reopen(pid_file.log_path, "w")
65
- STDERR.reopen(pid_file.log_path, "w")
66
- STDIN.reopen("/dev/null", "r")
67
- Process.setsid
68
- 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
69
90
  end
91
+
70
92
  sleep(0.1)
71
93
  for_ident(identifier)
72
94
  end
@@ -106,10 +128,11 @@ module ShopifyCli
106
128
  end
107
129
  end
108
130
 
109
- def initialize(identifier, pid:, time: Time.now.strftime('%s')) # :nodoc:
131
+ def initialize(identifier, pid: nil, time: Time.now.strftime('%s')) # :nodoc:
110
132
  @identifier = identifier
111
133
  @pid = pid
112
134
  @time = time
135
+ FileUtils.mkdir_p(ShopifyCli::ProcessSupervision.run_dir)
113
136
  @pid_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")
114
137
  @log_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.log")
115
138
  end
@@ -117,13 +140,17 @@ module ShopifyCli
117
140
  ##
118
141
  # will attempt to shutdown a running process
119
142
  #
143
+ # #### Parameters
144
+ #
145
+ # * `ctx` - the context of this command
146
+ #
120
147
  # #### Returns
121
148
  #
122
149
  # * `stopped` - [true, false]
123
150
  #
124
151
  def stop
125
- unlink
126
152
  kill_proc
153
+ unlink
127
154
  true
128
155
  rescue
129
156
  false
@@ -159,7 +186,11 @@ module ShopifyCli
159
186
  end
160
187
 
161
188
  def kill_proc
162
- kill(-pid) # process group
189
+ if Context.new.windows?
190
+ kill(pid)
191
+ else
192
+ kill(-pid) # process group
193
+ end
163
194
  rescue Errno::ESRCH
164
195
  begin
165
196
  kill(pid)
@@ -169,12 +200,18 @@ module ShopifyCli
169
200
  end
170
201
 
171
202
  def kill(id)
172
- Process.kill('TERM', id)
173
- 50.times do
174
- sleep 0.1
175
- 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
176
212
  end
177
213
  Process.kill('KILL', id) if stat(id)
214
+ sleep(0.1) if ctx.windows? # Give Windows a second to actually close the process
178
215
  end
179
216
 
180
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
@@ -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')
@@ -122,14 +123,21 @@ module ShopifyCli
122
123
  private
123
124
 
124
125
  def install(ctx)
125
- 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'))
127
+ check_prereq_command(ctx, 'curl')
128
+ check_prereq_command(ctx, ctx.linux? ? 'unzip' : 'tar')
126
129
  spinner = CLI::UI::SpinGroup.new
127
130
  spinner.add('Installing ngrok...') do
128
131
  zip_dest = File.join(ShopifyCli.cache_dir, 'ngrok.zip')
129
132
  unless File.exist?(zip_dest)
130
133
  ctx.system('curl', '-o', zip_dest, DOWNLOAD_URLS[ctx.os], chdir: ShopifyCli.cache_dir)
131
134
  end
132
- ctx.system('unzip', '-u', zip_dest, chdir: ShopifyCli.cache_dir)
135
+ args = if ctx.linux?
136
+ %W(unzip -u #{zip_dest})
137
+ else
138
+ %W(tar -xf #{zip_dest})
139
+ end
140
+ ctx.system(*args, chdir: ShopifyCli.cache_dir)
133
141
  ctx.rm(zip_dest)
134
142
  end
135
143
  spinner.wait
@@ -143,7 +151,7 @@ module ShopifyCli
143
151
  end
144
152
 
145
153
  def ngrok_command(port)
146
- "exec #{File.join(ShopifyCli.cache_dir, 'ngrok')} http -inspect=false -log=stdout -log-level=debug #{port}"
154
+ "\"#{File.join(ShopifyCli.cache_dir, 'ngrok')}\" http -inspect=false -log=stdout -log-level=debug #{port}"
147
155
  end
148
156
 
149
157
  def seconds_to_hm(seconds)
@@ -163,6 +171,13 @@ module ShopifyCli
163
171
  end
164
172
  start_ngrok(ctx, port)
165
173
  end
174
+
175
+ def check_prereq_command(ctx, command)
176
+ cmd_path = ctx.which(command)
177
+ ctx.abort(ctx.message('core.tunnel.error.prereq_command_required', command)) if cmd_path.nil?
178
+ ctx.done(ctx.message('core.tunnel.prereq_command_location', command, cmd_path))
179
+ end
180
+
166
181
  class LogParser # :nodoc:
167
182
  TIMEOUT = 10
168
183
 
@@ -195,7 +210,7 @@ module ShopifyCli
195
210
  end
196
211
 
197
212
  def parse_account
198
- account, timeout, _ = @log.match(/AccountName:([\w\s]*) SessionDuration:([\d]+) PlanName/)&.captures
213
+ account, timeout, _ = @log.match(/AccountName:([\w\s\d@._\-]*) SessionDuration:([\d]+) PlanName/)&.captures
199
214
  @account = account&.empty? ? nil : account
200
215
  @timeout = timeout&.empty? ? 0 : timeout.to_i
201
216
  end
@@ -1,3 +1,3 @@
1
1
  module ShopifyCli
2
- VERSION = '1.0.5'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -127,8 +127,10 @@ module ShopifyCli
127
127
  def self.cache_dir
128
128
  cache_dir = if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
129
129
  TEMP_DIR
130
- else
130
+ elsif ENV['LOCALAPPDATA'].nil?
131
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)
132
134
  end
133
135
 
134
136
  # Make sure the cache dir always exists
@@ -140,8 +142,10 @@ module ShopifyCli
140
142
  def self.tool_config_path
141
143
  if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
142
144
  TEMP_DIR
143
- else
145
+ elsif ENV['APPDATA'].nil?
144
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)
145
149
  end
146
150
  end
147
151
 
@@ -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
@@ -13,19 +13,17 @@ module CLI
13
13
  def call(command, command_name, args)
14
14
  with_traps do
15
15
  with_logging do |id|
16
+ command.call(args, command_name)
17
+ rescue => e
16
18
  begin
17
- command.call(args, command_name)
18
- rescue => e
19
- begin
20
- $stderr.puts "This command ran with ID: #{id}"
21
- $stderr.puts "Please include this information in any issues/report along with relevant logs"
22
- rescue SystemCallError
23
- # Outputting to stderr is best-effort. Avoid raising another error when outputting debug info so that
24
- # we can detect and log the original error, which may even be the source of this error.
25
- nil
26
- end
27
- raise e
19
+ $stderr.puts "This command ran with ID: #{id}"
20
+ $stderr.puts "Please include this information in any issues/report along with relevant logs"
21
+ rescue SystemCallError
22
+ # Outputting to stderr is best-effort. Avoid raising another error when outputting debug info so that
23
+ # we can detect and log the original error, which may even be the source of this error.
24
+ nil
28
25
  end
26
+ raise e
29
27
  end
30
28
  end
31
29
  end
@@ -10,9 +10,10 @@ module CLI
10
10
  # Constructor for CLI::Kit::Logger
11
11
  #
12
12
  # @param debug_log_file [String] path to the file where debug logs should be stored
13
- def initialize(debug_log_file:)
13
+ def initialize(debug_log_file:, env_debug_name: 'DEBUG')
14
14
  FileUtils.mkpath(File.dirname(debug_log_file))
15
15
  @debug_logger = ::Logger.new(debug_log_file, MAX_NUM_LOGS, MAX_LOG_SIZE)
16
+ @env_debug_name = env_debug_name
16
17
  end
17
18
 
18
19
  # Functionally equivalent to Logger#info
@@ -60,7 +61,7 @@ module CLI
60
61
  #
61
62
  # @param msg [String] the message to log
62
63
  def debug(msg)
63
- $stdout.puts CLI::UI.fmt(msg) if ENV['DEBUG']
64
+ $stdout.puts CLI::UI.fmt(msg) if is_debug?
64
65
  @debug_logger.debug(format_debug(msg))
65
66
  end
66
67
 
@@ -71,6 +72,11 @@ module CLI
71
72
  return msg unless CLI::UI::StdoutRouter.current_id
72
73
  "[#{CLI::UI::StdoutRouter.current_id[:id]}] #{msg}"
73
74
  end
75
+
76
+ def is_debug?
77
+ val = ENV[@env_debug_name]
78
+ val && val != '0' && val != ''
79
+ end
74
80
  end
75
81
  end
76
82
  end
@@ -10,7 +10,7 @@ module CLI
10
10
  def assert_all_commands_run(should_raise: true)
11
11
  errors = CLI::Kit::System.error_message
12
12
  CLI::Kit::System.reset!
13
- assert false, errors if should_raise && !errors.nil?
13
+ assert(false, errors) if should_raise && !errors.nil?
14
14
  errors
15
15
  end
16
16
 
@@ -196,22 +196,22 @@ module CLI
196
196
 
197
197
  unless errors[:unexpected].empty?
198
198
  final_error << CLI::UI.fmt(<<~EOF)
199
- {{bold:Unexpected command invocations:}}
200
- {{command:#{errors[:unexpected].join("\n")}}}
199
+ {{bold:Unexpected command invocations:}}
200
+ {{command:#{errors[:unexpected].join("\n")}}}
201
201
  EOF
202
202
  end
203
203
 
204
204
  unless errors[:not_run].empty?
205
205
  final_error << CLI::UI.fmt(<<~EOF)
206
- {{bold:Expected commands were not run:}}
207
- {{command:#{errors[:not_run].join("\n")}}}
206
+ {{bold:Expected commands were not run:}}
207
+ {{command:#{errors[:not_run].join("\n")}}}
208
208
  EOF
209
209
  end
210
210
 
211
211
  unless errors[:other].empty?
212
212
  final_error << CLI::UI.fmt(<<~EOF)
213
- {{bold:Commands were not run as expected:}}
214
- #{errors[:other].map { |cmd, msg| "{{command:#{cmd}}}\n#{msg}" }.join("\n\n")}
213
+ {{bold:Commands were not run as expected:}}
214
+ #{errors[:other].map { |cmd, msg| "{{command:#{cmd}}}\n#{msg}" }.join("\n\n")}
215
215
  EOF
216
216
  end
217
217