3trap 'echo "Interrupted."; exit 1' INT
6 echo "Usage: $(basename "$0") [--changed] [-h|--help] [FILES_OR_DIRS...]"
8 echo " --changed Only process modified files (master or MR target branch as reference)"
9 echo " -h, --help Show this help message"
10 echo " FILES_OR_DIRS List of files or directories to process"
17while [[ "$#" -gt 0 ]]; do
26 echo "Unknown option: $1" >&2
36# file extensions to include
37extensions=(c cpp cc h hh hpp)
39# If --changed is given without files/dirs, use default targets
40if $only_changed && [[ "${#targets[@]}" -eq 0 ]]; then
41 targets=(software examples documentation benchmarks tests)
44if [[ "${#targets[@]}" -eq 0 ]]; then
45 echo "Error: No files or directories specified."
49target_branch="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-master}"
51 echo "Checking connection to remote 'origin'..."
52 if git ls-remote --exit-code --heads origin "$target_branch" &>/dev/null; then
53 echo "Updating local sync of the target branch: $target_branch"
54 git fetch origin "$target_branch"
56 echo "Warning: Could not reach remote 'origin'. Skipping fetch (offline?)."
60# Generate `find`-compatible args: ( -name "*.c" -o -name "*.cpp" ...)
62for ext in "${extensions[@]}"; do
63 find_exts_args+=(-name "*.${ext}" -o)
65unset 'find_exts_args[${#find_exts_args[@]}-1]' # Remove trailing -o
66find_exts_args=( \( "${find_exts_args[@]}" \) )
68# Generate Bash regex: \.(c|cpp|cc|h|hh|hpp)$
69bash_regex="\.($(IFS='|'; echo "${extensions[*]}"))\$"
73for target in "${targets[@]}"; do
74 if [[ -d "$target" ]]; then
75 echo "Scanning directory: $target"
77 if $only_changed; then
79 (git diff --name-only "origin/$target_branch...HEAD"; \
80 git diff --name-only --cached; \
81 git diff --name-only) | sort -u)
82 while IFS= read -r file; do
83 [[ -f "$file" && "$file" == $target/* && "$file" =~ $bash_regex ]] && files+=("$file")
84 done <<< "$changed_files"
86 while IFS= read -r line; do
88 done < <(find "$target" -type f "${find_exts_args[@]}")
90 elif [[ -f "$target" && "$target" =~ $bash_regex ]]; then
93 echo "Skipping unsupported or non-existent target: $target"
97 for file in "${files[@]}"; do
99 output=$(emacs --batch -q --no-site-file --no-site-lisp --eval='
101 (defun indent-whole-buffer ()
102 (let ((inhibit-message t))
103 (indent-region (point-min) (point-max))))
104 (let ((file (car command-line-args-left)))
107 (setq indent-tabs-mode nil)
109 (indent-whole-buffer)
110 (if (buffer-modified-p)
114 (message "no changes")))
118 if [[ "$output" == fixed ]]; then
124if [[ "$modified" -eq 1 ]]; then
125 echo "One or more files were modified!"