Skip to main content

pupoxide/
lib.rs

1//! # Pupoxide
2//!
3//! A high-performance, memory-safe, declarative configuration management tool inspired by Puppet.
4//!
5//! Pupoxide leverages the power and safety of Rust and integrates the flexible scripting capabilities of Rhai
6//! to allow expressing complex system configurations cleanly, safely, and efficiently.
7//!
8//! ## Key Features
9//!
10//! - **Declarative Configuration DSL**: Describe files, directories, commands, and packages using a simple Rhai-based DSL.
11//! - **Safe Concurrent Execution**: Resources are executed in parallel using a Kahn-based topological sort, respecting dependency relationships.
12//! - **Resource Mutexes**: Package managers (like `apt` or `brew`) and other conflicting resources are automatically serialized using internal mutex locks.
13//! - **Hexagonal Architecture**: Core domains and applications are decoupled from infrastructure stores via clean ports and adapters.
14//! - **Hierarchical Configuration (Stash)**: Dynamically resolve system variables based on target host facts using a Multi-level Tera templated configuration storage.
15//! - **Zero Warnings & High Safety**: Built under a strict `#![deny(clippy::unwrap_used)]` compiler warning policy.
16//!
17//! ## Architecture Overview
18//!
19//! Pupoxide follows a clean **Ports & Adapters (Hexagonal)** architectural pattern inside `src/`:
20//!
21//! 1. **Domain (`src/domain/`)**: Houses the primary business entities (like `Resource`, `Catalog`, `Transaction`, `Facts`, and `ResourceReport`) and abstract port traits (like `ResourceProvider`). It is highly pure and contains minimal external dependencies.
22//! 2. **Application (`src/application/`)**: Defines orchestrations, including DSL registration, manifest evaluation via `PupoxideEngine`, and execution graphs via `execute_transaction`. It relies on abstract ports like `StashProvider` and `StateStore`.
23//! 3. **Infrastructure (`src/infrastructure/`)**: Implements specific I/O adapters, such as concrete `Stash` filesystems and transaction log `StateStore` adapters.
24//! 4. **Interface (`src/interface/`)**: Entry point for CLI configurations, REST handlers, or agent bindings.
25//!
26//! ## Quick Start Example
27//!
28//! The following example demonstrates how to configure the engine, compile a manifest, and apply it to a target system.
29//!
30//! ### 1. Write a Rhai Manifest (`site.rhai`)
31//!
32//! ```rhai
33//! // Declare a package resource
34//! pkg("git", #{
35//!     ensure: "present",
36//! });
37//!
38//! // Create a custom configuration file depending on git
39//! file("/etc/myapp/config.yaml", #{
40//!     ensure: "present",
41//!     content: "port: 8080\nenvironment: production",
42//!     require: ["package:git"],
43//! });
44//! ```
45//!
46//! ### 2. Execute via Rust API
47//!
48//! ```rust,ignore
49//! use pupoxide::application::{PupoxideEngine, execute_transaction};
50//! use pupoxide::domain::facts::Facts;
51//! use pupoxide::infrastructure::{Stash, StateStore, FsAdapter};
52//! use std::path::PathBuf;
53//! use std::sync::Arc;
54//!
55//! #[tokio::main]
56//! async fn main() -> anyhow::Result<()> {
57//!     // 1. Gather host facts
58//!     let mut facts = Facts::new();
59//!     facts.insert("os_family".to_string(), "Darwin".to_string());
60//!     facts.insert("hostname".to_string(), "my-macbook".to_string());
61//!
62//!     // 2. Initialize Infrastructure Adapters
63//!     let env_path = PathBuf::from("./examples/environments/production");
64//!     let stash = Stash::new(env_path.clone())?.map(|s| Arc::new(s) as Arc<dyn pupoxide::application::StashProvider>);
65//!     let state_store = StateStore::new(env_path.clone());
66//!     let provider = Arc::new(FsAdapter::new());
67//!
68//!     // 3. Build & Run the Pupoxide Engine
69//!     let engine = PupoxideEngine::builder()
70//!         .with_stash(stash.expect("stash config missing"))
71//!         .with_module_path(env_path.join("modules"))
72//!         .register_defaults()
73//!         .build();
74//!
75//!     let catalog = engine.run_manifest(
76//!         env_path.join("manifests/site.rhai"),
77//!         "my-macbook".to_string(),
78//!         "production".to_string(),
79//!         facts,
80//!     )?;
81//!
82//!     // 4. Apply configuration via Parallel Execution Graph
83//!     let reports = execute_transaction(
84//!         catalog,
85//!         &state_store,
86//!         provider,
87//!         false, // dry_run
88//!         |report| {
89//!             println!("Resource [{}]: {:?}", report.resource_id, report.status);
90//!         }
91//!     ).await?;
92//!
93//!     println!("Successfully synchronized system configuration!");
94//!     Ok(())
95//! }
96//! ```
97
98#![deny(clippy::unwrap_used)]
99
100pub mod application;
101pub mod domain;
102pub mod infrastructure;
103pub mod interface;
104
105pub use domain::resource;
106pub use infrastructure::FsAdapter;