Skip to content

Commit

Permalink
init add checkstyle mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
rgraue committed Jul 12, 2023
1 parent 1890f4e commit e5ca674
Show file tree
Hide file tree
Showing 4 changed files with 330 additions and 0 deletions.
160 changes: 160 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
6 changes: 6 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- id: checkstyle-java
name: checkstyle-java
description: ''
entry: ./.scripts/checkstyle-pre-commit.sh
language: script
require_serial: false
138 changes: 138 additions & 0 deletions .scripts/checkstyle-pre-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/bash

# Checkstyle jar artifact
CHECKSTYLE_VERSION="https://github.com/checkstyle/checkstyle/releases/download/checkstyle-10.12.0/checkstyle-10.12.0-all.jar"

# File locations
PRE_COMMIT_DIR=~/.cache/pre-commit/checkstyle
CHECKSTYLE_JAR="checkstyle.jar"
GOOGLE_CHECKS="google_checks.xml"
SUN_CHECKS="sun_checks.xml"
OUTPUT_CACHE="${PRE_COMMIT_DIR}/output_cache.txt"
OUTPUT_FILE="${PRE_COMMIT_DIR}/output.txt"

# script flags and codes
STRICT=false
EXIT_CODE=0

while getopts c:s flag
do
case "${flag}" in
c) CONFIG_ARG=${OPTARG};;
s) STRICT=true;;
*) EXIT_CODE=1;;
esac
done

# if error on script call.
if [ $EXIT_CODE != 0 ]
then
echo "exit"
exit $EXIT_CODE
fi

# make checkstyle dir in pre commit if does not exist
if [ ! -d "${PRE_COMMIT_DIR}" ]
then
echo "caching directory under: ${PRE_COMMIT_DIR}"
mkdir "${PRE_COMMIT_DIR}"
fi

# download checkstyle jar if not found
if [ ! -f "${PRE_COMMIT_DIR}/${CHECKSTYLE_JAR}" ]
then
echo "downloading checkstyle"
curl -o "${PRE_COMMIT_DIR}/${CHECKSTYLE_JAR}" -LJO "${CHECKSTYLE_VERSION}"
fi

# download google checks config if not found
if [ ! -f "${PRE_COMMIT_DIR}/${GOOGLE_CHECKS}" ]
then
echo "downloading google_checks config"
curl -o "${PRE_COMMIT_DIR}/${GOOGLE_CHECKS}" https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/main/resources/google_checks.xml
fi

# download sun checks config if not found
if [ ! -f "${PRE_COMMIT_DIR}/${SUN_CHECKS}" ]
then
echo "downloading sun_checks config"
curl -o "${PRE_COMMIT_DIR}/${SUN_CHECKS}" https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/main/resources/sun_checks.xml

fi

# switch to specify config to use.
# default to sun_checks.xml
case "${CONFIG_ARG}" in
"google") CONFIG_ARG="${GOOGLE_CHECKS}";;
"sun") CONFIG_ARG="${SUN_CHECKS}";;
*) CONFIG_ARG="${SUN_CHECKS}";;

esac

# determine config path
CHECKSTYLE_CONFIG="${PRE_COMMIT_DIR}/${CONFIG_ARG}"
echo "running checkstyle using ${CONFIG_ARG} config"

# HERE
# clear old output file.
if [ -f "${OUTPUT_FILE}" ]
then
rm "${OUTPUT_FILE}"
fi

# iterate through checked in java files.
ALL_FILES=$(git diff --cached --name-status)
FILE_STATUS=false
for FILE in $ALL_FILES
do
if [[ "${FILE}" == *.java && $FILE_STATUS = true ]]
then
# HERE
# run checkstyle command on specific file.
echo "linting ${FILE}"
LINT_RESULT=$(java -jar "${PRE_COMMIT_DIR}/${CHECKSTYLE_JAR}" -o "${OUTPUT_CACHE}" -c "${CHECKSTYLE_CONFIG}" "${FILE}" )

cat "${OUTPUT_CACHE}" >> "${OUTPUT_FILE}"
fi

# set status to true if positive change on file.
if [[ "${FILE}" = "D" || "${FILE}" = 'R'* ]]
then
FILE_STATUS=false
else
FILE_STATUS=true
fi
done

# HERE
# cleanup output cache
if [ -f "${OUTPUT_CACHE}" ]
then
rm "${OUTPUT_CACHE}"
fi

# Filter all checkstyle output
ERRORS=0
while read line; do
# parse output lines
if [[ "${line}" == '[ERROR]'* ]]
then
ERRORS=$((ERRORS + 1))
echo "${line}"
fi

# if STRICT set WARN as error
if [[ "${line}" == '[WARN]'* && $STRICT = true ]]
then
ERRORS=$((ERRORS + 1))
echo "${line}"
fi
done < "${OUTPUT_FILE}"

# if any errors set exit code to failing
if [ $ERRORS -gt 0 ]
then
EXIT_CODE=1
fi

exit $EXIT_CODE
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# pre-commit-mirror-checkstyle

A mirror of the checkstyle linting tool for use in pre-commit hooks

## Usage

Add the following code to your repo's `.pre-commit-config.yaml`

> `- hooks:`
`- id: checkstyle-java`
`repo: https://github.com/rgraue/pre-commit-mirror-checkstyle`
`rev: v0.1.15`

## Options

**Config** `-c`

- Specify the config to be used by checkstyle. `google` or `sun` only. Points to [google_checks](https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/main/resources/google_checks.xml) and [sun_checks](https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/main/resources/sun_checks.xml) respectively.

**Strict** `-s`

- Specify whether to fail on `[WARN]` (warnings) as well during linting. *Default False*

## Notes

`pre-commit` does not officially support **java** hooks. Java must be installed locally, and checkstyle jar and subsequent files will be saved under `~/.cache/pre-commit/checkstyle`. Files and configs will be installed during first run of hook.

0 comments on commit e5ca674

Please sign in to comment.