Skip to content

Instantly share code, notes, and snippets.

@ngmachado
Created July 3, 2025 15:10
Show Gist options
  • Save ngmachado/f8864ea1c636f824ca3395a3a31e599d to your computer and use it in GitHub Desktop.
Save ngmachado/f8864ea1c636f824ca3395a3a31e599d to your computer and use it in GitHub Desktop.
# Create the forge-retest plugin
cat > /usr/local/bin/forge-retest << 'EOF'
#!/bin/bash
# Forge Retest Plugin
# Usage: forge retest [--save] [--list] [--clear]
FAILED_TESTS_FILE=".forge-failed-tests.json"
show_help() {
echo "forge-retest - Rerun failed tests"
echo ""
echo "Usage:"
echo " forge retest # Run previously failed tests"
echo " forge retest --save # Run all tests and save failed ones"
echo " forge retest --list # List previously failed tests"
echo " forge retest --clear # Clear failed tests list"
echo " forge retest --help # Show this help"
}
save_failed_tests() {
echo "Running all tests and capturing failures..."
# Method 1: Parse forge test output directly
forge test 2>&1 | grep -E "\[FAIL.*\]" | while read -r line; do
# Extract test name from line like: [FAIL. Reason: revert: ...] testName() (gas: 123)
test_name=$(echo "$line" | sed -E 's/.*\[FAIL[^]]*\] ([^(]+).*/\1/')
echo "$test_name"
done | jq -R -s 'split("\n") | map(select(length > 0)) | map({name: .})' > "$FAILED_TESTS_FILE"
local count=$(cat "$FAILED_TESTS_FILE" | jq '. | length')
echo "Saved $count failed tests to $FAILED_TESTS_FILE"
}
list_failed_tests() {
if [[ ! -f "$FAILED_TESTS_FILE" ]]; then
echo "No failed tests file found. Run 'forge retest --save' first."
return 1
fi
echo "Previously failed tests:"
jq -r '.[] | " " + .name' "$FAILED_TESTS_FILE"
}
run_failed_tests() {
if [[ ! -f "$FAILED_TESTS_FILE" ]]; then
echo "No failed tests file found. Run 'forge retest --save' first."
return 1
fi
local count=$(cat "$FAILED_TESTS_FILE" | jq '. | length' 2>/dev/null || echo "0")
if [[ "$count" == "0" ]]; then
echo "No failed tests to rerun."
return 0
fi
echo "Rerunning $count failed tests..."
local test_names=$(jq -r '.[] | .name' "$FAILED_TESTS_FILE" | tr '\n' '|' | sed 's/|$//')
if [[ -n "$test_names" ]]; then
forge test --match-test "$test_names" -vv
fi
}
clear_failed_tests() {
if [[ -f "$FAILED_TESTS_FILE" ]]; then
rm "$FAILED_TESTS_FILE"
echo "Cleared failed tests list"
else
echo "No failed tests file to clear"
fi
}
case "${1:-}" in
--save)
save_failed_tests
;;
--list)
list_failed_tests
;;
--clear)
clear_failed_tests
;;
--help|-h)
show_help
;;
"")
run_failed_tests
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
EOF
chmod +x /usr/local/bin/forge-retest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment