feature:pip-install
Introduction
feature:pip-install installs the features your product declares from PyPI, or from their git tag when PyPI does not serve them. The production image and CI run it, so you rarely run it by hand.
splent feature:pip-install
Installing 2 feature(s)...
installing splent_feature_notes==1.3.0
ok splent_feature_notes==1.3.0
installing splent_feature_tags==0.1.0
pypi does not serve splent_feature_tags==0.1.0, installing its git tag v0.1.0 instead
ok git+https://git.splent.io/splent-io/splent_feature_tags.git@v0.1.0
Installed from their git tag because PyPI does not serve them. A tag is immutable, so the image is still reproducible:
splent_feature_tags v0.1.0
All 2 feature(s) installed from PyPI and git tags.
Only [tool.splent].features is read. A failure does not stop the run, and the command exits 1 at the end.
How each entry is installed
Entry in pyproject.toml |
What pip installs |
|---|---|
splent-io/splent_feature_notes@v1.3.0 |
splent_feature_notes==1.3.0, or the git tag v1.3.0 |
splent-io/splent_feature_notes |
Whatever PyPI serves, never your workspace copy |
A name in [tool.splent.distributions] |
That PyPI name, such as splent-feature-notes-alice==1.3.0 |
A feature published under a PyPI name of its own is installed by that name, which feature:attach records.
Falling back to the git tag
The tag and the PyPI package come from the same commit, so both are the same release. When PyPI has no such package or version, pip installs git+https://<forge>/<namespace>/<name>.git@<tag>, with the namespace as written and then with - for _.
That covers a private feature, and one PyPI does not serve yet (see PyPI new-project limits). Only a pinned, namespaced entry falls back. Any other pip failure is reported as it is.
splent feature:pip-install --pypi-only
--pypi-only fails instead of falling back.
Where it runs
In development, scripts/00_install_features.sh installs the copies under <product>/features/ with pip install -e. The production image runs splent feature:pip-install in the builder stage of docker/Dockerfile.<product>.prod, and so does CI. A production build takes nothing from your workspace.
A feature declared only in
features_devorfeatures_prodis not installed, yetproduct:buildmerges it into the deploy, so it fails at import time. The command lists each one first. Move it tofeaturesif the image needs it.
Reference
| Option | Description |
|---|---|
--pypi-only |
Fail instead of falling back to the git tag |
| Message | Exit | What to do |
|---|---|---|
FAIL <spec>: ... |
1 | Read pip’s last line, printed after it |
... and its git tag <tag> could not be installed either |
1 | Check the tag exists and your token can read the repository |
Installed without a version, so pip chose what PyPI serves |
0 | Pin the entries it lists |
Requirements
- A selected product (
SPLENT_APP). - Features released with
feature:release. - For a private repository,
SPLENT_FORGE_TOKEN(orGITHUB_TOKEN). It reaches git through the environment, and any credential in pip’s output is printed as***.
See also
product:buildbuilds the production image that runs this command.product:resolvefetches pinned features for development.