Skip to main content

olai_stack_runtime/
lib.rs

1//! Run trestle environments on Docker Compose.
2//!
3//! [`olai_stack_topology`] plans and renders an environment without touching Docker; this crate
4//! is the part that runs it. The CLI and the desktop app share it.
5//!
6//! - [`ComposeEngine`]: what the runtime asks of Compose (up, down, ls, ps, logs, events,
7//!   network removal). [`DockerCli`] runs the `docker` CLI; [`FakeEngine`] (feature `testing`)
8//!   is an in-memory stand-in for tests.
9//! - Typed [`ProjectStatus`], [`ServiceStatus`] / [`Health`] and [`EngineEvent`], parsed from the
10//!   CLI's JSON output (the test fixtures are captured from real engines, see
11//!   `docs/runtime.md`).
12//! - [`probe_host_ports`]: whether a plan's host ports are free before starting it.
13//! - [`managed_projects`] and [`remove_mesh_if_idle`]: matching what Docker runs against what
14//!   the caller manages.
15//! - [`Instances`]: runs the revisions of an [`olai_stack_state::Store`] as compose projects,
16//!   side by side, with the layered [`EffectiveEnv`] injected and credentials resolved by
17//!   [`SecretProvider`]s ([`EnvProvider`], and `KeychainProvider` behind feature `keychain`) and
18//!   [`Source`] overlays.
19//! - `neon` (feature `neon`): Neon branches as a source, through the Neon CLI
20//!   (`NeonControl`, `NeonCli`, `NeonBranchSource`, and `FakeNeon` with `testing`).
21//!
22//! Values that must not reach a file (credentials) go to Compose as process environment only:
23//! every lifecycle call takes the variables to add ([`UpOptions::env`]).
24//!
25//! ```no_run
26//! use olai_stack_runtime::{ComposeEngine, DockerCli, UpOptions};
27//!
28//! # async fn run() -> olai_stack_runtime::Result<()> {
29//! let docker = DockerCli::new();
30//! let opts = UpOptions { wait: true, ..UpOptions::default() };
31//! docker.up(std::path::Path::new("demo/dev"), &opts).await?;
32//! for project in docker.ls().await? {
33//!     println!("{}: {}", project.name, project.status);
34//! }
35//! # Ok(())
36//! # }
37//! ```
38
39#![cfg_attr(docsrs, feature(doc_cfg))]
40
41mod docker;
42mod effective;
43mod engine;
44mod error;
45mod events;
46#[cfg(feature = "testing")]
47mod fake;
48mod instances;
49mod logs;
50#[cfg(feature = "neon")]
51#[cfg_attr(docsrs, doc(cfg(feature = "neon")))]
52pub mod neon;
53mod ports;
54mod reconcile;
55mod secrets;
56mod source;
57mod status;
58
59pub use docker::DockerCli;
60pub use effective::{
61    EffectiveEnv, EnvLayers, EnvValue, Layer, LayerValue, MASK, MaskedVar, Resolved,
62};
63pub use engine::{ComposeEngine, DownOptions, EngineStream, LogOptions, Progress, UpOptions};
64pub use error::{Error, Result};
65pub use events::{
66    EngineEvent, EventAction, EventFilter, PROJECT_LABEL, SERVICE_LABEL, parse_event,
67};
68#[cfg(feature = "testing")]
69#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
70pub use fake::{FakeCall, FakeEngine};
71pub use instances::{
72    INSTANCES_DIR, InstanceError, InstanceEvent, Instances, Materialized, PLACEMENT_KEYS,
73    ReconcileOptions, Reconciled, instance_project, parse_instance_project,
74};
75pub use logs::{LogLine, parse_log_line};
76pub use ports::{BusyPort, is_free, probe_host_ports};
77pub use reconcile::{ProjectMatch, managed_projects, remove_mesh_if_idle};
78#[cfg(feature = "keychain")]
79#[cfg_attr(docsrs, doc(cfg(feature = "keychain")))]
80pub use secrets::KeychainProvider;
81pub use secrets::{EnvProvider, SecretError, SecretProvider, SecretProviders, SecretValue};
82pub use source::{Overlay, Source, SourceCtx, SourceError, UserVars};
83pub use status::{Health, ProjectStatus, Published, ServiceStatus, State, parse_ls, parse_ps};