Skip to content

Commit f1878ae

Browse files
authored
chore: Enhance fix-indent.sh with usage info and recursion
The script now provides usage instructions and supports recursive indentation fixing for Python files.
1 parent c313559 commit f1878ae

File tree

1 file changed

+161
-2
lines changed

1 file changed

+161
-2
lines changed

fix-indent.sh

Lines changed: 161 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,162 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22

3-
find * -type f -name "*.py" -print0 | xargs -0 sed -i -e '/^ *$/{N;s/^ *\n\( *\)\(.*\)/\1\n\1\2/}'
3+
usage() {
4+
cat <<'EOF'
5+
Usage:
6+
fix_indent <filename>
7+
Fix a single file in-place.
8+
9+
fix_indent -R <folder>
10+
Recurse through <folder>, fixing all *.py files.
11+
12+
fix_indent -R
13+
Recurse from the current directory, fixing all *.py files.
14+
15+
fix_indent -h
16+
Show this help and exit.
17+
18+
Rules enforced:
19+
- Replace every tab with 4 spaces.
20+
- Collapse multiple blank lines to a single blank line.
21+
- That blank line must be indented to match the immediately following non-blank line.
22+
- Remove blank lines at EOF (no trailing blank lines).
23+
EOF
24+
}
25+
26+
process_file() {
27+
local file="$1"
28+
local tmp
29+
30+
# Only operate on regular files
31+
[[ -f "$file" ]] || return 0
32+
33+
tmp="$(mktemp -- "${file}.fix_indent.XXXXXX")" || {
34+
echo "fix_indent: mktemp failed for: $file" >&2
35+
return 1
36+
}
37+
38+
# AWK filter:
39+
# - Convert tabs to 4 spaces
40+
# - Collapse blank runs to a single indented blank line (indent from next non-blank line)
41+
# - Drop trailing blanks at EOF
42+
# - Preserve CRLF if present
43+
awk '
44+
BEGIN { pending_blank = 0; use_crlf = 0 }
45+
46+
function emit(s) {
47+
if (use_crlf) print s "\r";
48+
else print s;
49+
}
50+
51+
{
52+
s = $0
53+
if (sub(/\r$/, "", s)) use_crlf = 1
54+
55+
gsub(/\t/, " ", s)
56+
57+
# whitespace-only line => treat as blank
58+
if (s ~ /^[ ]*$/) {
59+
pending_blank = 1
60+
next
61+
}
62+
63+
# if we have pending blanks, emit exactly one blank indented to this line
64+
if (pending_blank) {
65+
match(s, /^[ ]*/)
66+
emit(substr(s, RSTART, RLENGTH))
67+
pending_blank = 0
68+
}
69+
70+
emit(s)
71+
}
72+
73+
END {
74+
# If file ends with blanks, emit nothing (no blank lines at/beyond EOF)
75+
}
76+
' "$file" > "$tmp"
77+
78+
if [[ $? -ne 0 ]]; then
79+
echo "fix_indent: awk failed for: $file" >&2
80+
rm -f -- "$tmp"
81+
return 1
82+
fi
83+
84+
# Avoid touching files that would be unchanged
85+
if cmp -s -- "$file" "$tmp"; then
86+
rm -f -- "$tmp"
87+
return 0
88+
fi
89+
90+
# Overwrite in place (preserves mode/owner; updates mtime)
91+
if ! cat -- "$tmp" > "$file"; then
92+
echo "fix_indent: write failed for: $file" >&2
93+
rm -f -- "$tmp"
94+
return 1
95+
fi
96+
97+
rm -f -- "$tmp"
98+
return 0
99+
}
100+
101+
main() {
102+
local recursive=0
103+
local target=""
104+
105+
if [[ $# -eq 0 ]]; then
106+
usage >&2
107+
exit 2
108+
fi
109+
110+
case "$1" in
111+
-h)
112+
usage
113+
exit 0
114+
;;
115+
-R)
116+
recursive=1
117+
shift
118+
if [[ $# -ge 1 ]]; then
119+
target="$1"
120+
shift
121+
else
122+
target="."
123+
fi
124+
if [[ $# -ne 0 ]]; then
125+
usage >&2
126+
exit 2
127+
fi
128+
;;
129+
-*)
130+
usage >&2
131+
exit 2
132+
;;
133+
*)
134+
if [[ $# -ne 1 ]]; then
135+
usage >&2
136+
exit 2
137+
fi
138+
target="$1"
139+
;;
140+
esac
141+
142+
if [[ $recursive -eq 0 ]]; then
143+
# Single file mode
144+
process_file "$target" || exit $?
145+
exit 0
146+
fi
147+
148+
# Recursive mode
149+
if [[ ! -e "$target" ]]; then
150+
echo "fix_indent: path not found: $target" >&2
151+
exit 1
152+
fi
153+
154+
local rc=0
155+
while IFS= read -r -d '' f; do
156+
process_file "$f" || rc=1
157+
done < <(find "$target" -type f -name '*.py' -print0)
158+
159+
exit $rc
160+
}
161+
162+
main "$@"

0 commit comments

Comments
 (0)