Skip to content

Commit

Permalink
Enhancements to diff script (#5460)
Browse files Browse the repository at this point in the history
* Output diff for prettier format

* Allow selective formatting

* report progress when formatting cpp files

* document

---------

Co-authored-by: Yong He <[email protected]>
  • Loading branch information
expipiplus1 and csyonghe authored Oct 30, 2024
1 parent 90bde47 commit a98fb6c
Showing 1 changed file with 75 additions and 19 deletions.
94 changes: 75 additions & 19 deletions extras/formatting.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,33 @@ source_dir="$(dirname "$script_dir")"

check_only=0
no_version_check=0
run_cpp=0
run_yaml=0
run_sh=0
run_cmake=0
run_all=1

while [[ "$#" -gt 0 ]]; do
case $1 in
-h | --help) help=1 ;;
--check-only) check_only=1 ;;
--no-version-check) no_version_check=1 ;;
--cpp)
run_cpp=1
run_all=0
;;
--yaml)
run_yaml=1
run_all=0
;;
--sh)
run_sh=1
run_all=0
;;
--cmake)
run_cmake=1
run_all=0
;;
--source)
source_dir="$2"
shift
Expand All @@ -26,12 +47,16 @@ if [ "$help" ]; then
cat <<EOF
$me: Format or check formatting of files in this repo
Usage: $me [--check-only] [--no-version-check] [--source <path>]
Usage: $me [--check-only] [--no-version-check] [--source <path>] [--cpp] [--yaml] [--sh] [--cmake]
Options:
--check-only Check formatting without modifying files
--no-version-check Skip version compatibility checks
--source Path to source directory to format (defaults to parent of script directory)
--source Path to source directory to format (defaults to parent of script directory)
--cpp Format only C++ files
--yaml Format only YAML/JSON files
--sh Format only shell script files
--cmake Format only CMake files
EOF
exit 0
fi
Expand All @@ -45,7 +70,7 @@ require_bin() {
local version

if ! command -v "$name" &>/dev/null; then
echo "This script needs $name, but it isn't in \$PATH"
echo "This script needs $name, but it isn't in \$PATH" >&2
missing_bin=1
return
fi
Expand All @@ -54,14 +79,14 @@ require_bin() {
version=$("$name" --version | grep -oP "\d+\.\d+\.?\d*" | head -n1)

if ! printf '%s\n%s\n' "$min_version" "$version" | sort -V -C; then
echo "$name version $version is too old. Version $min_version or newer is required."
echo "$name version $version is too old. Version $min_version or newer is required." >&2
missing_bin=1
return
fi

if [ -n "$max_version" ]; then
if ! printf '%s\n%s\n' "$version" "$max_version" | sort -V -C; then
echo "$name version $version is too new. Version less than $max_version is required."
echo "$name version $version is too new. Version less than $max_version is required." >&2
missing_bin=1
return
fi
Expand All @@ -84,7 +109,7 @@ fi
exit_code=0

cmake_formatting() {
echo "Formatting CMake files..."
echo "Formatting CMake files..." >&2

readarray -t files < <(git ls-files '*.cmake' 'CMakeLists.txt' '**/CMakeLists.txt')

Expand All @@ -102,47 +127,78 @@ cmake_formatting() {
fi
}

track_progress() {
# Don't output the progress bar if stderr isn't a terminal, just eat all the input
[ -t 2 ] || {
cat >/dev/null
return
}

local total=$1
local current=0

while IFS= read -r _; do
((current++)) || :
percent=$((current * 100 / total))
printf '\rProgress: [%-50s] %d%%' "$(printf '#%.0s' $(seq 1 $((percent / 2))))" "$percent" >&2
done
echo >&2
}

cpp_formatting() {
echo "Formatting cpp files..."
echo "Formatting cpp files..." >&2

readarray -t files < <(git ls-files '*.cpp' '*.hpp' '*.c' '*.h' ':!external/**')

# The progress reporting is a bit sneaky, we use `--verbose` with xargs which
# prints a line to stderr for each command, and we simply count these...

if [ "$check_only" -eq 1 ]; then
local tmpdir
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT

printf '%s\n' "${files[@]}" | xargs -P "$(nproc)" -I{} bash -c "
printf '%s\n' "${files[@]}" | xargs --verbose -P "$(nproc)" -I{} bash -c "
mkdir -p \"\$(dirname \"$tmpdir/{}\")\"
diff -u --color=always --label \"{}\" --label \"{}\" \"{}\" <(clang-format \"{}\") > \"$tmpdir/{}\"
diff -u --color=always --label \"{}\" --label \"{}\" \"{}\" <(clang-format \"{}\") > \"$tmpdir/{}\"
:
"
" |& track_progress ${#files[@]}

for file in "${files[@]}"; do
# Fail if any of the diffs have contents
if [ -s "$tmpdir/$file" ]; then
cat "$tmpdir/$file"
exit_code=1
fi
done
else
printf '%s\n' "${files[@]}" | xargs -n1 -P "$(nproc)" clang-format -i
printf '%s\n' "${files[@]}" | xargs --verbose -n1 -P "$(nproc)" clang-format -i |&
track_progress ${#files[@]}
fi
}

yaml_json_formatting() {
echo "Formatting yaml and json files..."
echo "Formatting yaml and json files..." >&2

readarray -t files < <(git ls-files "*.yaml" "*.yml" "*.json" ':!external/**')

if [ "$check_only" -eq 1 ]; then
prettier --check "${files[@]}" || exit_code=1
for file in "${files[@]}"; do
if ! output=$(prettier "$file" 2>/dev/null); then
continue
fi
if ! diff -q "$file" <(echo "$output") >/dev/null 2>&1; then
diff --color -u --label "$file" --label "$file" "$file" <(echo "$output")
exit_code=1
fi
done
else
prettier --write "${files[@]}" | grep -v '(unchanged)' || :
prettier --write "${files[@]}" | grep -v '(unchanged)' >&2 || :
fi
}

sh_formatting() {
echo "Formatting sh files..."
echo "Formatting sh files..." >&2

readarray -t files < <(git ls-files "*.sh")

Expand All @@ -158,9 +214,9 @@ sh_formatting() {
fi
}

cmake_formatting
cpp_formatting
yaml_json_formatting
sh_formatting
((run_all || run_sh)) && sh_formatting
((run_all || run_cmake)) && cmake_formatting
((run_all || run_yaml)) && yaml_json_formatting
((run_all || run_cpp)) && cpp_formatting

exit $exit_code

0 comments on commit a98fb6c

Please sign in to comment.