Skip to content

Commit

Permalink
Show friendly msg on config.rb Ruby syntax error (#49)
Browse files Browse the repository at this point in the history
* Show friendly msg on config.rb Ruby syntax error

* More flexible assertion

The exact format of the syntax error message is different for various
versions of Ruby. Match on a substring of the error instead.
  • Loading branch information
mattbrictson authored Sep 5, 2019
1 parent cbe19f4 commit becf0df
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 21 deletions.
2 changes: 1 addition & 1 deletion lib/tomo/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def call(argv)
command.parse(argv)
rescue Interrupt
handle_error(InterruptedError.new, command_name)
rescue StandardError => e
rescue StandardError, SyntaxError => e
handle_error(e, command_name)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/tomo/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def self.from_config_rb(path=DEFAULT_CONFIG_PATH)
config.working_dir = File.dirname(path)
DSL::ConfigFile.new(config).instance_eval(config_rb, path.to_s, 1)
end
rescue StandardError => e
rescue StandardError, SyntaxError => e
raise DSL::ErrorFormatter.decorate(e, path, config_rb&.lines)
end

Expand Down
37 changes: 19 additions & 18 deletions lib/tomo/configuration/dsl/error_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,31 @@ module Tomo
class Configuration
module DSL
module ErrorFormatter
def self.decorate(error, path, lines)
if error.backtrace[0..1].grep(/^#{Regexp.quote(path)}:/).empty?
return error
class << self
def decorate(error, path, lines)
line_no = find_line_no(path, error.message, *error.backtrace[0..1])
return error if line_no.nil?

error.extend(self)
error.dsl_lines = lines || []
error.dsl_path = path
error.error_line_no = line_no
error
end

error.extend(self)
error.dsl_lines = lines || []
error.dsl_path = path
error
private

def find_line_no(path, *lines)
lines.find do |line|
line_no = line[/^#{Regexp.quote(path)}:(\d+):/, 1]
break line_no.to_i if line_no
end
end
end

include Colors

attr_accessor :dsl_lines, :dsl_path
attr_accessor :dsl_lines, :dsl_path, :error_line_no

def to_console
<<~ERROR
Expand All @@ -39,16 +50,6 @@ def trace_hint
HINT
end

def error_line_no
@_error_line_no ||= begin
pattern = /^#{Regexp.quote(dsl_path)}:(\d+):/
backtrace.each do |entry|
match = pattern.match(entry)
break match[1].to_i if match
end
end
end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def highlighted_lines
Expand Down
6 changes: 5 additions & 1 deletion lib/tomo/testing/cli_tester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ def initialize
@token = SecureRandom.hex(8)
end

def in_temp_dir(&block)
super(token, &block)
end

def run(*args, raise_on_error: true)
in_temp_dir(token) do
in_temp_dir do
restoring_defaults do
capturing_logger_output do
handling_exit(raise_on_error) do
Expand Down
51 changes: 51 additions & 0 deletions test/tomo/cli_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,55 @@ def test_execute_task_with_implicit_run_command
@tester.run "bundler:install", "--dry-run"
assert_match "Simulated bundler:install", @tester.stdout
end

def test_prints_error_when_config_has_syntax_error
@tester.in_temp_dir do
FileUtils.mkdir_p(".tomo")
IO.write(".tomo/config.rb", <<~CONFIG)
plugin "git"
deploy do
run "git:clone
run "git:create_release"
end
CONFIG
end
@tester.run "deploy", raise_on_error: false
assert_match(<<~'OUTPUT'.strip, @tester.stderr.gsub(/^ /, ""))
ERROR: Configuration syntax error in .tomo/config.rb at line 4.
3: run "git:clone
→ 4: run "git:create_release"
5: end
SyntaxError: .tomo/config.rb:4: syntax error
OUTPUT
end

def test_prints_error_when_config_dsl_is_used_incorrectly
@tester.in_temp_dir do
FileUtils.mkdir_p(".tomo")
IO.write(".tomo/config.rb", <<~CONFIG)
plugin "git"
deploy do
run
run "git:create_release"
end
CONFIG
end
@tester.run "deploy", raise_on_error: false
assert_equal(<<~'OUTPUT', @tester.stderr.gsub(/^ /, ""))
ERROR: Configuration syntax error in .tomo/config.rb at line 3.
2: deploy do
→ 3: run
4: run "git:create_release"
ArgumentError: wrong number of arguments (given 0, expected 1)
Visit https://tomo-deploy.com/configuration for syntax reference.
You can run this command again with --trace for a full backtrace.
OUTPUT
end
end

0 comments on commit becf0df

Please sign in to comment.