Since @dstufft has already sketched the semantics (which is the harder part) for transforming pip
into a universal package manager, today I have tried to think about the syntax (which is the simpler part) and the various command inputs and steps, based on his thoughts:
So given that, a unified tool would need to, at a minimum, enable:
- Allow installation and uninstallation of projects into an environment.
- This includes commands for repeat deployments into multiple environments.
- Introspect the current state of installed packages, and get more information about them.
- Tools to produce a local directory of artifacts for offline usage.
- This includes downloading from PyPI, producing wheels, and producing sdists. Basically an analogy of “install, but save to a local directory”.
- Allow upload of existing artifacts.
- This could also possibly include command line support for things like yanking a file, managing a two phase release, etc that we might add in the future.
- Build artifacts such as an sdist from a directory, or a wheel from a sdist.
I think that’s it for what a mvp of such a tool would look like?
There are also additional features that one could imagine it having, such as:
- Enable a “binary only” install mode ala pipx.
- Ability to bootstrap a project, potentially from a user supplied template ala cookiecutter.
- More commands to manage the development lifecycle such as a lint command, a test command, or a format command that would paper over differences between linters, test harnesses, or formatting tools.
- This could really be expanded quite far, things like building documentation, running benchmarks, etc.
- A generic “run a command” feature ala tox or npm run.
- A way to run a command from a project in development, ala cargo run.
For the moment I have only considered the minimal commands of his first paragraph. Here after is my attempt.
Installing
$ pip install {project}
- wheel → download → wheel + wheel dependencies → install
- wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies → install
- sdist → build → wheel → download → wheel + wheel dependencies → install
- sdist → build → wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies → install
- repo → build → sdist → build → wheel → download → wheel + wheel dependencies → install
- repo → build → sdist → build → wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies → install
- download → wheel + wheel dependencies → install
- download → wheel or sdist + wheel or sdist dependencies → build → wheel + wheel dependencies → install
$ pip uninstall {project}
Inspecting
$ pip inspect {project}
Fetching
$ pip fetch --wheel {project}
- download → wheel
- download → sdist → build → wheel
$ pip fetch --sdist {project}
$ pip fetch --any {project}
- download → wheel or sdist
$ pip fetch --wheel --dependencies {project}
- wheel → download → wheel + wheel dependencies
- wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies
- sdist → build → wheel → download → wheel + wheel dependencies
- sdist → build → wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies
- repo → build → sdist → build → wheel → download → wheel + wheel dependencies
- repo → build → sdist → build → wheel → download → wheel + wheel or sdist dependencies → build → wheel + wheel dependencies
- download → wheel + wheel dependencies
- download → wheel or sdist + wheel or sdist dependencies → build → wheel + wheel dependencies
$ pip fetch --sdist --dependencies {project}
- sdist → download → sdist + sdist dependencies
- repo → build → sdist → download → sdist + sdist dependencies
- download → sdist + sdist dependencies
$ pip fetch --any --dependencies {project}
- wheel → download → wheel + wheel or sdist dependencies
- sdist → download → sdist + wheel or sdist dependencies
- repo → build → sdist → download → sdist + wheel or sdist dependencies
- download → wheel or sdist + wheel or sdist dependencies
Publishing
$ pip publish --wheel {project}
- wheel → publish
- sdist → build → wheel → publish
- repo → build → sdist → build → wheel → publish
$ pip publish --sdist {project}
- sdist → publish
- repo → build → sdist → publish
Building
$ pip build --wheel {project}
- sdist → build → wheel
- repo → build → sdist → build → wheel
$ pip build --sdist {project}
Notes. — For all the above commands:
- The
--wheel
option is the default.
- The
--wheel
and --sdist
options can be combined.
All the above commands can build except the inspecting command.
All the above commands interact with the network except the inspecting and building commands.