Compare commits

...

4 Commits

Author SHA1 Message Date
alejandrobailo
49636274c7 Merge remote-tracking branch 'origin/master' into feat/migrate-to-prek 2026-01-26 19:04:26 +01:00
alejandrobailo
8a38b1cc0e chore: remove benchmark report file
Benchmark data moved to PR description for better visibility.
2026-01-26 18:41:05 +01:00
alejandrobailo
d46f649ff1 feat: migrate from pre-commit to prek
Replace pre-commit with prek, a faster Rust-based alternative that is
7x faster for installation and 6x faster for execution while being
fully compatible with .pre-commit-config.yaml.

Changes:
- Remove pre-commit from pyproject.toml dev dependencies
- Update scripts/setup-git-hooks.sh to use prek
- Update developer documentation (introduction.mdx)
- Update security documentation (software-security.mdx)
- Update AGENTS.md files with new commands
- Regenerate poetry.lock

prek is installed as a standalone tool via:
- pipx install prek (recommended)
- brew install prek
- uv tool install prek

Benchmarks on Prowler codebase:
- Cold install: 25.18s → 3.42s (7.37x faster)
- Warm execution: 87.53s → 14.80s (5.92x faster)
- Cache size: 170MB → 154MB (9.4% smaller)
2026-01-26 18:41:05 +01:00
alejandrobailo
34787659b9 docs: add prek migration benchmark report
Performance comparison between pre-commit 4.5.1 and prek 0.3.0:
- Cold install: 7.37x faster (25.18s → 3.42s)
- Warm execution: 5.92x faster (87.53s → 14.80s)
- Cache size: 9.4% smaller (170MB → 154MB)

All 18 hooks tested with 100% compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 17:57:30 +01:00
7 changed files with 62 additions and 125 deletions

View File

@@ -128,12 +128,12 @@ Prowler is an open-source cloud security assessment tool supporting AWS, Azure,
```bash
# Setup
poetry install --with dev
poetry run pre-commit install
prek install # install git hooks (requires prek: pipx install prek)
# Code quality
poetry run make lint
poetry run make format
poetry run pre-commit run --all-files
prek run --all-files
```
---

View File

