lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

package_boundary.rs (10198B)


      1 use std::collections::BTreeSet;
      2 
      3 const MANIFEST: &str = include_str!("../Cargo.toml");
      4 const README: &str = include_str!("../README");
      5 const PUBLIC_API: &str =
      6     include_str!("../../../contracts/api_baselines/radroots_runtime_paths.txt");
      7 const ROOT: &str = include_str!("../src/lib.rs");
      8 const SOURCES: &[&str] = &[
      9     include_str!("../src/context.rs"),
     10     include_str!("../src/conventions.rs"),
     11     include_str!("../src/error.rs"),
     12     include_str!("../src/identifier.rs"),
     13     include_str!("../src/platform.rs"),
     14     include_str!("../src/provision.rs"),
     15     include_str!("../src/roots.rs"),
     16     include_str!("../src/service.rs"),
     17 ];
     18 
     19 #[test]
     20 fn runtime_paths_is_unpublished_lint_governed_and_dependency_bounded() {
     21     for required in [
     22         "name = \"radroots_runtime_paths\"",
     23         "publish = false",
     24         "version = \"0.1.0-alpha\"",
     25     ] {
     26         assert!(
     27             MANIFEST.contains(required),
     28             "manifest is missing `{required}`"
     29         );
     30     }
     31     assert_eq!(
     32         dependency_keys(MANIFEST),
     33         BTreeSet::from(["rustix", "serde", "thiserror"])
     34     );
     35     assert_eq!(
     36         ROOT.lines()
     37             .filter_map(|line| line.strip_prefix("mod "))
     38             .filter_map(|line| line.strip_suffix(';'))
     39             .collect::<BTreeSet<_>>(),
     40         BTreeSet::from([
     41             "context",
     42             "conventions",
     43             "error",
     44             "identifier",
     45             "platform",
     46             "provision",
     47             "roots",
     48             "service",
     49         ])
     50     );
     51     assert!(!ROOT.contains("pub mod "));
     52     assert!(ROOT.contains("#![doc = include_str!(\"../README\")]"));
     53     for source in SOURCES {
     54         let production = source.split("#[cfg(test)]").next().unwrap_or(source);
     55         assert!(!production.contains("std::env"));
     56         for forbidden in [
     57             "impl Into<String>",
     58             "let value = value.into();",
     59             "String::deserialize",
     60         ] {
     61             assert!(
     62                 !production.contains(forbidden),
     63                 "bounded runtime-path text boundary still contains `{forbidden}`"
     64             );
     65         }
     66     }
     67     assert!(
     68         SOURCES
     69             .iter()
     70             .any(|source| source.contains("deserializer.deserialize_str(Visitor)"))
     71     );
     72 }
     73 
     74 #[test]
     75 fn removed_namespace_selection_and_raw_root_surfaces_cannot_return() {
     76     for forbidden in [
     77         "RadrootsRuntimeNamespace",
     78         "RadrootsRuntimeNamespaceKind",
     79         "RadrootsServiceInstanceNamespace",
     80         "RadrootsRuntimePathSelection",
     81         "RadrootsRuntimePathConfigEntry",
     82         "RadrootsRuntimePathPolicyContract",
     83         "RadrootsRuntimeSelectionContract",
     84         "RadrootsRuntimeSelectionOverrideContract",
     85         "RadrootsPathOverrides",
     86         "RadrootsBootstrapPaths",
     87         "default_service_instance_paths",
     88         "default_namespaced_bootstrap_paths",
     89         "default_shared_identity_path",
     90         "default_shared_runtime_logs_dir",
     91         "from_current_process",
     92         "MissingMobileRoots",
     93         "InvalidNamespaceComponent",
     94     ] {
     95         assert!(
     96             SOURCES.iter().all(|source| !source.contains(forbidden)) && !ROOT.contains(forbidden),
     97             "removed runtime-path surface `{forbidden}` returned"
     98         );
     99     }
    100 
    101     for forbidden in [
    102         "pub struct radroots_runtime_paths::RadrootsPaths",
    103         "pub struct radroots_runtime_paths::RadrootsPathOverrides",
    104         "pub struct radroots_runtime_paths::RadrootsRuntimeNamespace",
    105         "pub struct radroots_runtime_paths::RadrootsServiceInstanceNamespace",
    106         "pub struct radroots_runtime_paths::RadrootsRuntimePathSelection",
    107         "pub fn radroots_runtime_paths::RadrootsPathResolver::current",
    108         "pub fn radroots_runtime_paths::RadrootsPathResolver::resolve",
    109     ] {
    110         assert!(
    111             !PUBLIC_API.contains(forbidden),
    112             "reviewed API baseline exposes `{forbidden}`"
    113         );
    114     }
    115 }
    116 
    117 #[test]
    118 fn reviewed_api_requires_the_typed_runtime_context_boundary() {
    119     for required in [
    120         "pub struct radroots_runtime_paths::RuntimeContext",
    121         "pub struct radroots_runtime_paths::RuntimeContextBootstrap",
    122         "pub enum radroots_runtime_paths::RuntimeContextSource",
    123         "pub struct radroots_runtime_paths::RadrootsPathResolver",
    124         "pub struct radroots_runtime_paths::RadrootsServiceInstancePaths",
    125         "pub struct radroots_runtime_paths::RadrootsServiceInstanceArtifacts",
    126         "pub struct radroots_runtime_paths::ServiceId",
    127         "pub struct radroots_runtime_paths::InstanceId",
    128         "pub fn radroots_runtime_paths::RuntimeContext::resolve",
    129         "pub fn radroots_runtime_paths::RuntimeContext::repo_local_root",
    130         "pub fn radroots_runtime_paths::RuntimeContext::state_directory_plan",
    131         "pub struct radroots_runtime_paths::RuntimeStateDirectoryPlan",
    132         "pub fn radroots_runtime_paths::RuntimeStateDirectoryPlan::provision",
    133         "pub enum radroots_runtime_paths::StateDirectoryProvisionError",
    134         "pub fn radroots_runtime_paths::RadrootsPlatform::current",
    135         "pub fn radroots_runtime_paths::default_service_instance_artifacts",
    136         "pub fn radroots_runtime_paths::service_credential_artifact_path",
    137         "pub fn radroots_runtime_paths::default_shared_geonames_database_path_from_cache_root",
    138         "pub fn radroots_runtime_paths::default_shared_runtime_store_database_path_from_data_root",
    139     ] {
    140         assert!(
    141             PUBLIC_API.contains(required),
    142             "reviewed API baseline is missing `{required}`"
    143         );
    144     }
    145 
    146     for required in [
    147         "## Example",
    148         "## Root Profiles",
    149         "## State Directory Provisioning",
    150         "## Common Artifacts",
    151         "## Support Caveats",
    152         "## Public API Baseline",
    153         "The final reviewed root-only API",
    154         "validated as\n  borrowed UTF-8 before the crate creates their retained strings",
    155         "```rust",
    156         "| Linux `ServiceHost` | `/etc/radroots` | `/var/lib/radroots` | `/var/cache/radroots` | `/var/log/radroots` | `/run/radroots` | `/etc/radroots/secrets` |",
    157         "| Linux `InteractiveUser` | `$XDG_CONFIG_HOME/radroots` | `$XDG_DATA_HOME/radroots` | `$XDG_CACHE_HOME/radroots` | `$XDG_STATE_HOME/radroots/logs` | `$XDG_RUNTIME_DIR/radroots` | `$XDG_CONFIG_HOME/radroots/secrets` |",
    158         "| macOS `InteractiveUser` | `$HOME/Library/Application Support/Radroots/config` | `$HOME/Library/Application Support/Radroots/data` | `$HOME/Library/Caches/Radroots` | `$HOME/Library/Logs/Radroots` | `$HOME/Library/Application Support/Radroots/run` | `$HOME/Library/Application Support/Radroots/secrets` |",
    159         r"| Windows `InteractiveUser` | `%APPDATA%\Radroots\config` | `%LOCALAPPDATA%\Radroots\data` | `%LOCALAPPDATA%\Radroots\cache` | `%LOCALAPPDATA%\Radroots\logs` | `%LOCALAPPDATA%\Radroots\run` | `%APPDATA%\Radroots\secrets` |",
    160         "| `RepoLocal` | `<base>/config` | `<base>/data` | `<base>/cache` | `<base>/logs` | `<base>/run` | `<base>/secrets` |",
    161         "| Configuration | `<config>/config.toml` |",
    162         "| SQLite state | `<state>/state.sqlite` |",
    163         "| SQLite writer lock | `<state>/state.lock` |",
    164         "| Local admin socket | `<run>/admin.sock` |",
    165         "| Credential artifact | `<secrets>/<validated-credential-name>` |",
    166         "Pure path\nresolution never reads the ambient process environment or performs filesystem\nI/O.",
    167         "create only `services/<service>/<instance>`, one descriptor-relative component",
    168         "never changes an existing mode, and identity-checks any cleanup",
    169         "An entry whose identity cannot\nbe proven is preserved and the operation fails closed.",
    170         "For `ServiceHost`, the entire state-directory suffix must already exist.",
    171         "stable path-free unsupported-platform classification",
    172         "does not create any common\nartifact, configuration, cache, log, run, or secrets path",
    173         "An absolute\n`XDG_RUNTIME_DIR` is mandatory and has no fallback.",
    174         "Linux service-host\non x86_64 and aarch64 is eligible for Tier 1 only after all release gates pass.",
    175         "Linux and macOS interactive and explicit repo-local profiles on x86_64 and\naarch64 are developer-target behavior.",
    176         "Linux rootless OCI on x86_64 and\naarch64 is also only a target",
    177         "Windows interactive and repo-local derivation is\nimplemented but unsupported and carries no v1 support claim.",
    178         "Non-Linux `ServiceHost`, `MobileNative`, Android/iOS/Other interactive,",
    179         "Repo-local never",
    180         "Successful compilation or path derivation does not change",
    181         "[runtime-paths API baseline](../../contracts/api_baselines/radroots_runtime_paths.txt)",
    182     ] {
    183         assert!(README.contains(required), "README is missing `{required}`");
    184     }
    185 
    186     for forbidden in [
    187         "pub mod radroots_runtime_paths::context",
    188         "pub mod radroots_runtime_paths::conventions",
    189         "pub mod radroots_runtime_paths::error",
    190         "pub mod radroots_runtime_paths::identifier",
    191         "pub mod radroots_runtime_paths::platform",
    192         "pub mod radroots_runtime_paths::provision",
    193         "pub mod radroots_runtime_paths::roots",
    194         "pub mod radroots_runtime_paths::service",
    195         "radroots_runtime_paths::context::",
    196         "radroots_runtime_paths::conventions::",
    197         "radroots_runtime_paths::error::",
    198         "radroots_runtime_paths::identifier::",
    199         "radroots_runtime_paths::platform::",
    200         "radroots_runtime_paths::provision::",
    201         "radroots_runtime_paths::roots::",
    202         "radroots_runtime_paths::service::",
    203         "thiserror::",
    204         "serde_json::",
    205         "rustix::",
    206     ] {
    207         assert!(
    208             !PUBLIC_API.contains(forbidden),
    209             "reviewed API baseline exposes `{forbidden}`"
    210         );
    211     }
    212 }
    213 
    214 fn dependency_keys(manifest: &str) -> BTreeSet<&str> {
    215     manifest
    216         .split_once("[dependencies]")
    217         .map(|(_, dependencies)| dependencies)
    218         .unwrap_or_default()
    219         .lines()
    220         .skip(1)
    221         .take_while(|line| !line.starts_with('['))
    222         .filter_map(|line| line.split_once('=').map(|(key, _)| key.trim()))
    223         .filter(|key| !key.is_empty())
    224         .collect()
    225 }