forked from Serial-Studio/Serial-Studio
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsanitize-commit.sh
More file actions
executable file
·150 lines (130 loc) · 4.34 KB
/
sanitize-commit.sh
File metadata and controls
executable file
·150 lines (130 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/bin/bash
#
# sanitize-commit.sh — Clean up and prepare Git commits
#
# This script:
# - Normalizes file permissions on tracked files
# - Runs clang-format on source files
# - Shows a list of changed files
# - Enforces Conventional Commit messages
# - Optionally commits and pushes changes
#
# Intended to be run from the root of the repository.
#
# License: GNU General Public License v3.0
# https://www.gnu.org/licenses/gpl-3.0.html
#
# Author: Alex Spataru <https://github.com/alex-spataru>
#
# Usage:
# ./sanitize-commit.sh
# Ensure we're running in bash, not sh/dash or zsh
if [ -z "$BASH_VERSION" ]; then
echo "Error: This script requires bash. Run it with './sanitize-commit.sh' or 'bash sanitize-commit.sh'" >&2
exit 1
fi
# Fail fast on errors, undefined vars, or broken pipelines
set -euo pipefail
# Go to the root of the git repo
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT" || exit 1
# Create a temp file with the list of tracked files
tempfile=$(mktemp)
git ls-files -z > "$tempfile"
# Get the name of this script so we can exclude it from chmod operation
SCRIPT_NAME="$(basename "$0")"
# Set standard file permissions for everything except this script
echo "Sanitizing file permissions..."
while IFS= read -r -d '' file; do
if [[ "$(basename "$file")" == "$(basename "$0")" ]]; then
continue
fi
if [[ -f "$file" && "$file" == *.sh ]]; then
chmod 755 "$file"
elif [[ -f "$file" ]]; then
chmod 644 "$file"
fi
[[ -d "$file" ]] && chmod 755 "$file"
done < "$tempfile"
# Clean up the temporary file after use
rm -f "$tempfile"
# Rejoin broken C/C++ string literals that fit on one line
#echo "Rejoining broken string literals..."
#for dir in app doc examples; do
# if [[ -d "$dir" ]]; then
# find "$dir" -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.c' \) \
# ! -name 'miniaudio.h' \
# -print0 | while IFS= read -r -d '' file; do
# python3 -c "
#import re, sys
#with open(sys.argv[1], 'r') as f:
# content = f.read()
## Rejoin adjacent string literals split across lines
## Matches: \"...\" (optional whitespace/newline) \"...\"
#joined = re.sub(r'\"\s*\n\s*\"', '', content)
#if joined != content:
# with open(sys.argv[1], 'w') as f:
# f.write(joined)
# print(f' Rejoined strings in {sys.argv[1]}')
#" "$file"
# done
# fi
#done
# Format C/C++ files under known directories
echo "Running clang-format..."
for dir in app doc examples; do
if [[ -d "$dir" ]]; then
find "$dir" -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.c' \) \
! -name 'miniaudio.h' \
-print0 | xargs -0 clang-format -i || echo "clang-format failed in $dir"
fi
done
# Get a list of changed files (unstaged + staged)
echo "Checking for changes..."
CHANGED=$(git status --short)
# If nothing changed, we're done
if [[ -z "$CHANGED" ]]; then
echo "No changes detected."
exit 0
fi
# Show the user what changed
echo
echo "Changed files:"
git status --short
echo
# Count how many files changed (staged if any, otherwise unstaged)
COUNT=$(git diff --cached --name-only | wc -l)
[[ "$COUNT" -eq 0 ]] && COUNT=$(git diff --name-only | wc -l)
echo "$COUNT file(s) changed."
# Ask user whether to proceed with committing and pushing
read -rp "Do you want to commit and push these changes? [y/N] " ANSWER
ANSWER_LOWER=$(echo "$ANSWER" | tr '[:upper:]' '[:lower:]')
if [[ "$ANSWER_LOWER" != "y" ]]; then
echo "Aborting."
exit 0
fi
# Ask for a Conventional Commit message, and validate it
while true; do
echo
echo "Enter a Conventional Commit message (e.g., 'fix: correct permission issue'):"
read -rp "> " COMMIT_MSG
# Validate message against the conventional commit pattern
if [[ "$COMMIT_MSG" =~ ^(feat|fix|chore|docs|style|refactor|perf|test)(\(.+\))?:\ .+ ]]; then
break
else
echo "Invalid commit message format. Use Conventional Commits (e.g., 'feat: add new thing')."
fi
done
# Stage and commit all changes
git add .
git commit -m "$COMMIT_MSG"
# Ask user if they want to push
BRANCH=$(git rev-parse --abbrev-ref HEAD)
read -rp "Push to origin/$BRANCH? [y/N] " PUSH_CONFIRM
PUSH_CONFIRM_LOWER=$(echo "$PUSH_CONFIRM" | tr '[:upper:]' '[:lower:]')
if [[ "$PUSH_CONFIRM_LOWER" == "y" ]]; then
git push origin "$BRANCH"
echo "Changes pushed."
else
echo "Changes committed but not pushed."
fi