Skip to main content

isoloom_manifest/
lib.rs

1//! The run manifest, version 0: the contract between Isoloom and the Isothrum runner.
2//!
3//! Isoloom writes one `run.json` next to a target's generated files; the runner executes it and
4//! reads nothing else. The manifest holds the native commands in order (argv, never a shell), the
5//! documented driver actions, readiness, outputs, check runners, and the slots that carry inputs
6//! and secrets (names and destinations, never values).
7//!
8//! The types parse, they don't validate: a [`Manifest`] that parsed holds no shell as a program,
9//! no `${secrets.…}` placeholder, no absolute or climbing path, no port name with a dot, no UDP
10//! port that speaks HTTP and no other version than 0. [`Manifest::validate`] then checks what
11//! spans fields (step references, machines, placeholders).
12//! The JSON Schema ([`schema`]) is generated from the types and committed at
13//! `schemas/run-manifest-v0.schema.json`; the fixtures under `fixtures/` are shared with the
14//! runner, which tests against the same files.
15//!
16//! The crate is pure: it reads and writes text, and touches no file, process or clock. Its enums
17//! are exhaustive on purpose: the manifest is a closed, versioned contract, so a runner must handle
18//! every step action, delivery and condition, and a new one fails its build instead of falling
19//! into a wildcard.
20//!
21//! # Example
22//!
23//! ```
24//! use isoloom_manifest::{Driver, Template};
25//!
26//! let manifest = isoloom_manifest::parse(include_str!("../fixtures/docker.run.json"))?;
27//! assert_eq!(manifest.driver, Driver::Compose);
28//! // What Isoloom writes reads back as the same manifest.
29//! assert_eq!(isoloom_manifest::parse(&isoloom_manifest::to_json(&manifest)?)?, manifest);
30//! // A template can't hold a secret: it reaches a tool only through its slot.
31//! let refused = "--flag=${secrets.FLAG}".parse::<Template>().unwrap_err();
32//! assert_eq!(refused.code(), "secret_placeholder");
33//! # Ok::<(), isoloom_manifest::Error>(())
34//! ```
35
36pub mod access;
37mod argv;
38mod error;
39mod guest;
40mod identity;
41pub mod ignore;
42mod lifecycle;
43mod list;
44mod machine;
45mod manifest;
46mod names;
47mod outputs;
48mod path;
49mod port;
50mod provenance;
51mod schema;
52mod slots;
53mod step;
54mod template;
55mod validate;
56mod walk;
57
58pub use argv::{Argv, HostArgv, PerHostArgv, Program};
59pub use error::{Error, Result};
60pub use guest::Guest;
61pub use identity::{
62    Cloud, ComposeIdentity, Driver, Elevation, HostOs, Identity, Provider, StateOwner, Target, TerraformIdentity, Tool, VagrantIdentity, VagrantProvider,
63};
64pub use lifecycle::{Condition, Expiry, ExpiryUnit, Lifecycle, Park, Provision, ReadyGrammar, Recovery, Retries, Seal};
65pub use list::{NonEmpty, StepSelection};
66pub use machine::{Arch, Cidr, Machine, Native, Network, Resources, Role, Volume};
67pub use manifest::{Manifest, parse, to_json};
68pub use names::{EnvName, EnvironmentName, Identifier, Name, OsName, PinnedImage, PortName, SnakeName, StepId, ToolName, Version};
69pub use outputs::{Check, CheckKind, CheckProtocol, CheckRunner, Checks, Output, OutputRole, OutputSource};
70pub use path::{GuestPath, PathTemplate, RelPath};
71pub use port::{Port, PortKind, Protocol, Publish, PublishMode};
72pub use provenance::{EnvironmentRef, Generator, GeneratorName, Instance, ManifestVersion, SUPPORTED_VERSION};
73pub use schema::{SCHEMA_URL, schema};
74pub use slots::{Delivery, Param, SecretSlot, SecretSource, SetBy, SlotKind, StateFileFormat, Store, TfVarShape, Transport};
75pub use step::{Action, Failure, Run, Step, When};
76pub use template::{Part, Placeholder, RunVar, Template};