pyenforce 0.1.0
A comprehensive quality assurance CLI for enforcing strict Python code standards.
License: MIT
Requires Python: >=3.11
Keywords: code-quality, linting, static-analysis, type-checking, security, ruff, mypy, pylint, bandit, semgrep, vulture, pre-commit, ci

<p align="center">
  <img src="https://raw.githubusercontent.com/HH-MWB/pyenforce/main/assets/logo.svg" alt="PyEnforce" width="400"/>
  <br>
  <b>A comprehensive quality assurance CLI for enforcing strict Python code standards.</b>
</p>

**Py**thon **E**nforcer is a command-line tool that wraps industry-standard static analysis tools with curated, strict configurations. It ensures code quality, security, and maintainability by providing a unified interface to run these checks.

## Features

- **Centralized Configuration**: Bundles strict configurations for all supported tools, ensuring consistency across projects.
- **Unified Interface**: Run multiple quality checks using a single command-line tool.
- **Tool Suite**: Integrates six specialized tools:
  - **Ruff**: Linting and formatting.
  - **Mypy**: Static type checking.
  - **Pylint**: Code analysis.
  - **Bandit**: Security linting.
  - **Semgrep**: Static analysis for security and bugs.
  - **Vulture**: Dead code detection.

## Installation

Install `pyenforce` from PyPI (or from source) with the dependencies you need.

### Minimal Install

Installs only the CLI runner. You must install the underlying tools (like `ruff` or `mypy`) separately or have them in your environment.

```bash
pip install pyenforce
```

### Install with Specific Tools

Install `pyenforce` along with specific tools you plan to use.

```bash
# Install with Ruff
pip install "pyenforce[ruff]"

# Install with Mypy
pip install "pyenforce[mypy]"

# Install with multiple tools
pip install "pyenforce[ruff,mypy]"
```

### Install with All Tools

Install the CLI and the complete suite of supported tools.

```bash
pip install "pyenforce[all]"
```

## Usage

Run any of the supported tools using the `pye` command followed by the tool name:

```bash
pye <tool> [args...]
```

### Available Commands

| Tool | Command | Purpose |
|------|---------|---------|
| [Ruff](https://github.com/astral-sh/ruff) | `pye fmt` | Code formatter for consistent code style. |
| [Ruff](https://github.com/astral-sh/ruff) | `pye ruff` | Lightning-fast linter covering style, complexity, and imports. |
| [Mypy](https://github.com/python/mypy) | `pye mypy` | Verifies type hints and catches type errors. |
| [Pylint](https://github.com/pylint-dev/pylint) | `pye pylint` | Analyzes code quality and design patterns. |
| [Bandit](https://github.com/PyCQA/bandit) | `pye bandit` | Detects common security vulnerabilities. |
| [Semgrep](https://github.com/semgrep/semgrep) | `pye semgrep` | Advanced pattern matching for bugs and security issues. |
| [Vulture](https://github.com/jendrikseipp/vulture) | `pye vulture` | Identifies unused code. |

### Examples

Run a specific tool (e.g., Ruff):

```bash
pye ruff
```

Pass additional arguments (e.g., run Mypy on a specific directory):

```bash
pye mypy src/
```

## Pre-commit Usage

To use `pyenforce` with [pre-commit](https://pre-commit.com), add the following to your `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/HH-MWB/pyenforce
    rev: v0.1.0
    hooks:
      - id: ruff-format
      - id: ruff-check
      - id: mypy
      - id: pylint
      - id: bandit
      - id: semgrep
      - id: vulture
```

If you need to add extra dependencies (e.g., plugins) to a hook using `additional_dependencies` in your `.pre-commit-config.yaml`, **you must re-include the base dependency**. `pre-commit` overwrites the list instead of merging it.

Example: Adding a plugin to `pylint`:

```yaml
  - repo: https://github.com/HH-MWB/pyenforce
    rev: v0.1.0
    hooks:
      - id: pylint
        additional_dependencies:
          - ".[pylint]"     # Required: Re-adds Pylint
          - "pylint-django" # Your extra dependency
```

## License

This repository is licensed under the [MIT License](https://github.com/HH-MWB/pyenforce/blob/main/LICENSE).