@@ -116,18 +116,34 @@ In case you have any doubts, consult the [Poetry environment activation guide](h
</Warning>
### Pre-Commit Hooks
### Git Hooks with prek
This repository uses Git pre-commit hooks managed by the [pre-commit](https://pre-commit.com/) tool, it is installed with `poetry install --with dev`. Next, run the following command in the root of this repository:
This repository uses Git hooks managed by [prek](https://github.com/j178/prek), a fast pre-commit alternative written in Rust. It is ~7x faster than traditional pre-commit while being fully compatible with `.pre-commit-config.yaml`.
Install prek (choose one method):
```shell
pre-commit install
pipx install prek # recommended
# or: brew install prek
# or: uv tool install prek
```
Then run the following command in the root of this repository:
```shell
prek install
```
Successful installation should produce the following output:
```shell
pre-commit installed at .git/hooks/pre-commit
prek hook installed at .git/hooks/pre-commit
```
To run hooks manually on all files:
```shell
prek run --all-files
```
### Code Quality and Security Checks

View File

@@ -4,7 +4,7 @@ title: 'Software Security'
Prowler follows a **security-by-design approach** throughout the software development lifecycle. All changes go through automated checks at every stage, from local development to production deployment.
[Pre-commit](https://github.com/prowler-cloud/prowler/blob/master/.pre-commit-config.yaml) validations catch issues early, and [CI/CD pipelines](https://github.com/prowler-cloud/prowler/tree/master/.github) include multiple security gates ensuring code quality, secure configurations, and compliance with internal standards.
[Git hooks](https://github.com/prowler-cloud/prowler/blob/master/.pre-commit-config.yaml) (managed by [prek](https://github.com/j178/prek), a fast pre-commit alternative) catch issues early, and [CI/CD pipelines](https://github.com/prowler-cloud/prowler/tree/master/.github) include multiple security gates ensuring code quality, secure configurations, and compliance with internal standards.
Container registries are continuously scanned for vulnerabilities, with findings automatically reported to the security team for assessment and remediation. This process evolves alongside the stack as new languages, frameworks, and technologies are adopted, ensuring security practices remain comprehensive, proactive, and adaptable.
@@ -25,7 +25,7 @@ Multiple SAST tools are employed across the codebase to identify security vulner
- Configured to ignore test files and report only high-severity issues
- Runs on both SDK and API codebases
- **Pylint:** Static code analysis with security-focused checks
- Integrated into pre-commit hooks and CI/CD pipelines
- Integrated into git hooks (prek) and CI/CD pipelines
### Code Quality & Dead Code Detection
@@ -40,7 +40,7 @@ Dependencies are continuously monitored for known vulnerabilities with timely up
### Dependency Vulnerability Scanning
- **Safety:** Scans Python dependencies against known vulnerability databases
- Runs on every commit via pre-commit hooks
- Runs on every commit via git hooks (prek)
- Integrated into CI/CD for SDK and API
- Configured with selective ignores for tracked exceptions
- **Trivy:** Multi-purpose scanner for containers and dependencies
@@ -82,7 +82,7 @@ Prowler protects against accidental exposure of sensitive credentials.
- Scans entire codebase and Git history for secrets
- Runs on every push and pull request
- Pre-commit hook prevents committing secrets
- Git hook (prek) prevents committing secrets
- Detects high-entropy strings, API keys, tokens, and credentials
- Configured to report verified and unknown findings

93
poetry.lock generated
View File

@@ -1675,18 +1675,6 @@ files = [
[package.dependencies]
pycparser = {version = "*", markers = "implementation_name != \"PyPy\""}
[[package]]
name = "cfgv"
version = "3.4.0"
description = "Validate configuration and produce human readable error messages."
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
{file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
]
[[package]]
name = "cfn-lint"
version = "1.38.0"
@@ -2176,18 +2164,6 @@ files = [
graph = ["objgraph (>=1.7.2)"]
profile = ["gprof2dot (>=2022.7.29)"]
[[package]]
name = "distlib"
version = "0.4.0"
description = "Distribution utilities"
optional = false
python-versions = "*"
groups = ["dev"]
files = [
{file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"},
{file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"},
]
[[package]]
name = "distro"
version = "1.9.0"
@@ -2836,21 +2812,6 @@ files = [
{file = "iamdata-0.1.202507281.tar.gz", hash = "sha256:4050870068ca2fb044d03c46229bc8dbafb4f99db2f50c77297aafd437154ddd"},
]
[[package]]
name = "identify"
version = "2.6.12"
description = "File identification library for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2"},
{file = "identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6"},
]
[package.extras]
license = ["ukkonen"]
[[package]]
name = "idna"
version = "3.10"
@@ -3974,18 +3935,6 @@ plot = ["matplotlib"]
tgrep = ["pyparsing"]
twitter = ["twython"]
[[package]]
name = "nodeenv"
version = "1.9.1"
description = "Node.js virtual environment builder"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
groups = ["dev"]
files = [
{file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
{file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
]
[[package]]
name = "numpy"
version = "2.0.2"
@@ -4372,25 +4321,6 @@ files = [
{file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"},
]
[[package]]
name = "pre-commit"
version = "4.2.0"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd"},
{file = "pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146"},
]
[package.dependencies]
cfgv = ">=2.0.0"
identify = ">=1.0.0"
nodeenv = ">=0.11.1"
pyyaml = ">=5.1"
virtualenv = ">=20.10.0"
[[package]]
name = "propcache"
version = "0.3.2"
@@ -6151,27 +6081,6 @@ h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
[[package]]
name = "virtualenv"
version = "20.32.0"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "virtualenv-20.32.0-py3-none-any.whl", hash = "sha256:2c310aecb62e5aa1b06103ed7c2977b81e042695de2697d01017ff0f1034af56"},
{file = "virtualenv-20.32.0.tar.gz", hash = "sha256:886bf75cadfdc964674e6e33eb74d787dff31ca314ceace03ca5810620f4ecf0"},
]
[package.dependencies]
distlib = ">=0.3.7,<1"
filelock = ">=3.12.2,<4"
platformdirs = ">=3.9.1,<5"
[package.extras]
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""]
[[package]]
name = "vulture"
version = "2.14"
@@ -6614,4 +6523,4 @@ files = [
[metadata]
lock-version = "2.1"
python-versions = ">3.9.1,<3.13"
content-hash = "adfc2da2c6e3e803f7a151b9697dbc3f461366a03e4504eb97498cbc72b2e48c"
content-hash = "fa93b6512bcc3e5938b54510d2fe320c3c2b957cb0a03ea5d39df550eb65aaa0"

View File

@@ -109,7 +109,7 @@ prowler/
```bash
# Setup
poetry install --with dev
poetry run pre-commit install
prek install # install git hooks (requires prek: pipx install prek)
# Run Prowler
poetry run python prowler-cli.py {provider}
@@ -121,7 +121,7 @@ poetry run pytest -n auto -vvv tests/
poetry run pytest tests/providers/{provider}/services/{service}/ -v
# Code Quality
poetry run pre-commit run --all-files
prek run --all-files
```
---
@@ -142,7 +142,7 @@ poetry run pre-commit run --all-files
## QA CHECKLIST
- [ ] `poetry run pytest` passes
- [ ] `poetry run pre-commit run --all-files` passes
- [ ] `prek run --all-files` passes
- [ ] Check metadata JSON is valid
- [ ] Tests cover PASS, FAIL, and empty resource scenarios
- [ ] Docstrings follow Google style

View File

@@ -121,7 +121,8 @@ mock = "5.2.0"
moto = {extras = ["all"], version = "5.1.11"}
openapi-schema-validator = "0.6.3"
openapi-spec-validator = "0.7.1"
pre-commit = "4.2.0"
# Note: prek (pre-commit alternative) is installed as a standalone tool via pipx/brew
# See: https://github.com/j178/prek
pylint = "3.3.4"
pytest = "8.3.5"
pytest-cov = "6.0.0"

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Setup Git Hooks for Prowler
# This script installs pre-commit hooks using the project's Poetry environment
# This script installs git hooks using prek (fast pre-commit alternative)
set -e
@@ -23,13 +23,6 @@ if ! git rev-parse --git-dir >/dev/null 2>&1; then
exit 1
fi
# Check if Poetry is installed
if ! command -v poetry &>/dev/null; then
echo -e "${RED}❌ Poetry is not installed${NC}"
echo -e "${YELLOW} Install Poetry: https://python-poetry.org/docs/#installation${NC}"
exit 1
fi
# Check if pyproject.toml exists
if [ ! -f "pyproject.toml" ]; then
echo -e "${RED}❌ pyproject.toml not found${NC}"
@@ -37,31 +30,49 @@ if [ ! -f "pyproject.toml" ]; then
exit 1
fi
# Check if dependencies are already installed
if ! poetry run python -c "import pre_commit" 2>/dev/null; then
echo -e "${YELLOW}📦 Installing project dependencies (including pre-commit)...${NC}"
poetry install --with dev
else
echo -e "${GREEN}${NC} Dependencies already installed"
# Check if prek is installed, if not try to install it
if ! command -v prek &>/dev/null; then
echo -e "${YELLOW}📦 prek not found, attempting to install...${NC}"
if command -v pipx &>/dev/null; then
pipx install prek
elif command -v uv &>/dev/null; then
uv tool install prek
elif command -v brew &>/dev/null; then
brew install prek
else
echo -e "${RED}❌ Could not install prek automatically${NC}"
echo -e "${YELLOW} Install prek manually: https://github.com/j178/prek${NC}"
echo -e "${YELLOW} Options: pipx install prek | brew install prek | uv tool install prek${NC}"
exit 1
fi
fi
echo -e "${GREEN}${NC} prek is installed: $(prek --version)"
echo ""
# Clear any existing core.hooksPath to avoid pre-commit conflicts
# Clear any existing core.hooksPath to avoid conflicts
if git config --get core.hooksPath >/dev/null 2>&1; then
echo -e "${YELLOW}🧹 Clearing existing core.hooksPath configuration...${NC}"
git config --unset-all core.hooksPath
fi
echo -e "${YELLOW}🔗 Installing pre-commit hooks...${NC}"
poetry run pre-commit install
# Uninstall old pre-commit hooks if they exist
if [ -f ".git/hooks/pre-commit" ] && grep -q "pre-commit" ".git/hooks/pre-commit" 2>/dev/null; then
echo -e "${YELLOW}🧹 Removing old pre-commit hooks...${NC}"
pre-commit uninstall 2>/dev/null || true
fi
echo -e "${YELLOW}🔗 Installing prek hooks...${NC}"
prek install
echo ""
echo -e "${GREEN}✅ Git hooks successfully configured!${NC}"
echo ""
echo -e "${YELLOW}📋 Pre-commit system:${NC}"
echo -e " • Python pre-commit manages all git hooks"
echo -e "${YELLOW}📋 prek system (fast pre-commit alternative):${NC}"
echo -e " • prek manages all git hooks (~7x faster than pre-commit)"
echo -e " • API files: Python checks (black, flake8, bandit, etc.)"
echo -e " • UI files: UI checks (TypeScript, ESLint, Claude Code validation)"
echo -e " • Run manually: prek run --all-files"
echo ""
echo -e "${GREEN}🎉 Setup complete!${NC}"
echo ""