Skip to content

Instantly share code, notes, and snippets.

@ts95
Created October 11, 2020 11:40
Show Gist options
  • Save ts95/9f6359d54c061e8c32f22fdb6321e551 to your computer and use it in GitHub Desktop.
Save ts95/9f6359d54c061e8c32f22fdb6321e551 to your computer and use it in GitHub Desktop.
Only run SwiftLint for chunks that differ from HEAD
#!/bin/bash
# Parameters
source="$(pwd)/" # Track folder source where diffs are checked
project_root=${0%/*} # Track project root folder
swiftlint_path='swiftlint' # Track SwiftLint path
changed_files () {
sort -u \
<(git diff --name-only --diff-filter=d --cached) \
<(git diff --name-only --diff-filter=d) \
| egrep "${source#$(pwd)/}" \
| egrep '.swift$'
}
diff_unified () {
sort -u <(git diff --cached -U0 $1) <(git diff -U0 $1)
}
if [ ! "$(changed_files)" ]; then
exit 0
fi
# Check if SwiftLint is installed
if [[ $(which swiftlint) == 'swiftlint not found' ]]; then
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
exit 1
fi
cd $project_root
# Iterate through each modified file
while read file; do
hunkCount=0 # Track number of hunks
hunkLines=() # Track each hunk range [start, end] = [hunkLines[i*2], hunkLines[i*2+1]]
# Iterate through each git diff hunk
while read hunk; do
hunkCount=$((hunkCount+1))
hunkLines+=(${hunk%%+*}) # Add hunk start line
hunkLines+=($(echo $hunk | bc)) # Add hunk end line
done< <(diff_unified $file | egrep '@@' | cut -d ' ' -f 3 | sed -e 's|+||' -e 's|,|+|')
# Iterate through each violation from SwiftLint
while read violation; do
line=$(echo $violation | cut -d : -f 2) # Track violation line number
# Iterate through each hunk range to see if violation applies
for i in $(seq 0 $((hunkCount-1))); do
# Check if violation is in range of hunk
if [ "$line" -ge "${hunkLines[i*2]}" ] && [ "$line" -le "${hunkLines[i*2+1]}" ]; then
# Violation output format is automatically recognized by Xcode
echo $violation
# Check if the violation contains an error, and exit immediately
if [[ $violation == *" error: "* ]]; then exit 1; fi
break
fi
done
done< <($swiftlint_path lint --quiet --path $file)
done< <(changed_files)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment