Skip to content

Instantly share code, notes, and snippets.

@mrdziuban
Last active November 17, 2016 17:32
Show Gist options
  • Save mrdziuban/c1b8260912329a1ddbdcc8a1dfe15cc4 to your computer and use it in GitHub Desktop.
Save mrdziuban/c1b8260912329a1ddbdcc8a1dfe15cc4 to your computer and use it in GitHub Desktop.
Ruby script to pretty print Shapeless record errors

Setup

  • Download shapeless_errors.rb to your computer

  • Make it executable:

    chmod +x /path/to/shapeless_errors.rb

  • Install the terminal-table gem:

    gem install terminal-table

    • Note: You might need to sudo gem install if you're using system Ruby
  • Run your Scala code and pipe it into shapeless_errors.rb:

    sbt run | /path/to/shapeless_errors.rb

#!/usr/bin/env ruby
################################################################################
# #
# Reads lines from STDIN and matches them against the format in which a #
# Shapeless record is printed. #
# #
# If the line matches the format, the keys and values of the record are #
# parsed and displayed using the terminal-table gem #
# (https://github.com/tj/terminal-table). #
# #
# USAGE: sbt run | /path/to/shapeless_errors.rb #
# #
################################################################################
begin
require 'terminal-table'
rescue LoadError
puts "\033[1;31mFailing to display Shapeless errors correctly without the terminal-table gem!"
puts "Please install it with\n\n\tgem install terminal-table\n\n"
puts "Displaying output normally...\n\033[0m"
end
msg = 'Parsed Shapeless record'
term_width = `tput cols`.to_i
num_stars = (term_width - (msg.length + 2)) / 2
header = "\n\033[1;32m#{'*' * num_stars} #{msg} #{'*' * num_stars}\033[0m\n"
footer = "\n\033[1;32m#{'*' * term_width}\033[0m\n"
while line = $stdin.gets
matches = line.scan(/shapeless\.tag\.Tagged\[([^,]*)\],([^,]*)/)
if matches.empty? || defined?(Terminal::Table).nil?
puts line
next
end
start = /^(.*?)shapeless\.::/.match(line)
matches = matches.map { |m| [m[0], m[1][0..-2]] }
table = Terminal::Table.new(headings: ['Key', 'Value'], rows: matches)
puts "#{start ? start[1] : ''}#{header}#{table}#{footer}"
end
@mrdziuban
Copy link
Author

mrdziuban commented Nov 17, 2016

Example output:

Before

[error] /foo/bar.scala:58: type mismatch;
[error]  found   : this.Out
[error]     (which expands to)  shapeless.::[Option[Int] with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("foo")],Option[Int]],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],Int],shapeless.HNil]]
[error]  required: shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("foo")],Int],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],Int],shapeless.HNil]]

After

[error] /foo/bar.scala:58: type mismatch;
[error]  found   : this.Out
[error]     (which expands to)
******************** Parsed Shapeless record ********************
+---------------+-------------+
| Key           | Value       |
+---------------+-------------+
| String("foo") | Option[Int] |
| String("bar") | Int         |
+---------------+-------------+
*****************************************************************
[error]  required:
******************** Parsed Shapeless record ********************
+---------------+-------+
| Key           | Value |
+---------------+-------+
| String("foo") | Int   |
| String("bar") | Int   |
+---------------+-------+
*****************************************************************

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment