Last active
August 10, 2017 10:08
-
-
Save jemc/95969e3e2b58ddb0dede138c737907f5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
## | |
# In Pony 0.16.0, we introduced a breaking syntax change that affects all calls | |
# to partial functions (functions that can raise an error). | |
# | |
# All partial function calls are now required to be followed by a question mark. | |
# | |
# For example, `iterator.next()` is now `iterator.next()?`, providing a visual | |
# indication at the call site of any places where an error may be raised. | |
# | |
# Call sites to partial functions that fail to include the question mark | |
# will result in a compiler error that looks like this: | |
# | |
# /tmp/test.pony:5:19: call is not partial but the method is - a question mark | |
# is required after this call | |
# iterator.next() | |
# ^ | |
# Info: | |
# /tmp/ponyc/packages/builtin/array.pony:578:24: method is here | |
# fun ref next(): B->A ? => | |
# ^ | |
# | |
# See this RFC for more details: | |
# https://github.com/ponylang/rfcs/pull/82 | |
# | |
# As you might imagine, this change will affect nearly every Pony codebase, | |
# so we want to provide support for developers who are making this transition. | |
# | |
# This script is that support. It is an executable code migration tool that | |
# can ingest Pony compiler errors in the format emitted by ponyc to STDERR | |
# and make the necessary modifications to the Pony source code files that caused | |
# the errors, adding the question mark wherever it is needed for compliance | |
# with the new syntax requirement. | |
# | |
# This script will ignore any other errors in the ingested compiler output. | |
# | |
# An example invocation of this script might look like: | |
# | |
# ponyc |& bash ./pony-explicit-partial-calls.bash | |
# | |
# This script requires Bash version 4 for associative arrays. | |
# MacOS users who are missing Bash 4 can install it using homebrew: | |
# https://github.com/Toberumono/Miscellaneous/wiki/Installing-Bash-4.3-on-Mac-OSX | |
# | |
# A Windows-compatible implementation of this script is available at: | |
# https://gist.github.com/kulibali/cd5caf3a32d510bb86412f3fd4d52d0f | |
# | |
# If you need any other assistance with this transition, please reach out to | |
# us on IRC or on the mailing list. We're here to help! | |
# | |
set -e | |
error_pattern='^(.+):([0-9]+):([0-9]+): call is not partial but' | |
error_key_pattern='^(.+):([0-9]+)$' | |
tmpfile=`mktemp -t pony.XXXXXXXX` | |
declare -A errors | |
# Iterate over each line from stdin, which is expected to be the stderr stream | |
# of a failed Pony compilation that includes the error message we're targetting. | |
# Collect the errors into the associative array named `errors`, with each key | |
# being a filename and row number (separated by colon), and each value being | |
# a list of matching error columns on that row of that file, separated by colon. | |
while IFS=$'\n' read -r line; do | |
if [[ $line =~ $error_pattern ]]; then | |
error_filename="${BASH_REMATCH[1]}" | |
error_row="${BASH_REMATCH[2]}" | |
error_col="${BASH_REMATCH[3]}" | |
error_cols_this_row=${errors["$error_filename:$error_row"]} | |
error_cols_this_row="$error_cols_this_row:$error_col" | |
errors["$error_filename:$error_row"]="$error_cols_this_row" | |
fi | |
done | |
# Iterate over each gathered error, so we can fix it. | |
for error_key in "${!errors[@]}"; do | |
if [[ $error_key =~ $error_key_pattern ]]; then | |
error_filename="${BASH_REMATCH[1]}" | |
error_row="${BASH_REMATCH[2]}" | |
error_cols="${errors[$error_key]}" | |
# Split error_cols into an array, using ':' as the separator. | |
IFS=':' read -r -a error_cols <<< "$error_cols" | |
# Remove the (empty) first element of error_cols. | |
unset error_cols[0] | |
# Sort error_cols into reverse numeric order, keeping unique columns only. | |
# This keeps earlier edits on a line from affecting the index of later ones. | |
IFS=$'\n' error_cols=($(sort -r -n -u <<<"${error_cols[*]}")) | |
unset IFS | |
# For each error, open the file to edit it and fix the error. | |
for error_col in "${error_cols[@]}"; do | |
# Iterate over each line in the file, emitting the (possibly altered) | |
# line to stdout, which gets redirected to be written to a tmpfile. | |
row=0 | |
while IFS=$'\n' read -r line; do | |
row=$(( $row + 1 )) | |
# Compare the row number we're at with the row number of the error, | |
# emitting the altered line if a match, otherwise emitting it as normal. | |
if [[ $row == $error_row ]]; then | |
# Insert a '?' character at the appropriate column in the line. | |
printf '%s?%s\n' "${line:0:$error_col}" "${line:$error_col}" | |
else | |
# Print the line, unaltered. | |
echo "$line" | |
fi | |
done < "$error_filename" > "$tmpfile" | |
# Finish the edit of the file by moving the tmpfile into its place. | |
mv "$tmpfile" "$error_filename" | |
done | |
fi | |
done | |
echo DONE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for the script!
I have some suggestions:
src/datast/matrix.pony
didn't have a final newline and as a result line 49 got dropped.A way to fix this would be to replace line 103 by
/usr/bin/bash
isn't present on all systems (for example, it is/bin/bash
on Ubuntu 17.04). I believe that having#!/usr/bin/env bash
as shebang would make the script easier to use.