forked from musescore/MuseScore
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Uncrustify: Faster pre-commit hook to fix code style
Run multiple instances of Uncrustify in parallel to speed up fixing the code style for many files at once.
- Loading branch information
Showing
7 changed files
with
222 additions
and
43 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,126 @@ | ||
#!/usr/bin/env bash | ||
|
||
echo "Uncrustifying staged files..." | ||
|
||
RELPATH=../.. | ||
staged=$(git diff --name-only --cached) | ||
|
||
cd ./tools/codestyle/ | ||
while IFS= read -r file; do | ||
ext="${file##*.}" | ||
if [ $ext != "cpp" ] && [ $ext != "h" ]; then | ||
continue | ||
fi | ||
cp "$RELPATH/$file" "$RELPATH/$file.bak" | ||
if $( ./uncrustify_run_file.sh "$RELPATH/$file" ); then | ||
mv "$RELPATH/$file.uncrustify" "$RELPATH/$file" | ||
rm "$RELPATH/$file.bak" | ||
git add "$RELPATH/$file" | ||
else | ||
echo $? | ||
mv "$RELPATH/$file.bak" "$RELPATH/$file" | ||
rm "$RELPATH/$file.uncrustify" | ||
echo "Uncrustify failed for $file" | ||
fi | ||
done <<< "$staged" | ||
|
||
echo "Finished uncrustifying" | ||
|
||
exit 0 | ||
((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } | ||
|
||
set -euo pipefail | ||
|
||
source "tools/codestyle/globals.source" | ||
|
||
function path_under_any_of_dirs() | ||
{ | ||
local path="$1" dir | ||
shift | ||
for dir in "$@"; do | ||
if [[ "${path}" == "${dir}/"* ]]; then | ||
return 0 | ||
fi | ||
done | ||
return 1 | ||
} | ||
|
||
# Files with staged changes that are required to follow the coding style. | ||
function get_staged_files() | ||
{ | ||
local tidy_globs=() dir ext | ||
for dir in "${TIDY_DIRS[@]}"; do | ||
for ext in "${TIDY_EXTENSIONS[@]}"; do | ||
tidy_globs+=("${dir}/*.${ext}") | ||
done | ||
done | ||
|
||
local untidy_dirs=() untidy_path | ||
while IFS= read -r -d '' untidy_path; do | ||
untidy_dirs+=("${untidy_path%/${UNTIDY_FILE}}") | ||
done < <(git ls-files -z -- "*/${UNTIDY_FILE}") | ||
|
||
STAGED_FILES=() | ||
|
||
local file | ||
while IFS= read -r -d '' file; do | ||
if ! path_under_any_of_dirs "${file}" "${untidy_dirs[@]}"; then | ||
STAGED_FILES+=("${file}") | ||
fi | ||
done < <(git diff -z --name-only --cached -- "${tidy_globs[@]}") | ||
|
||
NUM_STAGED="${#STAGED_FILES[@]}" | ||
} | ||
|
||
# Files from STAGED_FILES that also have unstaged changes. Beware, if | ||
# STAGED_FILES is empty then this will return all unstaged files. | ||
function get_unstaged_files() | ||
{ | ||
UNSTAGED_FILES=() | ||
|
||
while IFS= read -r -d '' unstaged_file; do | ||
UNSTAGED_FILES+=("${unstaged_file}") | ||
done < <(git diff -z --name-only -- "${STAGED_FILES[@]}") | ||
|
||
NUM_UNSTAGED="${#UNSTAGED_FILES[@]}" | ||
} | ||
|
||
exit_status=0 | ||
|
||
get_staged_files | ||
|
||
if ((${NUM_STAGED} == 0)); then | ||
echo >&2 "$0: Nothing to do." | ||
exit 0 | ||
fi | ||
|
||
get_unstaged_files | ||
|
||
echo >&2 "$0: Tidying staged files..." | ||
|
||
# Avoid overwriting unstaged changes. | ||
for file in "${UNSTAGED_FILES[@]}"; do | ||
mv "${file}" "${file}.unstaged" | ||
git checkout -- "${file}" | ||
done | ||
|
||
# Begin tidying the staged version of each file. | ||
STAGED_PIDS=() | ||
for file in "${STAGED_FILES[@]}"; do | ||
"tools/codestyle/tidy_file.sh" "${file}" & # Run in background. Must not use Git. | ||
STAGED_PIDS+=( $! ) # store process ID | ||
done | ||
|
||
# Begin tidying the unstaged versions to reduce diff with staged versions. | ||
UNSTAGED_PIDS=() | ||
for file in "${UNSTAGED_FILES[@]}"; do | ||
"tools/codestyle/tidy_file.sh" "${file}.unstaged" & # Run in background. Must not use Git. | ||
UNSTAGED_PIDS+=( $! ) # store process ID | ||
done | ||
|
||
# Once the staged files are tidy, re-stage them. | ||
for idx in "${!STAGED_PIDS[@]}"; do | ||
# Wait for background process to finish | ||
if wait "${STAGED_PIDS[${idx}]}"; then | ||
# Process was successful | ||
file="${STAGED_FILES[${idx}]}" | ||
git add -- "${file}" # Run in foreground to avoid git index conflicts. | ||
else | ||
# Process failed | ||
exit_status=$? | ||
fi | ||
done | ||
|
||
# Once the unstaged files are tidy, restore them. | ||
for idx in "${!UNSTAGED_PIDS[@]}"; do | ||
# Wait for background process to finish | ||
if wait "${UNSTAGED_PIDS[${idx}]}"; then | ||
# Process was successful | ||
file="${UNSTAGED_FILES[${idx}]}" | ||
mv "${file}.unstaged" "${file}" | ||
else | ||
# Process failed | ||
exit_status=$? | ||
fi | ||
done | ||
|
||
if ((${exit_status} == 0)); then | ||
echo >&2 "$0: Tidying complete!" | ||
else | ||
echo >&2 "$0: Errors occured." | ||
fi | ||
|
||
exit ${exit_status} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Source this file in Bash scripts to determine where to enforce the coding style. | ||
|
||
# Files with these extensions follow the coding style. | ||
readonly TIDY_EXTENSIONS=( | ||
# Alphabetical order please! | ||
c | ||
cpp | ||
h | ||
hpp | ||
m | ||
mm | ||
) | ||
|
||
# Files in these directories follow the coding style. | ||
readonly TIDY_DIRS=( | ||
# Alphabetical order please! | ||
src | ||
) | ||
|
||
# Files in containing directory and subdirs don't follow coding style. | ||
readonly UNTIDY_FILE='.untidy' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#!/usr/bin/env bash | ||
|
||
((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } | ||
|
||
set -euo pipefail | ||
|
||
# Call the right command to tidy a file based on purely on its extension. | ||
# For best performance, filter the list of files prior to calling this script. | ||
|
||
# Editors, don't use `git` in this script as it can cause conflicts reading | ||
# the git index when multiple instances of this script are run in parallel. | ||
|
||
HERE="${BASH_SOURCE%/*}" # path to dir that contains this script | ||
|
||
function uncrustify_file() | ||
{ | ||
local file="$1" lang="$2" status | ||
if ! uncrustify -c "${HERE}/uncrustify_musescore.cfg" --no-backup -l "${lang}" "${file}"; then | ||
status=$? | ||
rm -f "${file}.uncrustify" # remove possible temporary file | ||
return ${status} | ||
fi | ||
} | ||
|
||
if (($# != 1)); then | ||
echo >&2 "$0: Error: Too many arguments. Please specify a single file." | ||
exit 255 # make xargs exit early and ensure non-zero status on macOS | ||
fi | ||
|
||
file="$1" | ||
base="${file%.unstaged}" # remove possible '.unstaged' extension (see hooks/pre-commit) | ||
ext="${base##*.}" | ||
|
||
set +e | ||
case "${ext,,}" in | ||
c) uncrustify_file "${file}" 'CPP' ;; | ||
h|cpp|hpp) uncrustify_file "${file}" 'CPP' ;; | ||
m) uncrustify_file "${file}" 'OC' ;; | ||
mm) uncrustify_file "${file}" 'OC+' ;; | ||
*) echo >&2 "Skipping: ${file}" ;; | ||
esac | ||
status=$? | ||
set -e | ||
|
||
if ((${status} != 0)); then | ||
echo >&2 "$0: Error ${status} for ${file}" | ||
exit 255 # make xargs exit early and ensure non-zero status on macOS | ||
fi |
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
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