mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
The `error` variable was set on failure but never reached the exit code, so removal failures such as a locked DLL left `nmake clean` green while stale artifacts remained. Exit with `error` at the end. Since `rd /s` does not set ERRORLEVEL on failure, check the entries remaining after it instead. Also pass `/f` to `del` to remove read-only files as `rm -f` does.
87 lines
2.6 KiB
Batchfile
Executable File
87 lines
2.6 KiB
Batchfile
Executable File
@echo off
|
|
@setlocal EnableExtensions DisableDelayedExpansion || exit /b -1
|
|
|
|
set prog=%~n0
|
|
set dryrun=
|
|
set recursive=
|
|
set debug=
|
|
set error=0
|
|
set parent=
|
|
|
|
:optloop
|
|
if "%1" == "-f" shift
|
|
if "%1" == "-n" (shift & set "dryrun=%1" & goto :optloop)
|
|
if "%1" == "-r" (shift & set "recursive=%1" & goto :optloop)
|
|
if "%1" == "--debug" (shift & set "debug=%1" & set PROMPT=$E[34m+$E[m$S & echo on & goto :optloop)
|
|
:begin
|
|
if "%1" == "" exit /b %error%
|
|
set p=%1
|
|
shift
|
|
set p=%p:/=\%
|
|
call :remove %p%
|
|
goto :begin
|
|
|
|
:remove
|
|
setlocal
|
|
|
|
::- Split %1 by '?' and '*', wildcard characters
|
|
for /f "usebackq delims=?* tokens=1*" %%I in ('%1') do (set "par=%%I" & set "sub=%%J")
|
|
if "%sub%" == "" goto :remove_plain
|
|
if "%sub:\=%" == "%sub%" goto :remove_plain
|
|
::- Extract the first wildcard
|
|
set "q=%1"
|
|
call set "q=%%q:%par%=%%"
|
|
set q=%q:~0,1%
|
|
|
|
::- `delims` chars at the beginning are removed in `for`
|
|
if "%sub:~0,1%" == "\" (
|
|
set "sub=%sub:~1%"
|
|
set "par=%par%%q%"
|
|
) else (
|
|
for /f "usebackq delims=\\ tokens=1*" %%I in ('%sub%') do (set "par=%par%%q%%%I" & set "sub=%%J")
|
|
)
|
|
|
|
::- Recursive search
|
|
for /d %%D in (%par%) do (
|
|
call :remove %sub% %2%%D\
|
|
)
|
|
goto :remove_end
|
|
:remove_plain
|
|
set p=%2%1
|
|
if not exist "%p%" goto :remove_end
|
|
if not "%dryrun%" == "" (
|
|
echo Removing %p:\=/%
|
|
goto :remove_end
|
|
)
|
|
::- Try `rd` first for symlink to a directory; `del` attemps to remove all
|
|
::- files under the target directory, instead of the symlink itself.
|
|
rd /q "%p%" 2> nul && goto :remove_end
|
|
|
|
::- If matching files and directory exist, remove the files only first.
|
|
del /f /q "%p%" 2> nul
|
|
|
|
::- `del` exits with 0 even when nothing matched, so its result cannot
|
|
::- tell whether directories remain; check if matching entries still
|
|
::- exist instead.
|
|
if not exist "%p%" goto :remove_end
|
|
|
|
::- Unless `-r` option is given, do not remove directories; just fail.
|
|
if not "%recursive%" == "-r" (
|
|
call set error=1
|
|
goto :remove_end
|
|
)
|
|
|
|
::- Remove remained directories recursively.
|
|
for /D %%I in (%p%) do (
|
|
rd /s /q %%I 2> nul
|
|
)
|
|
|
|
::- `rd /s` does not set ERRORLEVEL on failure; check what remains
|
|
::- instead. `if exist "dir\*"` is true even for an empty directory,
|
|
::- so check remaining files and directories separately.
|
|
if not exist "%p%" goto :remove_end
|
|
for %%I in (%p%) do if not exist "%%I\" set error=1
|
|
for /D %%I in (%p%) do if exist "%%I\" set error=1
|
|
:remove_end
|
|
endlocal & set "error=%error%" & goto :EOF
|