product:derive
Table of contents
- Introduction
- How a derivation runs
- Deriving for production
- Pre-flight checks
- Deriving past a failed pre-flight
- Freeing a busy port
- Reference
- Requirements
- See also
Introduction
product:derive takes your product from its configuration to a running app in one command. It checks that the configuration is valid, then resolves, configures, builds and starts it, in development or in production. A product that fails the checks is never derived.
splent product:derive --dev
Deriving my_first_app (dev)
validate UVL configuration is satisfiable
contract no conflicts detected
refiners no collisions detected (0 refiners)
ports no conflicts detected
sync resolving feature symlinks...
...
env generating .env files
env merging .env files
up starting containers
run launching application
...
Product: my_first_app
Env: dev
Port: 5591 -> 5000
URL: http://localhost:5591
my_first_app (dev) derived successfully.
The first run takes several minutes, since it builds the web image, pulls MariaDB, installs every feature and runs the migrations. Later runs reuse Docker’s cache.
How a derivation runs
| Step | --dev |
--prod |
|---|---|---|
| 1 | product:resolve --dev --strict links the base and features_dev features |
product:resolve --prod --strict clones the pinned releases into the cache and links them |
| 2 | product:env --generate --all --dev writes the .env files |
product:build writes the bundle and builds the image |
| 3 | product:env --merge --dev merges them into the product’s .env |
product:deploy --image <product>:latest starts production on that image |
| 4 | product:up --dev starts every stack |
|
| 5 | product:run --dev runs the entrypoint |
|
| 6 | product:port prints the URL |
A failed step prints Derivation stopped: <command> failed. and exits with that step’s code. You can also run each step on its own.
Deriving for production
splent product:derive --prod
This rehearses a production deployment on your machine. It deploys the image the build just made, even when deploy/.env names a published one.
Pre-flight checks
| Check | What it checks | Runs |
|---|---|---|
| pyproject sanity | No feature twice across features, features_dev and features_prod, and an SPL model that can be found. A failure skips the other checks |
Always |
| SAT | The selection of the mode satisfies the UVL model | Always |
| Contracts and refiners | No error-level collision between the features’ contracts, and the product part of the refinement phase | Always |
| Parameters and frontend | The errors of phases 6 and 7 of product:validate |
Always |
| Feature readiness | Every prod feature is versioned, and on PyPI or tagged on the forge | --prod |
Errors stop the derivation. Warnings do not. Run product:validate to see the same checks in full without deriving.
validate UVL configuration is NOT satisfiable
run 'splent product:validate' to inspect
Pre-flight checks failed. Fix the issues above before deriving.
Deriving past a failed pre-flight
splent product:derive --dev --skip-validate
Use it to try a selection your line’s model does not allow yet, before you publish the new model. The checks still run and print their findings, then a warning says the product is not valid as it stands, and the pipeline goes on.
WARNING --skip-validate: the checks above failed and the derivation goes on.
my_product is NOT a valid product of its line as it stands. Development only:
fix the selection or publish the model before any release, as its CI will refuse it.
The port check still stops it. --prod --skip-validate is refused, since a production derivation is always a valid product. Check the new model with product:validate --model and publish it before any release.
Freeing a busy port
When a port is taken by another container, the command lists the containers that block it, tags each as dev or prod, and offers to stop and remove them. Declining stops the derivation.
ports 1 conflict(s) found:
port 5591 <- my_first_app/my_first_app_web (blocked by: my_first_app_web_deploy (prod))
run 'splent product:down --prod' to stop the production deployment first
Stop and remove the conflicting containers? [y/N]:
Your product’s own containers never count as a conflict, so you can derive again a product that is running or was derived halfway.
Reference
Options
| Option | Description |
|---|---|
--dev |
Derive for development |
--prod |
Derive for production |
--skip-validate |
With --dev only, derive although the pre-flight checks fail |
--dev or --prod is required.
Ports checked
| Mode | Ports read from | Not a conflict |
|---|---|---|
--dev |
The compose files of the product and its features, with the product’s .env |
The product’s <product>_dev project and its feature projects |
--prod |
deploy/docker-compose.yml with deploy/.env, or docker/docker-compose.prod.yml before the bundle exists |
The product’s <product>_deploy project |
With neither compose file, the check prints ports no compose file yet, product:build will generate it and moves on.
Pre-flight messages
| Message | Meaning |
|---|---|
pyproject duplicate '<feature>': ... |
A feature is listed twice |
pyproject SPL '<name>' has no model available |
The model is not on disk and cannot be fetched. See spl:pin |
contract [<field>] <message> |
Two features’ contracts collide |
refiners [<code>] <message> |
Two refiners collide, with what to do |
params <error> |
A value does not fit its feature’s schema |
frontend [<code>] <message> |
A bundle does not fit the page |
refiners not checked, no local copy of <names> |
A warning. The derivation goes on |
<check> crashed: <error> |
The checker failed, and the derivation stops |
Requirements
- A selected product (
SPLENT_APP) withpyproject.tomland adocker/directory. - Docker.
- The product’s SPL model, in a working copy, in the cache, or pinned by DOI in
[tool.splent.spl_model]so the pre-flight can download it.
See also
product:validateruns the checks without deriving.product:buildandproduct:deployare the production steps.