## Proviso requirements.txt management

A tool for managing requirements.txt version pinning and updating. Proviso extracts dependencies from your project's setup.py or pyproject.toml, resolves all transitive dependencies using PyPI, and generates a fully pinned requirements.txt file that works across multiple Python versions.

### Installation

#### Command line

```
pip install proviso
```

#### requirements.txt/setup.py

Pinning specific versions or SHAs is recommended to avoid unplanned upgrades.

##### Versions

```
# Start with the latest versions and don't just copy what's here
proviso==0.0.1
```

##### SHAs

```
# Start with the latest/specific versions and don't just copy what's here
-e git+https://git@github.com/octodns/proviso.git@ec9661f8b335241ae4746eea467a8509205e6a30#egg=proviso
```

### Usage

#### Basic usage

Generate a requirements.txt for all currently active Python versions:

```bash
proviso
```

This will:
1. Read dependencies from your project's setup.py or pyproject.toml
2. Resolve all transitive dependencies from PyPI
3. Generate a requirements.txt with pinned versions that work across all currently active Python versions (queried from endoflife.date)

#### Common options

Generate requirements for specific Python versions:

```bash
proviso --python-versions 3.10,3.11,3.12
```

Include specific extras (e.g., dev dependencies):

```bash
proviso --extras dev,test
```

Specify a custom output file:

```bash
proviso --filename requirements-dev.txt
```

Customize the header comment:

```bash
proviso --header "# Generated requirements - do not edit"
```

#### Full command-line reference

```console
usage: proviso [-h] [--directory DIRECTORY] [--extras EXTRAS] [--python-versions PYTHON_VERSIONS] [--filename FILENAME]
               [--level {DEBUG,INFO,WARNING,ERROR}] [--header HEADER]

Extract project requirements, resolve dependencies, and manage requirements.txt

options:
  -h, --help            show this help message and exit
  --directory DIRECTORY
                        Project root directory (default: current directory)
  --extras EXTRAS       Comma-separated list of extras to include (e.g., "dev,test"). Defaults to all defined extras.
  --python-versions PYTHON_VERSIONS
                        Comma-separated list of Python versions (e.g., "3.9,3.10,3.11"). Defaults to currently active versions
                        per endoflife.date.
  --filename FILENAME   Output filename or path for requirements (default: requirements.txt). If just a filename, will be placed
                        in --directory; if a path, will be used as-is.
  --level {DEBUG,INFO,WARNING,ERROR}
                        Logging level (default: WARNING)
  --header HEADER       Header comment to place at the top of the requirements file. Use the string "[command line]" to insert the
                        actual command that was run. (default: "# DO NOT EDIT THIS FILE DIRECTLY - use [command line]")
```

#### Features

- **Multi-version support**: Generates a single requirements.txt that works across multiple Python versions, using environment markers (e.g., `package==1.0.0; python_version=='3.10'`) when different versions are needed
- **Complete dependency resolution**: Recursively resolves all transitive dependencies from PyPI
- **Automatic Python version detection**: Uses endoflife.date API to determine currently active Python versions
- **Extras support**: Include optional dependency groups (dev, test, etc.) from your setup.py or pyproject.toml
- **Flexible output**: Generate requirements files with custom names and locations

### Development

See the [/script/](/script/) directory for some tools to help with the development process. They generally follow the [Script to rule them all](https://github.com/github/scripts-to-rule-them-all) pattern. Most useful is `./script/bootstrap` which will create a venv and install both the runtime and development related requirements. It will also hook up a pre-commit hook that covers most of what's run by CI.
