pre-commmit Configuration for NWChemEx
pre-commmit is a tool for configuring and automating githooks, which are a series of hooks for inserting custom automations into git’s operations. The pre-commit tool takes its name from arguably the most commonly used githook, the pre-commit hook, that runs when a user attempts to commit changes. The pre-commit tool provides a simplified syntax for configuring githooks, and has a community of defined hooks from which to draw. To simplify the process of formatting/linting, we advise developers to use pre-commit as outlined in the following when working within the NWX stack.
The NWX configuration for pre-commit (.pre-commit-config.yaml
) lives in
NWChemEx/pre-commit-config.
Normally, this YAML file would be expected to live in the root directory of the
repository where pre-commit would be used. NWX is made up of a number of
different libraries in different repositories, so we find it helpful to keep
the configuration file in a centralized location. This methodology does cause
some deviation from the default usage of pre-commit, but not excessively so.
The first step is to clone NWChemEx/pre-commit-config
git clone https://github.com/NWChemEx/pre-commit-config.git
It is recommended to use a Python virtual environment when developing NWX libraries (see Python Development Workflow for more details). In a new or existing Python virtual environment, install the required packages for pre-commit:
cd pre-commit-config
# Make a virtual environment if one doesn't already exist
python3 -m venv .venv
# Activate the virtual environment and install the requirements
. .venv/bin/activate
pip install -r requirements.txt
cd ../
When you clone a new repository, you will need to install the pre-commit hooks for them to take effect. Assuming for the moment that you want to develop code within the PluginPlay library, you would clone that repo and install the pre-commit hooks as follows:
# Clone PluginPlay
git clone https://github.com/NWChemEx/PluginPlay.git
# Activate a Python virtual environment where pre-commit is installed
. {path/to/}.venv/bin/activate
# Navigate into the repository where you want to install the hooks
cd PluginPlay
# Finally, install the pre-commit hooks
pre-commit install -c {path/to/}pre-commit-config/.pre-commit-config.yaml
At this point, the pre-commit hooks are installed and will run when a git
commit
is attempted. If all hooks pass successfully, the commit should finish
successfully and you should see an output similar to the following:
trim trailing whitespace.................................................Passed
check for added large files..............................................Passed
check python ast.....................................(no files to check)Skipped
check json...........................................(no files to check)Skipped
check for merge conflicts................................................Passed
check xml............................................(no files to check)Skipped
check yaml...........................................(no files to check)Skipped
debug statements (python)............................(no files to check)Skipped
fix end of files.........................................................Passed
fix requirements.txt.................................(no files to check)Skipped
mixed line ending........................................................Passed
yapf.................................................(no files to check)Skipped
clang-format.........................................(no files to check)Skipped
license-eye..............................................................Passed
When one or more hooks fail, the commit will fail and the failing hooks will be noted in the printout:
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook
Fixing docs/source/conventions/pre_commit.rst
check for added large files..............................................Passed
check python ast.....................................(no files to check)Skipped
check json...........................................(no files to check)Skipped
check for merge conflicts................................................Passed
check xml............................................(no files to check)Skipped
check yaml...........................................(no files to check)Skipped
debug statements (python)............................(no files to check)Skipped
fix end of files.........................................................Failed
- hook id: end-of-file-fixer
- exit code: 1
- files were modified by this hook
Fixing docs/source/conventions/pre_commit.rst
fix requirements.txt.................................(no files to check)Skipped
mixed line ending........................................................Passed
yapf.................................................(no files to check)Skipped
clang-format.........................................(no files to check)Skipped
license-eye..............................................................Passed
When most hooks fail, they will also make the requisite changes to the
corresponding files to allow them to pass. These new changes will need to be
staged for commit via git add .
or equivalent, at which time the commit can
be attempted again.
It is also possible to manually run the pre-commit hooks:
# With appropriate virtual environment active
pre-commit run --all-files -c {path/to/}pre-commit-config/.pre-commit-config.yaml
Note, it is required to pass the
-c {path/to/}pre-commit-config/.pre-commit-config.yaml
flag each time this
command is run, even if the pre-commit hooks have already been installed. To
simplify this call, the developer may want to define an alias for this command
in their shell configuration. For the bash shell, this could be
alias run_nwx_precommit="pre-commit run --all-files -c {path/to/}pre-commit-config/.pre-commit-config.yaml"
If at any point you want to remove the installed pre-commit hooks, you can run
pre-commit uninstall
within the repo where you want to remove the hooks.