如何在Windows批处理文件中集成Checkstyle、PMD、Findbug到SVN预提交钩子?
Hey there! Let's walk through how to set up a Windows batch (.bat) pre-commit hook for VisualSVN Server that runs Checkstyle, PMD, and FindBugs to enforce Java code standards. Since your project is small, this approach should work just fine despite the usual caveats about pre-commit checks.
1. Prerequisites First
Before diving into the script, make sure you have these ready:
- VisualSVN Server up and running with your repository configured
- Checkstyle, PMD, and FindBugs binary packages downloaded and extracted to a fixed path (e.g.,
C:\CodeQualityTools) - Java JDK installed and
java/javaccommands available in your system PATH (test withjava -versionin Command Prompt)
2. Understand SVN Pre-Commit Hook Parameters
VisualSVN passes two mandatory parameters to the pre-commit hook:
%1: Full path to your SVN repository%2: Transaction ID of the pending commit
We'll use svnlook (a built-in SVN tool) to fetch the files being committed and their content.
3. Write the Batch Script
Create a file named pre-commit.bat (save it somewhere safe, like your repository's hooks folder) with the following code. Be sure to adjust the tool paths and configs to match your setup:
@echo off setlocal enabledelayedexpansion :: -------------------------- :: Configure tool paths here :: -------------------------- set CHECKSTYLE_PATH=C:\CodeQualityTools\checkstyle-10.12.6\checkstyle.bat set PMD_PATH=C:\CodeQualityTools\pmd-6.55.0\bin\pmd.bat set FINDBUGS_PATH=C:\CodeQualityTools\findbugs-3.0.1\bin\findbugs.bat set CHECKSTYLE_CONFIG=C:\CodeQualityTools\config\sun_checks.xml # Use your preferred ruleset set PMD_RULES=java-basic,java-design # Adjust PMD rules as needed :: SVN hook input parameters set REPOS=%1 set TXN=%2 :: Temporary directory to store committed Java files (avoids conflicts) set TEMP_DIR=%TEMP%\svn_precommit_%TXN% mkdir "%TEMP_DIR%" 2>nul :: Get list of changed Java files in this commit svnlook changed "%REPOS%" -t "%TXN%" | findstr /i "\.java$" > "%TEMP_DIR%\changed_files.txt" :: Skip checks if no Java files are being committed if not exist "%TEMP_DIR%\changed_files.txt" goto :PASS :: Export each Java file to the temp directory for /f "tokens=2 delims= " %%f in (%TEMP_DIR%\changed_files.txt) do ( svnlook cat "%REPOS%" -t "%TXN%" "%%f" > "%TEMP_DIR%\%%~nxf" ) :: -------------------------- :: Run Checkstyle :: -------------------------- echo Running Checkstyle checks... call "%CHECKSTYLE_PATH%" -c "%CHECKSTYLE_CONFIG%" "%TEMP_DIR%\*.java" > "%TEMP_DIR%\checkstyle_results.txt" if errorlevel 1 ( echo ❌ Checkstyle found violations: type "%TEMP_DIR%\checkstyle_results.txt" goto :FAIL ) :: -------------------------- :: Run PMD :: -------------------------- echo Running PMD checks... call "%PMD_PATH%" check -d "%TEMP_DIR%" -R %PMD_RULES% -f text > "%TEMP_DIR%\pmd_results.txt" if errorlevel 1 ( echo ❌ PMD found violations: type "%TEMP_DIR%\pmd_results.txt" goto :FAIL ) :: -------------------------- :: Run FindBugs (requires compiled class files) :: -------------------------- echo Compiling Java files for FindBugs... mkdir "%TEMP_DIR%\classes" 2>nul javac -d "%TEMP_DIR%\classes" "%TEMP_DIR%\*.java" 2> "%TEMP_DIR%\compile_errors.txt" if errorlevel 1 ( echo ❌ Compilation failed for FindBugs: type "%TEMP_DIR%\compile_errors.txt" goto :FAIL ) echo Running FindBugs checks... call "%FINDBUGS_PATH%" -textui -output "%TEMP_DIR%\findbugs_results.txt" "%TEMP_DIR%\classes" :: Check if FindBugs reported errors/warnings findstr /i "ERROR\|WARN" "%TEMP_DIR%\findbugs_results.txt" >nul if not errorlevel 1 ( echo ❌ FindBugs found issues: type "%TEMP_DIR%\findbugs_results.txt" goto :FAIL ) :: -------------------------- :: All checks passed :: -------------------------- :PASS echo ✅ All code quality checks passed. rmdir /s /q "%TEMP_DIR%" exit 0 :: -------------------------- :: Checks failed - block commit :: -------------------------- :FAIL echo ❌ Pre-commit hook failed: Code does not meet quality standards. rmdir /s /q "%TEMP_DIR%" exit 1
Key Notes About the Script:
- Temporary Directory: Uses the transaction ID to avoid conflicts between concurrent commits.
- FindBugs Quirk: Unlike Checkstyle/PMD, FindBugs needs compiled
.classfiles. The script runsjavacto compile the staged Java files—if your project has dependencies, add a-classpathflag to thejavaccommand pointing to your dependency JARs. - Error Handling: Each tool runs in sequence; if any fails, the script exits with a non-zero code, blocking the commit and showing the error details.
4. Configure the Hook in VisualSVN Server
- Open VisualSVN Server Manager, right-click your repository, and select Properties.
- Switch to the Hooks tab.
- Find the Pre-commit hook section, click Edit.
- Select Execute the following command, then browse to your
pre-commit.batfile. - Check the boxes for Wait for the script to finish and Fail the commit if the script returns a non-zero exit code.
- Click OK to save the configuration.
5. Test It Out
- Try committing a Java file with violations (e.g., a class named
myclassinstead ofMyClass, missing Javadoc). - The commit should be blocked, and you'll see the error output in your SVN client.
- Fix the violations and re-submit—this time it should go through smoothly.
内容的提问来源于stack exchange,提问作者Uvaraj Seerangan

