Metadata-Version: 2.4
Name: esys-lpip
Version: 0.3.0
Summary: Git-backed, name-oriented front end to pip for internal Python packages
Author: Project maintainers
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: packaging>=23.0
Requires-Dist: platformdirs>=4.0
Requires-Dist: tomlkit>=0.11
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: pre-commit>=3.0; extra == "dev"

# lpip

Git-backed, name-oriented front end to `pip` for internal Python packages —
no internal PyPI registry required.

Install from PyPI as **`esys-lpip`** (`pip install esys-lpip`); the command
and import remain **`lpip`**.

## Status

| Item | Value |
|------|-------|
| Workflow | A2C 0.10.0 ([ADR-0000](docs/adr/0000-adopt-a2c-workflow.md)) |
| Profile | `python-pypi` |
| Product | v1 CLI on PyPI as `esys-lpip` (0.1.1) |

## What this is

`lpip` (**local-pip**) resolves a logical package name from a TOML catalog
(`lpip-sources.toml`), validates configuration and prerequisites, and delegates
installation to `python -m pip install ...`. The catalog may be a local file
or a Git-backed checkout in a persistent user cache.

It is a small client, not a package manager replacement, registry, or service
([ADR-0001](docs/adr/0001-pip-delegation.md),
[ADR-0004](docs/adr/0004-cli-first-no-service.md)).

## Why Git instead of a private index

A private package index is a second service: you host it, keep it up, and
invent another login. **lpip treats Git as the index.** Names resolve to
`git+` URLs; pip installs the tree. Access control is whatever you already
use to clone — typically SSH keys or deploy keys. No extra account, no extra
host, no extra secret type.

Public PyPI is how you install *this* tool. Internal packages stay in the Git
you already operate.

## Non-goals (v1)

- Internal package index or hosted registry
- A dependency resolver other than pip
- Background daemons, lockfile solving, or workspace orchestration

## Quick start

```bash
pip install esys-lpip
lpip --help
```

From a clone (contributors):

```bash
python -m venv .venv
# Windows: .venv\Scripts\activate
# Unix: source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

Re-run `scripts/setup-dev` after clone if you need pre-commit and gitlint
hooks (see [docs/workflow/adoption.md](docs/workflow/adoption.md)).

## Intended configuration

Local catalog:

```toml
[source]
type = "file"
path = "~/company/lpip-sources.toml"
```

Git-backed catalog:

```toml
[source]
type = "git"
url = "ssh://git.company/dev/lpip-catalog.git"
revision = "main"
path = "lpip-sources.toml"
refresh = "auto"
```

Example catalog entry:

```toml
[packages.libfoo]
url = "git+ssh://git.company/libs/libfoo.git"
revision = "main"
subdirectory = "python"
```

Author that file **in the catalog Git repository** (then commit and push).
`--url` is a normal clone URL (`ssh://`, `https://`, or `git@host:path`);
lpip stores `git+ssh` / `git+https` for pip:

```bash
cd /path/to/lpip-catalog
lpip catalog init
lpip catalog add libfoo --url ssh://git.company/libs/libfoo.git --revision main --subdirectory python
# or: lpip catalog add   # prompts for missing fields
```

Consumers only fetch (`source.type = git` + `lpip catalog refresh`). `add` /
`init` do not write the consumer cache.

Install a mixed list (`lpip-requirements.txt` is the usual name): catalog
names first, then pip for the rest. Bare `lpip install NAME` still fails if
the name is not in the catalog.

```bash
lpip install libfoo==1.2.3
lpip install -r lpip-requirements.txt
lpip install -r lpip-requirements.txt --catalog-only
```

`==` on a catalog name selects the Git tag (`1.2.3` or `v1.2.3`). Other
specifiers on catalog names fail; PyPI lines in `-r` are passed to pip as-is.

List Git tags that parse as versions (optional leading `v`):
`lpip versions libfoo` or `lpip index versions libfoo` (`--pre`, `--all`).

`lpip version` / `lpip --version` print this tool’s installed version.

`lpip install --upgrade` / `-U` and `lpip upgrade` pass pip `--upgrade`
(same for `-r`).

Commands: `lpip install`, `lpip upgrade`, `lpip list`, `lpip show`,
`lpip versions`, `lpip version`, `lpip validate`, `lpip doctor`,
`lpip catalog …` (`init`, `add`, `refresh`, …), `lpip config …`,
`lpip index versions`. Details:
[docs/architecture/cli-and-configuration.md](docs/architecture/cli-and-configuration.md).

## Documentation

| Topic | Location |
|-------|----------|
| Architecture | [docs/architecture/overview.md](docs/architecture/overview.md) |
| Artifact chain | [docs/workflow/documentation-structure.md](docs/workflow/documentation-structure.md) |
| ASRs | [docs/asr/](docs/asr/) |
| ADRs | [docs/adr/INDEX.md](docs/adr/INDEX.md) |
| Acceptance criteria | [docs/ac/](docs/ac/) |
| A2C adoption | [docs/workflow/adoption.md](docs/workflow/adoption.md) |
| Release | [docs/release-pipeline.md](docs/release-pipeline.md) |
| Publishing | [docs/package-publishing.md](docs/package-publishing.md) |
| GitLab CI | [docs/gitlab-ci.md](docs/gitlab-ci.md) |
| Agent entry | [AGENTS.md](AGENTS.md) |

## License

MIT (`pyproject.toml`).
