This guide helps contributors set up pre-commit hooks for the bash-logger project. Pre-commit hooks automatically check your code before you commit, catching issues early and ensuring pipeline checks pass before you submit pull requests.
- Quick Start (Recommended)
- What Pre-commit Does
- Manual Installation (Alternative)
- Common Commands
- CI integration
- Troubleshooting
- Understanding Hook Failures
- Hook Configuration
- Integration with CI/CD
- For Maintainers: Managing Pre-commit
- Additional Resources
- Questions?
If you have Python 3 installed, the easiest way is to run our setup script:
./scripts/setup-precommit.shThe script will:
- Check for required dependencies (Python and pip)
- Install the pre-commit framework
- Configure git hooks from
.pre-commit-config.yaml - Run checks on existing files (optional)
- Provide next steps and useful commands
That's it! You're done. Pre-commit hooks are now active.
Pre-commit hooks run automatically before each commit. They check:
-
ShellCheck - Validates Bash script syntax and common errors
- Catches syntax errors, undefined variables, incorrect quoting, and more
- Runs on all
.shfiles
-
MarkdownLint - Checks and auto-fixes Markdown formatting
- Automatically fixes formatting issues (blank lines, trailing spaces, etc.)
- For issues that can't be auto-fixed (line length), you'll need to fix manually
- Ensures consistent formatting, proper headings, and link validation
- Runs on all
.mdfiles
-
Bash Logger Tests - Runs the test suite
- Verifies all changes pass the test suite
- Prevents committing broken code
-
Commit Message Format - Validates semantic versioning format
- Ensures commit messages follow the pattern:
<type>(<scope>): <subject> - Enables automated release and version management
- Provides clear feedback if message format is incorrect
- Examples:
feat(logging): add color support,fix: prevent race condition
- Ensures commit messages follow the pattern:
When hooks run and auto-fix formatting (like MarkdownLint), the modified files will be staged and your commit will proceed. If any check fails and can't be auto-fixed, your commit will be blocked until you address the issues.
If you prefer to install manually or the script doesn't work for your setup:
- Python 3.6+ - Download here
- pip - Usually comes with Python 3
-
Install pre-commit framework:
pip install --user pre-commit
-
Make sure pre-commit is in your PATH. If not found, add it:
export PATH="$HOME/.local/bin:$PATH"
-
Install the git hooks:
cd /path/to/gist-bash-logging pre-commit install -
(Optional) Run hooks on all existing files:
pre-commit run --all-files
pre-commit run --all-filespre-commit run shellcheck --all-files
pre-commit run markdownlint --all-files
pre-commit run bash-logger-tests --all-filesIf you need to commit without running hooks (not recommended):
git commit --no-verifypre-commit autoupdatepre-commit uninstallpre-commit installThe GitHub Actions lint workflow runs pre-commit with --all-files, so ShellCheck and MarkdownLint versions come from .pre-commit-config.yaml.
When bumping a hook version, update the config (for example with pre-commit autoupdate) and commit the change; CI will automatically pick it up.
The pre-commit command is not in your PATH. Try:
# Run as a module instead
python -m pre-commit run --all-filesOr add the user bin directory to your PATH. Common locations:
- Linux/Mac:
~/.local/bin - Windows with Python:
%APPDATA%\Python\Python3x\Scripts
MarkdownLint requires Node.js. Install it from nodejs.org
ShellCheck is installed via pip as part of pre-commit setup, but sometimes it needs the Python environment. Try:
python -m pip install --upgrade shellcheck-pyFor a single commit:
git commit --no-verifyTo fully disable hooks temporarily:
pre-commit uninstall
# ... make your commits ...
pre-commit installShellCheck finds potential issues in Bash scripts. Review its output and fix the issues. Common ones:
- Undefined variables - use quotes:
"$var"instead of$var - Unquoted variables in conditions
- Using
[instead of[[
See ShellCheck wiki for detailed explanations.
MarkdownLint automatically fixes many formatting issues (blank lines, trailing spaces, etc.). If it fixes issues, the modified files will be staged and your commit will proceed.
However, some issues require manual fixes:
- Line length - Lines exceeding 120 characters must be reworded or restructured
- Content-related issues - Problems that can't be fixed without changing your content
When MarkdownLint blocks your commit due to unfixable issues:
- Review the error messages in the output
- Manually fix the mentioned issues
- Run
pre-commit run markdownlint --all-filesto verify fixes - Try committing again
See MarkdownLint docs for detailed rule explanations.
If tests fail, it means your changes broke existing functionality. Run tests locally:
./tests/run_tests.shCheck the output to understand what's failing and fix accordingly.
If your commit message doesn't follow semantic versioning format, the commit will be blocked with a helpful error message.
Common issues:
- Missing type: Use
feat:,fix:,docs:, etc. at the start - Missing colon: Ensure format is
type(scope): message - Invalid type: Must be one of:
feat,fix,docs,style,refactor,perf,test,chore,ci
To fix:
- Review the error message and examples provided
- Reword your commit message to match the format
- Amend the commit:
git commit --amend - Try committing again
Examples of valid commit messages:
feat(config): add support for custom log format
fix: prevent logger initialization without level
docs: update contribution guidelines
refactor(tests): simplify test runner
chore: update dependencies
See CONTRIBUTING.md for more details on the commit message format and why we use semantic versioning.
The hooks are configured in .pre-commit-config.yaml at the project root.
repos:
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.10.0
hooks:
- id: shellcheck
args: [--severity=warning] # Only fail on warnings and aboverepo- Source of the hookrev- Version to use (update withpre-commit autoupdate)hooks- Specific hooks from that repoargs- Arguments passed to the tool (configuration)
Pre-commit hooks get updates periodically. Keep them current:
pre-commit autoupdateThis updates .pre-commit-config.yaml to use newer versions.
These same checks run in GitHub Actions on every pull request. Setting up pre-commit locally means:
- You catch issues before pushing
- Faster feedback cycle
- Fewer failed pipeline runs
- Better code quality overall
It's a win-win!
Edit .pre-commit-config.yaml and add a new repo/hook section, then commit. Contributors will get the new hook on their next pre-commit install.
pre-commit autoupdateCommits the updated versions to git.
In .pre-commit-config.yaml, add exclude patterns:
- id: shellcheck
exclude: |
(?x)^(
scripts/legacy.*|
demo-scripts/.*
)$- Pre-commit Documentation
- ShellCheck Documentation
- MarkdownLint Rules
- Getting Started with Contributing
If you have issues with pre-commit setup, please:
- Check the troubleshooting section above
- Review the GitHub Issues
- Run with verbose output:
pre-commit run --all-files -v - Open a new issue if you find a bug or have a feature request
Happy contributing! 🚀