# pyproject-installer
This tool is intended for build, install, run or management of dependencies
sources of Python project in source tree within network-isolated environments.
## Description
- Supported platform: Unix.<br>
Currently, platform-specific parts:
- pipe is used for calling build backend hooks in subprocess
- script wrappers are generated only for Unix systems
- OS environment of this project is a `network-isolated` environment, which
implies that a local loopback interface is the only available network
interface. Thus, `pyproject-installer` doesn't perform any network activity
(e.g. it doesn't install build dependencies specified via PEP518 configuration
or PEP517's `get_requires_for_*` hooks). This also makes it difficult or
impossible to create an isolated Python environment for calling build backend
hooks specified in PEP517, therefore, current Python environment is the only
available environment.
- Source tree can be either checkout of VCS or unpacked source distribution.
- An installation result will be consumed by external tool like RPM.<br>
The main usage of `pyproject-installer` looks like:
```
external tool => (pyproject-installer: build => install to destdir) => external tool packages destdir
```
Therefore, there is no need to build intermediate source distribution for
build wheel, only `build_wheel` backend's hook is actually called.
Note: an installation into Python virtual environment is also supported, but
only the manual uninstallation of such packages is possible (tools should
refuse an uninstallation of distribution with missing `RECORD` file).
- Only stdlib or vendored dependencies can be used in runtime for bootstrapping
any Python project.<br>
Current vendored packages:
- `tomli` (used for parsing `pyproject.toml` configuration file).
Note: `tomli` is the part of stdlib since Python 3.11.
- `packaging` (used for parsing PEP508 dependencies)
- Installation of build dependencies is up to the caller.<br>
These dependencies of Python projects are managed externally with system
package managers like `apt` or `dnf`. [External source](#management-of-dependencies-sources) of upstream's
dependencies may be used for provision of formatted list of dependencies to external tools.
- There is no post-installation bytecompilation.<br>
PEP427 says that wheel installers should compile any installed .py to .pyc.
External tools like RPM already provide Python bytecompilation means, which
compile for multiple optimization levels at a time. No point to compile
modules twice.
- RECORD file is not installed.<br>
https://peps.python.org/pep-0627/#optional-record-file:
> Specifically, the RECORD file is unnecessary when projects are installed by
a Linux system packaging system, which has its own ways to keep track of
files, uninstall them or check their integrity. Having to keep a RECORD file
in sync with the disk and the system package database would be unreasonably
fragile, and no RECORD file is better than one that does not correspond to
reality.
- INSTALLER file is not installed by default(optional).<br>
https://peps.python.org/pep-0627/#optional-installer-file:
> The INSTALLER file is also made optional, and specified to be used for
informational purposes only. It is still a single-line text file containing
the name of the installer.
https://packaging.python.org/en/latest/specifications/recording-installed-packages/#the-installer-file:
> This value should be used for informational purposes only. For example, if a
tool is asked to uninstall a project but finds no RECORD file, it may
suggest that the tool named in INSTALLER may be able to do the
uninstallation.
- Built distribution can be checked within Python virtual environment with the
help of `run` command.
- Project's dependencies sources can be managed (i.e. stored, synced, verified
or evaluated) with the help of `deps` command.
## Usage
### Build
Build project from source tree in current Python environment according to
PEP517. This doesn't trigger installation of project's build dependencies.
```
python -m pyproject_installer build
```
Build positional arguments:
<pre>
<em><strong>description</strong></em>: source directory
<em><strong>default</strong></em>: current working directory
<em><strong>example</strong></em>: python -m pyproject_installer build .
</pre>
Build options:
<pre>
<em><strong>name</strong></em>: --outdir OUTDIR, -o OUTDIR
<em><strong>description</strong></em>: output directory for built wheel
<em><strong>default</strong></em>: {srcdir}/dist
<em><strong>example</strong></em>: python -m pyproject_installer build --outdir ~/outdir
</pre>
Upon successful build `pyproject_installer` dumps wheel filename into
`{OUTDIR}/.wheeltracker`.
<pre>
<em><strong>name</strong></em>: --sdist
<em><strong>description</strong></em>: build source distribution(sdist) instead of binary
one(wheel).
<em><strong>note</strong></em>: installer supports only wheel format.
<em><strong>default</strong></em>: build wheel
<em><strong>example</strong></em>: python -m pyproject_installer build --sdist
</pre>
<pre>
<em><strong>name</strong></em>: --backend-config-settings BACKEND_CONFIG_SETTINGS
<em><strong>description</strong></em>: ad-hoc configuration for build backend as dumped JSON dictionary
<em><strong>default</strong></em>: None
Example of passing <em><strong>config_settings</strong></em> for setuptools>=64.0.0:
python -m pyproject_installer build --backend-config-settings='{"--build-option": ["--python-tag=sometag", "--build-number=123"]}'
Example of passing <em><strong>config_settings</strong></em> for setuptools<64.0.0:
python -m pyproject_installer build --backend-config-settings='{"--global-option": ["--python-tag=sometag", "--build-number=123"]}'
Example of passing <em><strong>config_settings</strong></em> for pdm backend:
python -m pyproject_installer build --backend-config-settings='{"--python-tag": "sometag"}'
</pre>
### Install
Install project built in wheel format. This doesn't trigger installation of
project's runtime dependencies.
```
python -m pyproject_installer install
```
Install positional arguments:
<pre>
<em><strong>description</strong></em>: wheel file to install
<em><strong>default</strong></em>: contructed as directory {cwd}/dist and wheel filename read from
{cwd}/dist/.wheeltracker
<em><strong>example</strong></em>: python -m pyproject_installer install wheel.whl
</pre>
Install options:
<pre>
<em><strong>name</strong></em>: --destdir DESTDIR, -d DESTDIR
<em><strong>description</strong></em>: Wheel installation root will be prepended with destdir
<em><strong>default</strong></em>: /
<em><strong>example</strong></em>: python -m pyproject_installer install --destdir ~/destdir
</pre>
<pre>
<em><strong>name</strong></em>: --installer INSTALLER
<em><strong>description</strong></em>: Name of installer to be recorded in dist-info/INSTALLER
<em><strong>default</strong></em>: None, INSTALLER will be omitted
<em><strong>example</strong></em>: python -m pyproject_installer install --installer custom_installer
</pre>
<pre>
<em><strong>name</strong></em>: --no-strip-dist-info
<em><strong>description</strong></em>: Don't strip dist-info. By default only <em><strong>METADATA</strong></em>
and <em><strong>entry_points.txt</strong></em> files are allowed in <em>dist-info</em> directory.
<em><strong>note</strong></em>: <em><strong>RECORD</strong></em> is unconditionally filtered out.
<em><strong>default</strong></em>: False
<em><strong>example</strong></em>: python -m pyproject_installer install --no-strip-dist-info
</pre>
### Run
Run command within Python virtual environment that has access to system and user
site packages, their console scripts and installed built package.
```
python -m pyproject_installer run
```
Run positional arguments:
<pre>
<em><strong>description</strong></em>: command to run within virtual environment
<em><strong>example</strong></em>: python -m pyproject_installer run pytest
</pre>
Dash note:
> https://docs.python.org/3/library/argparse.html#arguments-containing
If you have positional arguments that must begin with - and don't look like
negative numbers, you can insert the pseudo-argument '--' which tells
`parse_args()` that everything after that is a positional argument:
```
python -m pyproject_installer run -- pytest -vra
```
Run options:
<pre>
<em><strong>name</strong></em>: --wheel WHEEL
<em><strong>description</strong></em>: wheel file to install into virtual environment
<em><strong>default</strong></em>: contructed as directory {cwd}/dist and wheel filename read from
{cwd}/dist/.wheeltracker
<em><strong>example</strong></em>: python -m pyproject_installer run --wheel wheel.whl pytest
</pre>
Note: venv's directory name is `.run_venv`.
### Management of dependencies sources
Collect PEP508 requirements from different sources, store and evaluate
them in Python environment.
```
python -m pyproject_installer deps --help
```
Common deps options:
<pre>
<em><strong>name</strong></em>: --depsconfig
<em><strong>description</strong></em>: configuration file to use
<em><strong>default</strong></em>: {cwd}/pyproject_deps.json
<em><strong>example</strong></em>: python -m pyproject_installer deps --depsconfig foo.json
</pre>
#### deps subcommands
<pre>
<em><strong>name</strong></em>: show
<em><strong>description</strong></em>: show configuration and data of dependencies's sources
<em><strong>example</strong></em>: python -m pyproject_installer deps show --help
</pre>
Positional arguments:
<pre>
<em><strong>description</strong></em>: source names
<em><strong>default</strong></em>: all
<em><strong>example</strong></em>: python -m pyproject_installer deps show build
</pre>
---
<pre>
<em><strong>name</strong></em>: add
<em><strong>description</strong></em>: configure source of Python dependencies. Supported sources: standardized formats like PEP517, PEP518, PEP735 or core metadata are fully supported, while tool-specific formats like pip, tox, poetry, hatch, pdm or pipenv have limited support.
<em><strong>example</strong></em>: python -m pyproject_installer deps add --help
</pre>
Positional arguments:
<pre>
<em><strong>description</strong></em>: source name
</pre>
<pre>
<em><strong>description</strong></em>: source type
<em><strong>choice</strong></em>: pep517, pep518, pep735, metadata, pip_reqfile, poetry, tox, hatch, pdm, pipenv
</pre>
<pre>
<em><strong>description</strong></em>: specific configuration options for source
<em><strong>default</strong></em>: []
</pre>
<pre>
<em><strong>examples</strong></em>:
Configuration of source of <strong>PEP518</strong> dependencies:
python -m pyproject_installer deps add build_pep518 pep518
Configuration of source of <strong>PEP517</strong> dependencies:
python -m pyproject_installer deps add build_pep517 pep517
Configuration of source of <strong>metadata</strong> dependencies:
python -m pyproject_installer deps add runtime metadata
Configuration of source of <strong>PEP735</strong> dependencies:
python -m pyproject_installer deps add check pep735 test
Configuration of source of <strong>pip</strong> requirements:
python -m pyproject_installer deps add check pip_reqfile requirements.txt
Configuration of source of <strong>tox</strong> requirements:
python -m pyproject_installer deps add check tox tox.ini testenv
Configuration of source of <strong>poetry</strong> requirements:
python -m pyproject_installer deps add check poetry dev
Configuration of source of <strong>hatch</strong> requirements:
python -m pyproject_installer deps add check hatch hatch.toml test
Configuration of source of <strong>pdm</strong> requirements:
python -m pyproject_installer deps add check pdm test
Configuration of source of <strong>pipenv</strong> requirements:
python -m pyproject_installer deps add check pipenv Pipfile packages
</pre>
---
<pre>
<em><strong>name</strong></em>: sync
<em><strong>description</strong></em>: sync stored requirements to configured sources
<em><strong>example</strong></em>: python -m pyproject_installer deps sync --help
</pre>
Positional arguments:
<pre>
<em><strong>description</strong></em>: source names
<em><strong>default</strong></em>: all
<em><strong>example</strong></em>: python -m pyproject_installer deps sync build
</pre>
Options:
<pre>
<em><strong>name</strong></em>: --verify
<em><strong>description</strong></em>: Sync sources, but print diff and exits with code 4 if the sources were unsynced
<em><strong>default</strong></em>: only sync
<em><strong>example</strong></em>: python -m pyproject_installer deps sync --verify build
</pre>
<pre>
<em><strong>name</strong></em>: --verify-exclude
<em><strong>description</strong></em>: Regex patterns, exclude from diff requirements PEP503-normalized names of those match one of the patterns. Requires --verify.
<em><strong>default</strong></em>: []
<em><strong>example</strong></em>: python -m pyproject_installer deps sync --verify build --verify-exclude 'foo.*'
</pre>
---
<pre>
<em><strong>name</strong></em>: eval
<em><strong>description</strong></em>: evaluate stored requirements according to PEP508 in current Python environment and print them to stdout in PEP508 format (by default) or specified one
<em><strong>example</strong></em>: python -m pyproject_installer deps eval --help
</pre>
Positional arguments:
<pre>
<em><strong>description</strong></em>: source names
<em><strong>default</strong></em>: all
<em><strong>example</strong></em>: python -m pyproject_installer deps eval build
</pre>
Options:
<pre>
<em><strong>name</strong></em>: --depformat
<em><strong>description</strong></em>: format of dependency to print. Supported substitutions: $name - project's name, $nname - PEP503 normalized project's name, $fextra - project's extras (expanded first with --depformatextra)
<em><strong>default</strong></em>: PEP508 format
<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --depformat='python3-$nn'
</pre>
<pre>
<em><strong>name</strong></em>: --depformatextra
<em><strong>description</strong></em>: format of extras to print (one extra of dependencies per line). Result is expanded in format specified by --depformat as $fextra. Supported substitutions: $extra
<em><strong>default</strong></em>: ''
<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --depformat='python3-$nn$fextra' --depformatextra='+$extra'
</pre>
<pre>
<em><strong>name</strong></em>: --extra
<em><strong>description</strong></em>: PEP508 'extra' marker to evaluate with
<em><strong>default</strong></em>: None
<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --extra tests
</pre>
<pre>
<em><strong>name</strong></em>: --exclude
<em><strong>description</strong></em>: regexes patterns, exclude requirement having PEP503-normalized name that matches one of these patterns
<em><strong>default</strong></em>: []
<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --exclude types- pytest-cov
</pre>
---
<pre>
<em><strong>name</strong></em>: delete
<em><strong>description</strong></em>: deconfigure source of Python dependencies
<em><strong>example</strong></em>: python -m pyproject_installer deps delete --help
</pre>
Positional arguments:
<pre>
<em><strong>description</strong></em>: source name
<em><strong>example</strong></em>: python -m pyproject_installer deps delete build
</pre>
## Comparison with other tools
`pyproject-installer` consists of builder and installer, both provide
*only necessary* and *sufficient* functionality.
### builder
Functionally, today's builder is similar to [build](https://pypi.org/project/build).<br>
The key differences are:
- highly specialized defaults (see [description](#Description))
- highly specialized features to drop extra runtime dependencies like
`pep517`. No point to vendor `pep517` to call only `build_wheel` backend hook
in subprocess.
### installer
Functionally, today's installer is similar to [installer](https://pypi.org/project/installer).<br>
The key differences are:
- highly specialized defaults and features (see [description](#Description))
Both can be replaced with [pip](https://pypi.org/project/pip). But again, no
point to use full-featured complex `pip` to highly specialized task.
## Bootstrap
There is a self-hosted build backend to avoid dependency on any other backend.
For example, bootstrap can be done as:
```console
export PYTHONPATH=$(pwd)/src
python -m pyproject_installer build
python -m pyproject_installer install --destdir=/rootdir
```
## Tests
- unit tests can be run as:
```
pytest tests/unit
```
- integration tests (require internet connection and `git` tool) can be run as:
```
pytest tests/integration
```
## License
Distributed under the terms of the **MIT** license, `pyproject-installer` is
free and open source software.
Raw data
{
"_id": null,
"home_page": null,
"name": "pyproject-installer",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "packaging, PEP517, build, install",
"author": null,
"author_email": "Stanislav Levin <slev@altlinux.org>",
"download_url": "https://files.pythonhosted.org/packages/83/d8/fd101b04561d1412ef8816e251e8365c8ecba4198db80a35f2f48d9e5984/pyproject_installer-0.5.5.tar.gz",
"platform": null,
"description": "# pyproject-installer\n\nThis tool is intended for build, install, run or management of dependencies\nsources of Python project in source tree within network-isolated environments.\n\n\n## Description\n\n- Supported platform: Unix.<br>\n Currently, platform-specific parts:\n - pipe is used for calling build backend hooks in subprocess\n - script wrappers are generated only for Unix systems\n\n- OS environment of this project is a `network-isolated` environment, which\n implies that a local loopback interface is the only available network\n interface. Thus, `pyproject-installer` doesn't perform any network activity\n (e.g. it doesn't install build dependencies specified via PEP518 configuration\n or PEP517's `get_requires_for_*` hooks). This also makes it difficult or\n impossible to create an isolated Python environment for calling build backend\n hooks specified in PEP517, therefore, current Python environment is the only\n available environment.\n\n- Source tree can be either checkout of VCS or unpacked source distribution.\n\n- An installation result will be consumed by external tool like RPM.<br>\n The main usage of `pyproject-installer` looks like:\n ```\n external tool => (pyproject-installer: build => install to destdir) => external tool packages destdir\n ```\n\n Therefore, there is no need to build intermediate source distribution for\n build wheel, only `build_wheel` backend's hook is actually called.\n\n Note: an installation into Python virtual environment is also supported, but\n only the manual uninstallation of such packages is possible (tools should\n refuse an uninstallation of distribution with missing `RECORD` file).\n\n- Only stdlib or vendored dependencies can be used in runtime for bootstrapping\n any Python project.<br>\n Current vendored packages:\n - `tomli` (used for parsing `pyproject.toml` configuration file).\n Note: `tomli` is the part of stdlib since Python 3.11.\n - `packaging` (used for parsing PEP508 dependencies)\n\n- Installation of build dependencies is up to the caller.<br>\n These dependencies of Python projects are managed externally with system\n package managers like `apt` or `dnf`. [External source](#management-of-dependencies-sources) of upstream's\n dependencies may be used for provision of formatted list of dependencies to external tools.\n\n- There is no post-installation bytecompilation.<br>\n PEP427 says that wheel installers should compile any installed .py to .pyc.\n External tools like RPM already provide Python bytecompilation means, which\n compile for multiple optimization levels at a time. No point to compile\n modules twice.\n\n- RECORD file is not installed.<br>\n https://peps.python.org/pep-0627/#optional-record-file:\n > Specifically, the RECORD file is unnecessary when projects are installed by\n a Linux system packaging system, which has its own ways to keep track of\n files, uninstall them or check their integrity. Having to keep a RECORD file\n in sync with the disk and the system package database would be unreasonably\n fragile, and no RECORD file is better than one that does not correspond to\n reality.\n\n- INSTALLER file is not installed by default(optional).<br>\n https://peps.python.org/pep-0627/#optional-installer-file:\n > The INSTALLER file is also made optional, and specified to be used for\n informational purposes only. It is still a single-line text file containing\n the name of the installer.\n\n https://packaging.python.org/en/latest/specifications/recording-installed-packages/#the-installer-file:\n > This value should be used for informational purposes only. For example, if a\n tool is asked to uninstall a project but finds no RECORD file, it may\n suggest that the tool named in INSTALLER may be able to do the\n uninstallation.\n\n- Built distribution can be checked within Python virtual environment with the\n help of `run` command.\n\n- Project's dependencies sources can be managed (i.e. stored, synced, verified\n or evaluated) with the help of `deps` command.\n\n## Usage\n\n### Build\nBuild project from source tree in current Python environment according to\nPEP517. This doesn't trigger installation of project's build dependencies.\n```\npython -m pyproject_installer build\n```\n\nBuild positional arguments:\n<pre>\n<em><strong>description</strong></em>: source directory\n<em><strong>default</strong></em>: current working directory\n<em><strong>example</strong></em>: python -m pyproject_installer build .\n</pre>\n\nBuild options:\n<pre>\n<em><strong>name</strong></em>: --outdir OUTDIR, -o OUTDIR\n<em><strong>description</strong></em>: output directory for built wheel\n<em><strong>default</strong></em>: {srcdir}/dist\n<em><strong>example</strong></em>: python -m pyproject_installer build --outdir ~/outdir\n</pre>\nUpon successful build `pyproject_installer` dumps wheel filename into\n`{OUTDIR}/.wheeltracker`.\n\n<pre>\n<em><strong>name</strong></em>: --sdist\n<em><strong>description</strong></em>: build source distribution(sdist) instead of binary\none(wheel).\n<em><strong>note</strong></em>: installer supports only wheel format.\n<em><strong>default</strong></em>: build wheel\n<em><strong>example</strong></em>: python -m pyproject_installer build --sdist\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --backend-config-settings BACKEND_CONFIG_SETTINGS\n<em><strong>description</strong></em>: ad-hoc configuration for build backend as dumped JSON dictionary\n<em><strong>default</strong></em>: None\n\nExample of passing <em><strong>config_settings</strong></em> for setuptools>=64.0.0:\npython -m pyproject_installer build --backend-config-settings='{\"--build-option\": [\"--python-tag=sometag\", \"--build-number=123\"]}'\n\nExample of passing <em><strong>config_settings</strong></em> for setuptools<64.0.0:\npython -m pyproject_installer build --backend-config-settings='{\"--global-option\": [\"--python-tag=sometag\", \"--build-number=123\"]}'\n\nExample of passing <em><strong>config_settings</strong></em> for pdm backend:\npython -m pyproject_installer build --backend-config-settings='{\"--python-tag\": \"sometag\"}'\n</pre>\n\n### Install\nInstall project built in wheel format. This doesn't trigger installation of\nproject's runtime dependencies.\n```\npython -m pyproject_installer install\n```\n\nInstall positional arguments:\n<pre>\n<em><strong>description</strong></em>: wheel file to install\n<em><strong>default</strong></em>: contructed as directory {cwd}/dist and wheel filename read from\n{cwd}/dist/.wheeltracker\n<em><strong>example</strong></em>: python -m pyproject_installer install wheel.whl\n</pre>\n\nInstall options:\n<pre>\n<em><strong>name</strong></em>: --destdir DESTDIR, -d DESTDIR\n<em><strong>description</strong></em>: Wheel installation root will be prepended with destdir\n<em><strong>default</strong></em>: /\n<em><strong>example</strong></em>: python -m pyproject_installer install --destdir ~/destdir\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --installer INSTALLER\n<em><strong>description</strong></em>: Name of installer to be recorded in dist-info/INSTALLER\n<em><strong>default</strong></em>: None, INSTALLER will be omitted\n<em><strong>example</strong></em>: python -m pyproject_installer install --installer custom_installer\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --no-strip-dist-info\n<em><strong>description</strong></em>: Don't strip dist-info. By default only <em><strong>METADATA</strong></em>\nand <em><strong>entry_points.txt</strong></em> files are allowed in <em>dist-info</em> directory.\n<em><strong>note</strong></em>: <em><strong>RECORD</strong></em> is unconditionally filtered out.\n<em><strong>default</strong></em>: False\n<em><strong>example</strong></em>: python -m pyproject_installer install --no-strip-dist-info\n</pre>\n\n### Run\nRun command within Python virtual environment that has access to system and user\nsite packages, their console scripts and installed built package.\n```\npython -m pyproject_installer run\n```\n\nRun positional arguments:\n<pre>\n<em><strong>description</strong></em>: command to run within virtual environment\n<em><strong>example</strong></em>: python -m pyproject_installer run pytest\n</pre>\n\nDash note:\n> https://docs.python.org/3/library/argparse.html#arguments-containing\nIf you have positional arguments that must begin with - and don't look like\nnegative numbers, you can insert the pseudo-argument '--' which tells\n`parse_args()` that everything after that is a positional argument:\n```\npython -m pyproject_installer run -- pytest -vra\n```\n\nRun options:\n<pre>\n<em><strong>name</strong></em>: --wheel WHEEL\n<em><strong>description</strong></em>: wheel file to install into virtual environment\n<em><strong>default</strong></em>: contructed as directory {cwd}/dist and wheel filename read from\n{cwd}/dist/.wheeltracker\n<em><strong>example</strong></em>: python -m pyproject_installer run --wheel wheel.whl pytest\n</pre>\n\nNote: venv's directory name is `.run_venv`.\n\n\n### Management of dependencies sources\n\nCollect PEP508 requirements from different sources, store and evaluate\nthem in Python environment.\n\n```\npython -m pyproject_installer deps --help\n```\n\nCommon deps options:\n<pre>\n<em><strong>name</strong></em>: --depsconfig\n<em><strong>description</strong></em>: configuration file to use\n<em><strong>default</strong></em>: {cwd}/pyproject_deps.json\n<em><strong>example</strong></em>: python -m pyproject_installer deps --depsconfig foo.json\n</pre>\n\n#### deps subcommands\n\n<pre>\n<em><strong>name</strong></em>: show\n<em><strong>description</strong></em>: show configuration and data of dependencies's sources\n<em><strong>example</strong></em>: python -m pyproject_installer deps show --help\n</pre>\n\nPositional arguments:\n<pre>\n<em><strong>description</strong></em>: source names\n<em><strong>default</strong></em>: all\n<em><strong>example</strong></em>: python -m pyproject_installer deps show build\n</pre>\n\n---\n\n<pre>\n<em><strong>name</strong></em>: add\n<em><strong>description</strong></em>: configure source of Python dependencies. Supported sources: standardized formats like PEP517, PEP518, PEP735 or core metadata are fully supported, while tool-specific formats like pip, tox, poetry, hatch, pdm or pipenv have limited support.\n<em><strong>example</strong></em>: python -m pyproject_installer deps add --help\n</pre>\n\nPositional arguments:\n<pre>\n<em><strong>description</strong></em>: source name\n</pre>\n\n<pre>\n<em><strong>description</strong></em>: source type\n<em><strong>choice</strong></em>: pep517, pep518, pep735, metadata, pip_reqfile, poetry, tox, hatch, pdm, pipenv\n</pre>\n\n<pre>\n<em><strong>description</strong></em>: specific configuration options for source\n<em><strong>default</strong></em>: []\n</pre>\n\n<pre>\n<em><strong>examples</strong></em>:\nConfiguration of source of <strong>PEP518</strong> dependencies:\npython -m pyproject_installer deps add build_pep518 pep518\n\nConfiguration of source of <strong>PEP517</strong> dependencies:\npython -m pyproject_installer deps add build_pep517 pep517\n\nConfiguration of source of <strong>metadata</strong> dependencies:\npython -m pyproject_installer deps add runtime metadata\n\nConfiguration of source of <strong>PEP735</strong> dependencies:\npython -m pyproject_installer deps add check pep735 test\n\nConfiguration of source of <strong>pip</strong> requirements:\npython -m pyproject_installer deps add check pip_reqfile requirements.txt\n\nConfiguration of source of <strong>tox</strong> requirements:\npython -m pyproject_installer deps add check tox tox.ini testenv\n\nConfiguration of source of <strong>poetry</strong> requirements:\npython -m pyproject_installer deps add check poetry dev\n\nConfiguration of source of <strong>hatch</strong> requirements:\npython -m pyproject_installer deps add check hatch hatch.toml test\n\nConfiguration of source of <strong>pdm</strong> requirements:\npython -m pyproject_installer deps add check pdm test\n\nConfiguration of source of <strong>pipenv</strong> requirements:\npython -m pyproject_installer deps add check pipenv Pipfile packages\n</pre>\n\n---\n\n<pre>\n<em><strong>name</strong></em>: sync\n<em><strong>description</strong></em>: sync stored requirements to configured sources\n<em><strong>example</strong></em>: python -m pyproject_installer deps sync --help\n</pre>\n\nPositional arguments:\n<pre>\n<em><strong>description</strong></em>: source names\n<em><strong>default</strong></em>: all\n<em><strong>example</strong></em>: python -m pyproject_installer deps sync build\n</pre>\n\nOptions:\n<pre>\n<em><strong>name</strong></em>: --verify\n<em><strong>description</strong></em>: Sync sources, but print diff and exits with code 4 if the sources were unsynced\n<em><strong>default</strong></em>: only sync\n<em><strong>example</strong></em>: python -m pyproject_installer deps sync --verify build\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --verify-exclude\n<em><strong>description</strong></em>: Regex patterns, exclude from diff requirements PEP503-normalized names of those match one of the patterns. Requires --verify.\n<em><strong>default</strong></em>: []\n<em><strong>example</strong></em>: python -m pyproject_installer deps sync --verify build --verify-exclude 'foo.*'\n</pre>\n\n---\n\n<pre>\n<em><strong>name</strong></em>: eval\n<em><strong>description</strong></em>: evaluate stored requirements according to PEP508 in current Python environment and print them to stdout in PEP508 format (by default) or specified one\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval --help\n</pre>\n\nPositional arguments:\n<pre>\n<em><strong>description</strong></em>: source names\n<em><strong>default</strong></em>: all\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval build\n</pre>\n\nOptions:\n<pre>\n<em><strong>name</strong></em>: --depformat\n<em><strong>description</strong></em>: format of dependency to print. Supported substitutions: $name - project's name, $nname - PEP503 normalized project's name, $fextra - project's extras (expanded first with --depformatextra)\n<em><strong>default</strong></em>: PEP508 format\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --depformat='python3-$nn'\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --depformatextra\n<em><strong>description</strong></em>: format of extras to print (one extra of dependencies per line). Result is expanded in format specified by --depformat as $fextra. Supported substitutions: $extra\n<em><strong>default</strong></em>: ''\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --depformat='python3-$nn$fextra' --depformatextra='+$extra'\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --extra\n<em><strong>description</strong></em>: PEP508 'extra' marker to evaluate with\n<em><strong>default</strong></em>: None\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --extra tests\n</pre>\n\n<pre>\n<em><strong>name</strong></em>: --exclude\n<em><strong>description</strong></em>: regexes patterns, exclude requirement having PEP503-normalized name that matches one of these patterns\n<em><strong>default</strong></em>: []\n<em><strong>example</strong></em>: python -m pyproject_installer deps eval build --exclude types- pytest-cov\n</pre>\n\n---\n\n<pre>\n<em><strong>name</strong></em>: delete\n<em><strong>description</strong></em>: deconfigure source of Python dependencies\n<em><strong>example</strong></em>: python -m pyproject_installer deps delete --help\n</pre>\n\nPositional arguments:\n<pre>\n<em><strong>description</strong></em>: source name\n<em><strong>example</strong></em>: python -m pyproject_installer deps delete build\n</pre>\n\n\n## Comparison with other tools\n\n`pyproject-installer` consists of builder and installer, both provide\n*only necessary* and *sufficient* functionality.\n\n### builder\n\nFunctionally, today's builder is similar to [build](https://pypi.org/project/build).<br>\nThe key differences are:\n- highly specialized defaults (see [description](#Description))\n- highly specialized features to drop extra runtime dependencies like\n `pep517`. No point to vendor `pep517` to call only `build_wheel` backend hook\n in subprocess.\n\n### installer\n\nFunctionally, today's installer is similar to [installer](https://pypi.org/project/installer).<br>\nThe key differences are:\n- highly specialized defaults and features (see [description](#Description))\n\nBoth can be replaced with [pip](https://pypi.org/project/pip). But again, no\npoint to use full-featured complex `pip` to highly specialized task.\n\n\n## Bootstrap\nThere is a self-hosted build backend to avoid dependency on any other backend.\n\nFor example, bootstrap can be done as:\n```console\nexport PYTHONPATH=$(pwd)/src\npython -m pyproject_installer build\npython -m pyproject_installer install --destdir=/rootdir\n```\n\n## Tests\n- unit tests can be run as:\n ```\n pytest tests/unit\n ```\n- integration tests (require internet connection and `git` tool) can be run as:\n ```\n pytest tests/integration\n ```\n\n## License\n\nDistributed under the terms of the **MIT** license, `pyproject-installer` is\nfree and open source software.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Pyproject installer",
"version": "0.5.5",
"project_urls": {
"source": "https://github.com/stanislavlevin/pyproject_installer",
"tracker": "https://github.com/stanislavlevin/pyproject_installer/issues"
},
"split_keywords": [
"packaging",
" pep517",
" build",
" install"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d485599513f01bce516abc4e87b1e05624fe9704c9a0c8e5bfe0c0506bc8c836",
"md5": "b507bb2030a536af576e149327c22d26",
"sha256": "d3796c495351309e87c05455a541156b32b807118cf2290b452b01f403e4e7ca"
},
"downloads": -1,
"filename": "pyproject_installer-0.5.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b507bb2030a536af576e149327c22d26",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 111389,
"upload_time": "2024-11-14T14:26:12",
"upload_time_iso_8601": "2024-11-14T14:26:12.924163Z",
"url": "https://files.pythonhosted.org/packages/d4/85/599513f01bce516abc4e87b1e05624fe9704c9a0c8e5bfe0c0506bc8c836/pyproject_installer-0.5.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "83d8fd101b04561d1412ef8816e251e8365c8ecba4198db80a35f2f48d9e5984",
"md5": "95eb28c074406c3989a7bc9f6333a5fb",
"sha256": "5dc7daffc556156fcb7c8d2837e7edabad70c7437d8ea1e4c83022f09d4844b1"
},
"downloads": -1,
"filename": "pyproject_installer-0.5.5.tar.gz",
"has_sig": false,
"md5_digest": "95eb28c074406c3989a7bc9f6333a5fb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 131417,
"upload_time": "2024-11-14T14:26:15",
"upload_time_iso_8601": "2024-11-14T14:26:15.192109Z",
"url": "https://files.pythonhosted.org/packages/83/d8/fd101b04561d1412ef8816e251e8365c8ecba4198db80a35f2f48d9e5984/pyproject_installer-0.5.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-14 14:26:15",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stanislavlevin",
"github_project": "pyproject_installer",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pyproject-installer"
}