Skip to content

Instantly share code, notes, and snippets.

@dakennguyen
Last active September 11, 2021 11:03
Show Gist options
  • Save dakennguyen/c9022858ff9e265eb986c6eb5c510895 to your computer and use it in GitHub Desktop.
Save dakennguyen/c9022858ff9e265eb986c6eb5c510895 to your computer and use it in GitHub Desktop.
Run `rspec` for only changed files

Description

Inside your git repository, find all modified files since your base commit. If said file is a spec file, run rspec for it. If it is a source file, find spec file by vim-projectionist, and then run rspec automatically.

Installation

You have to setup spec file as source file's alternate, either by setting up g:projectionist_heuristics in your vimrc or creating a .projections.json in the root of the project.

For example:

  "app/*.rb": {
    "alternate": "spec/{}_spec.rb"
  }

For more details on how to setup projectionist please refer to: https://github.com/tpope/vim-projectionist

# Author : Khoa Nguyen
# GitHub : https://www.github.com/dakennguyen
# Date : 31/08/2021
# Version: 0.1
# Description: Run rspec for all 'dirty' files, i.e. files that have been modified
# Dependencies: `awk`, `sed`, and `vim-projectionist`
drs() {
[ ! -d .git ] && echo 'NOT A GIT REPOSITORY' && return 0
CONFIG_FILE=~/.config/nvim/init.lua # not necessary if having `.projections.json` in the root of the project
BASE_COMMIT=$(git merge-base HEAD origin/HEAD) # origin/HEAD is project's default branch (e.g. master, main,...)
get_command_for_each_file() {
cat << EOF
let g:query_result=projectionist#query("alternate", {}, "${PWD}/${1}")[0][1]
if filereadable(g:query_result)
call writefile([g:query_result], "tmp-target-files", "a")
endif
EOF
}
# Get all source files, i.e. not spec files
git diff --name-only --diff-filter=d $BASE_COMMIT HEAD | sed '/^spec/d' > tmp-source-files
# Write vim ex-mode commands for each file
while read line; do
get_command_for_each_file $line >> tmp-vim-commands
done <tmp-source-files
[ -f tmp-source-files ] && rm tmp-source-files
# Using vim-projectionist, run vim ex-mode to get alternative files
[ -s tmp-vim-commands ] && nvim -u $CONFIG_FILE -s tmp-vim-commands -es
[ -f tmp-vim-commands ] && rm tmp-vim-commands
# Append with all spec files
git diff --name-only --diff-filter=d $BASE_COMMIT HEAD spec/ >> tmp-target-files
# Remove duplicates
awk '!visited[$0]++ { print $0 }' tmp-target-files > tmp-target-files-deduplicated
[ -f tmp-target-files ] && rm tmp-target-files
# Run rspec
[ ! -s tmp-target-files-deduplicated ] && echo 'NO CHANGED FILES' || bundle exec rspec $(paste -sd ' ' tmp-target-files-deduplicated)
[ -f tmp-target-files-deduplicated ] && rm tmp-target-files-deduplicated
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment