Skip to main content

Unified code quality orchestration; linters, formatters, type checkers, and security analyzers in one CLI

Project description

Scrutiny

Unified code quality orchestration for Python projects.

Scrutiny runs Ruff (formatter + linter), Mypy, Radon, and Bandit in a single command with tiered strictness, opt-in pyproject.toml generation, context-aware defaults, and structured logging. Scrutiny respects your pyproject.toml as the authoritative source and never modifies it unless you explicitly ask. Configure once, enforce everywhere.

Installation

# All tools
pip install 'ks-scrutiny[all]'

# Specific tools only
pip install 'ks-scrutiny[ruff,mypy]'

# Core package only (install tools separately)
pip install ks-scrutiny

Configuration Precedence

Scrutiny follows a strict priority contract when building tool commands:

  1. Explicit scrutiny CLI overrides win over everything.
  2. pyproject.toml is authoritative when the CLI is silent.
  3. Scrutiny's own defaults only fill in keys neither source has expressed.

Concretely: if you set fix = false under [tool.ruff], scrutiny will not pass --fix to ruff. If you set exclude = [...] under [tool.ruff], scrutiny will not emit its own --exclude flags, letting ruff read the pyproject list natively. The equivalent rule holds for mypy and bandit. Operational concerns that have no pyproject equivalent (--no-cache, JSON output formatting) still emit regardless.

Use --pyproject-only to suppress scrutiny defaults entirely; tools then run with only your CLI overrides and pyproject settings.

Framework-specific rule families (--framework django, etc.) are emitted as --extend-select so they supplement rather than replace your pyproject select list when it exists.

pyproject.toml Management

Running scrutiny does not modify your pyproject.toml. It reads whatever is there, respects it, and analyses your code. Config generation is an explicit, one-time action via an opt-in flag.

Managed sections: [tool.ruff], [tool.mypy], [tool.bandit], and optionally [tool.pytest.ini_options] + [tool.coverage.*]. All other tool sections are never touched.

Generation flags

Flag Generates
--generate-config [tool.ruff], [tool.mypy], [tool.bandit]
--generate-config=test Above + [tool.pytest.ini_options] + [tool.coverage.*]
--generate-config=all Above + pytest plugin addopts (pytest-cov, pytest-xdist)
--generate-test-config Only [tool.pytest.ini_options] + [tool.coverage.*]
--generate-test-config=plugins Only test sections with plugin addopts

--generate-config and --generate-test-config are mutually exclusive. Combine either with --override-config to replace existing managed sections instead of merging.

Merge vs override

Scenario Default (merge) With --override-config
Key exists in your file Preserved Replaced with generated
Key missing from your file Added Added
Unmanaged tool sections Untouched Untouched

Generated settings are tier-aware; the rules, strictness, and thresholds written to your config match your selected tier (essential, standard, strict, or insane).

Quick Start

# Run analysis with the standard tier (default); read-only, does not modify files
scrutiny

# Bootstrap managed [tool.*] sections on first use
scrutiny --generate-config

# Run on a specific directory
scrutiny src/

# Opt into auto-fix and formatting
scrutiny --fix --tool ruff

# Strict tier for maximum rigor
scrutiny --strict

# Check tool availability
scrutiny --doctor

Output Example

======================================================================
Code Quality Analysis
  Project:   my-project
  Tools:     ruff_linter, mypy, radon, bandit
  Tier:      standard
  Security:  enabled
  Context:   cli
  Mode:      standard
  Framework: none
======================================================================

Running ruff_linter...
[ruff_linter]
  Files: 12
  Issues: 0
  Time: 0.03s
  Checked: 22 lint rule groups
  Result: no issues found

Running mypy...
[mypy]
  Files: 12
  Issues: 0
  Time: 0.45s
  Checked: warn unreachable, ignore missing imports
  Result: no type errors

Running radon...
[radon]
  Files: 12
  Issues: 0
  Time: 0.08s
  Checked: cyclomatic complexity (threshold C, max score 20)
  Result: all functions within threshold

Running bandit...
[bandit]
  Files: 12
  Issues: 0
  Time: 0.15s
  Checked: security (MEDIUM+ severity, HIGH+ confidence)
  Result: no findings

======================================================================
Script Code: 0
All checks passed (12 files, 0.73s)
  ruff_linter    ... passed
  mypy           ... passed
  radon          ... passed
  bandit         ... passed
======================================================================

Configuration Tiers

Tier Description Use Case
--essential Core correctness only Legacy codebases, quick checks
--standard Quality + correctness (default) Production-ready code
--strict Maximum rigor Enforced style and best practices
--insane Every rule enabled Bulletproof but noisy

Each tier includes all rules from the tier below it.

CLI Flags (Summary)

Flag Description
--tool ruff|mypy|radon|bandit Run only specified tool(s)
--essential / --standard / --strict / --insane Select quality tier
--fix / --check-only Enable/disable auto-fix
--parallel / --no-parallel Parallel tool execution
--generate-config[=test|all] Create/merge managed pyproject sections
--generate-test-config[=plugins] Create/merge only test sections
--override-config Replace (not merge) managed sections on generation
--pyproject-only Use pyproject + CLI only; bypass scrutiny defaults
--show-config Display effective configuration
--doctor Check tool availability
-q / -v / --detailed Output verbosity

See CLI Reference for the complete reference.

Documentation

License

See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ks_scrutiny-4.0.1.tar.gz (217.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ks_scrutiny-4.0.1-py3-none-any.whl (115.5 kB view details)

Uploaded Python 3

File details

Details for the file ks_scrutiny-4.0.1.tar.gz.

File metadata

  • Download URL: ks_scrutiny-4.0.1.tar.gz
  • Upload date:
  • Size: 217.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for ks_scrutiny-4.0.1.tar.gz
Algorithm Hash digest
SHA256 0fd386eadc50b07857bd31cb54806e6dea88b201629ac5f8f61269bc554649cb
MD5 93b084e09a313c7fe17ce9fab097ddd3
BLAKE2b-256 a5c95b0b6e5512363d2a09ba0e02b318287520b8f4b5a359c950df58645265b0

See more details on using hashes here.

File details

Details for the file ks_scrutiny-4.0.1-py3-none-any.whl.

File metadata

  • Download URL: ks_scrutiny-4.0.1-py3-none-any.whl
  • Upload date:
  • Size: 115.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for ks_scrutiny-4.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 50097fd01b0d3996e4660249eecb31eb1cd0005106366b1370fc87aeb1b04ab7
MD5 6187c1d89b5b1a189686f2f1a0080b5a
BLAKE2b-256 caedc255438972edbba289eec56acb70adea744e0bb18f5b01311471e1c6ed0b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page