Skip to content

Commit 0d4cdfc

Browse files
authored
build: add --fix option for check-whitespace (#59118)
Help agents (and humans) to solve whitespace quicker. New options include to try fixing issues before checking for errors that cannot be automatically fixed (tabs in the middle of lines) and the ability to pass specific files as arguments (particularly for testing this script or for files that aren't yet in git). Partially written by Claude.
1 parent ebf55c0 commit 0d4cdfc

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ will not be reflected, unless you use `Revise`.
1919

2020
## For all changes
2121

22-
1. Run `make check-whitespace` before creating the PR to make sure you're not committing any whitespace errors.
22+
1. Run `make fix-whitespace` before creating the PR to make sure you're not committing any whitespace errors.
2323

2424
## Building Julia
2525

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ else
136136
$(warn "Skipping whitespace check because git is unavailable")
137137
endif
138138

139+
fix-whitespace:
140+
ifneq ($(NO_GIT), 1)
141+
@# Append the directory containing the julia we just built to the end of `PATH`,
142+
@# to give us the best chance of being able to run this check.
143+
@PATH="$(PATH):$(dir $(JULIA_EXECUTABLE))" julia $(call cygpath_w,$(JULIAHOME)/contrib/check-whitespace.jl) --fix
144+
else
145+
$(warn "Skipping whitespace fix because git is unavailable")
146+
endif
147+
139148
release-candidate: release testall
140149
@$(JULIA_EXECUTABLE) $(JULIAHOME)/contrib/add_license_to_files.jl #add license headers
141150
@#Check documentation
@@ -686,7 +695,7 @@ distcleanall: cleanall
686695
@-$(MAKE) -C $(BUILDROOT)/doc cleanall
687696

688697
.FORCE:
689-
.PHONY: .FORCE default debug release check-whitespace release-candidate \
698+
.PHONY: .FORCE default debug release check-whitespace fix-whitespace release-candidate \
690699
julia-debug julia-release julia-stdlib julia-deps julia-deps-libs \
691700
julia-cli-release julia-cli-debug julia-src-release julia-src-debug \
692701
julia-symlink julia-base julia-sysimg julia-sysimg-ji julia-sysimg-release julia-sysimg-debug \

contrib/check-whitespace.jl

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,39 @@ allow_tabs(path) =
3232
endswith(path, "test/syntax.jl") ||
3333
endswith(path, "test/triplequote.jl")
3434

35-
const errors = Set{Tuple{String,Int,String}}()
36-
3735
function check_whitespace()
38-
for path in eachline(`git ls-files -- $patterns`)
36+
# Get file list from ARGS if provided, otherwise use git ls-files
37+
errors = Set{Tuple{String,Int,String}}()
38+
files_to_check = filter(arg -> arg != "--fix", ARGS)
39+
if isempty(files_to_check)
40+
files_to_check = eachline(`git ls-files -- $patterns`)
41+
end
42+
43+
files_fixed = 0
44+
if "--fix" in ARGS
45+
for path in files_to_check
46+
content = newcontent = read(path, String)
47+
isempty(content) && continue
48+
if !allow_tabs(path)
49+
tabpattern = r"^([ \t]+)"m => (x -> replace(x, r"((?: {4})*)( *\t)" => s"\1 ")) # Replace tab sequences at start of line after any number of 4-space groups
50+
newcontent = replace(newcontent, tabpattern)
51+
end
52+
newcontent = replace(newcontent,
53+
r"\s*$" => '\n', # Remove trailing whitespace and normalize line ending at eof
54+
r"\s*?[\r\n]" => '\n', # Remove trailing whitespace and normalize line endings on each line
55+
r"\xa0" => ' ' # Replace non-breaking spaces
56+
)
57+
if content != newcontent
58+
write(path, newcontent)
59+
files_fixed += 1
60+
end
61+
end
62+
if files_fixed > 0
63+
println(stderr, "Fixed whitespace issues in $files_fixed files.")
64+
end
65+
end
66+
67+
for path in files_to_check
3968
lineno = 0
4069
non_blank = 0
4170

0 commit comments

Comments
 (0)