Last active
May 14, 2025 23:01
-
-
Save Buitragox/57a498858e899f8dd300855248e30017 to your computer and use it in GitHub Desktop.
Compare spec coverage between two commits
This file contains hidden or 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
# This script is used to get the coverage of two commits in a git repository. | |
function coverages() { | |
local HASH_MODE=false | |
local PICKER_MODE=false | |
local SEARCH_TERM="" | |
local COMMIT="" | |
local PREV_COMMIT="" | |
# Parse arguments | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
-c|--commits) | |
HASH_MODE=true | |
shift | |
COMMIT="$1" | |
shift | |
if [[ $# -gt 0 ]]; then | |
PREV_COMMIT="$1" | |
shift | |
else | |
echo "Error: When using -c|--commits, you must provide two commit hashes." | |
return 1 | |
fi | |
;; | |
-p|--picker) | |
PICKER_MODE=true | |
shift | |
;; | |
*) | |
SEARCH_TERM="$1" | |
shift | |
;; | |
esac | |
done | |
# Check if a search term or commit hashes were provided | |
if [[ -z "$SEARCH_TERM" && "$HASH_MODE" = false && "$PICKER_MODE" = false ]]; then | |
echo "Usage: coverages <COMMIT_DESCRIPTION>" | |
echo " or: coverages -c <COMMIT_HASH1> <COMMIT_HASH2>" | |
echo ' or: coverages -p | --picker (requires \e]8;;https://github.com/junegunn/fzf\e\\fzf\e]8;;\e\\ to pick commits)' | |
echo "Examples:" | |
echo " coverages \"#240\" (If the PR is already merged)" | |
echo " coverages \"COM-123: Fix\"" | |
echo " coverages -c abc1234 def5678" | |
echo " coverages -c HEAD HEAD~1" | |
echo " coverages -p" | |
return 1 | |
fi | |
local RED='\033[0;31m' | |
local NC='\033[0m' # No Color | |
# Check if fzf is installed if using picker mode | |
if [[ "$PICKER_MODE" = true ]]; then | |
if ! command -v fzf >/dev/null 2>&1; then | |
echo "Error: fzf is not installed. Please install it first with:" | |
echo " brew install fzf" | |
return 1 | |
fi | |
COMMIT=$(git log --pretty=format:"%h %ad %s" --date=short | fzf --prompt="Select the first commit (newer) » " --height=~50% --layout=reverse --border | awk '{print $1}') | |
if [[ -z "$COMMIT" ]]; then | |
echo "No commit selected. Aborting." | |
return 1 | |
fi | |
echo "${RED}Selected commit #1: $COMMIT${NC}" | |
PREV_COMMIT=$(git log --pretty=format:"%h %ad %s" --date=short | fzf --prompt="Select the first commit (newer) » " --height=~50% --layout=reverse --border | awk '{print $1}') | |
if [[ -z "$PREV_COMMIT" ]]; then | |
echo "No second commit selected. Aborting." | |
return 1 | |
fi | |
echo "${RED}Selected commit #2: $PREV_COMMIT${NC}" | |
fi | |
# Skip commit search if hash mode or picker mode is enabled (direct commit hashes provided) | |
if [[ "$HASH_MODE" = false && "$PICKER_MODE" = false ]]; then | |
COMMIT=$(git log --grep="$SEARCH_TERM" --format="%H" -n 1) | |
if [[ -z $COMMIT ]]; then | |
echo "No commit found with description \"$SEARCH_TERM\" in the message." | |
return 1 | |
fi | |
# Use the previous commit as the second commit | |
PREV_COMMIT=$(git rev-parse $COMMIT~1) | |
fi | |
# Verify commits exist when using hash mode | |
if [[ "$HASH_MODE" = true || "$PICKER_MODE" = true ]]; then | |
if ! git rev-parse --verify $COMMIT^{commit} >/dev/null 2>&1; then | |
echo "Error: First commit hash '$COMMIT' is not valid." | |
return 1 | |
fi | |
if ! git rev-parse --verify $PREV_COMMIT^{commit} >/dev/null 2>&1; then | |
echo "Error: Second commit hash '$PREV_COMMIT' is not valid." | |
return 1 | |
fi | |
fi | |
echo "Commit #1: $COMMIT" | |
git log -n 1 --pretty=format:"%s%n%n%b" $COMMIT | |
echo "Commit #2: $PREV_COMMIT" | |
git log -n 1 --pretty=format:"%s%n%n%b" $PREV_COMMIT | |
# Ask for confirmation before proceeding | |
echo -n "Get coverages for these commits? (y/n): " | |
read CONFIRM | |
if [[ ! $CONFIRM =~ ^[Yy]$ ]]; then | |
echo "Cancelled." | |
return 0 | |
fi | |
local CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |
echo "${RED}Checking out commit $COMMIT...${NC}" | |
git checkout $COMMIT | |
if [[ $? -ne 0 ]]; then | |
echo "${RED}Error: git checkout failed. You may have uncommitted changes. Aborting.${NC}" | |
return 1 | |
fi | |
echo "${RED}Installing gems...${NC}" | |
bundle install | |
echo "${RED}Preparing database...${NC}" | |
bundle exec rake db:test:prepare | |
echo "${RED}Running tests...${NC}" | |
bundle exec rspec | |
local AFTER=$(cat ./coverage/.last_run.json | jq '.result.covered_percent') | |
echo "${RED}Checking out previous commit $PREV_COMMIT...${NC}" | |
git checkout $PREV_COMMIT | |
echo "${RED}Installing gems...${NC}" | |
bundle install | |
echo "${RED}Preparing database...${NC}" | |
bundle exec rake db:test:prepare | |
echo "${RED}Running tests...${NC}" | |
bundle exec rspec | |
local BEFORE=$(cat ./coverage/.last_run.json | jq '.result.covered_percent') | |
echo "${RED}Restoring environment...${NC}" | |
git checkout $CURRENT_BRANCH | |
bundle install | |
bundle exec rake db:test:prepare | |
echo "\n${RED}DONE!${NC}" | |
echo "Coverage before (commit #1 $COMMIT): $BEFORE" | |
echo "Coverage after (commit #2 $PREV_COMMIT): $AFTER" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment