From a94e5d13eadabbe53fd631c364a3a546b1a25078 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:30:51 -0500 Subject: [PATCH 1/9] ci: pin fp conformance workflow provenance --- .github/workflows/fp-conformance.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/fp-conformance.yml b/.github/workflows/fp-conformance.yml index 54c481824..dbb735985 100644 --- a/.github/workflows/fp-conformance.yml +++ b/.github/workflows/fp-conformance.yml @@ -2,7 +2,7 @@ name: fp-conformance # Functional-programming conformance ratchet. # -# Deliberately cheap: stdlib Python, no toolchain, no dependency install, no +# Deliberately cheap: stdlib Python, no dependency install, no dependency # network. It compares current findings against the recorded budget and fails # only on regression, so the pre-existing backlog never blocks a pull request # while new violations do. @@ -38,14 +38,19 @@ concurrency: jobs: conformance: name: functional programming conformance - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 5 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + fetch-depth: 1 + show-progress: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: '3.11' + cache: '' - name: Scan run: | @@ -56,7 +61,7 @@ jobs: - name: Upload findings if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: fp-findings path: fp-findings.json From 262e4d7ac5b2bcbb3124fa908f353c15873247fd Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:31:09 -0500 Subject: [PATCH 2/9] ci: serialize interface fleet audit on fixed runner --- .github/workflows/interface-fleet-audit.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/interface-fleet-audit.yml b/.github/workflows/interface-fleet-audit.yml index 69da41c3c..62b3401b8 100644 --- a/.github/workflows/interface-fleet-audit.yml +++ b/.github/workflows/interface-fleet-audit.yml @@ -22,9 +22,13 @@ on: permissions: contents: read +concurrency: + group: interface-fleet-audit-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: scanner-tests: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 5 steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -41,7 +45,7 @@ jobs: fleet-audit: if: github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 30 env: GITHUB_TOKEN: ${{ secrets.INTERFACE_FLEET_READ_TOKEN || github.token }} From e3f403ae24edf5767e65ed8653f7888b51d25ded Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:31:24 -0500 Subject: [PATCH 3/9] ci: serialize one-shot runtime env repair --- .github/workflows/one-shot-runtime-env-test-patch.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/one-shot-runtime-env-test-patch.yml b/.github/workflows/one-shot-runtime-env-test-patch.yml index 7370a5e0e..3f895abcc 100644 --- a/.github/workflows/one-shot-runtime-env-test-patch.yml +++ b/.github/workflows/one-shot-runtime-env-test-patch.yml @@ -8,6 +8,10 @@ on: permissions: contents: read +concurrency: + group: one-shot-runtime-env-test-patch-${{ github.ref }} + cancel-in-progress: true + jobs: patch: runs-on: ubuntu-24.04 From 954ea94a1d98545ae4728c404b4e2e2d44b20efd Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:31:36 -0500 Subject: [PATCH 4/9] ci: harden ores-lint provenance and permissions --- .github/workflows/ores-lint.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ores-lint.yml b/.github/workflows/ores-lint.yml index dd1d98271..897759f34 100644 --- a/.github/workflows/ores-lint.yml +++ b/.github/workflows/ores-lint.yml @@ -6,11 +6,23 @@ on: workflow_dispatch: # Add `push:` here once this repo's lint debt is paid down. +permissions: + contents: read + +concurrency: + group: ores-lint-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 + timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + fetch-depth: 1 + show-progress: false - name: Detect project types id: detect @@ -18,10 +30,11 @@ jobs: [ -f package.json ] && echo "js=true" >> "$GITHUB_OUTPUT" || echo "js=false" >> "$GITHUB_OUTPUT" [ -f Cargo.toml ] && echo "rs=true" >> "$GITHUB_OUTPUT" || echo "rs=false" >> "$GITHUB_OUTPUT" - - uses: actions/setup-node@v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 if: steps.detect.outputs.js == 'true' with: node-version: '22' + package-manager-cache: false # ESLint is a global tool here, not a repo dependency - so this job never # runs `npm install` and never needs the repo's node_modules. From 1edbcbe11e6d9f0db3e49af41271eb0556b1baa8 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:31:50 -0500 Subject: [PATCH 5/9] ci: scope role-contract write authority to fixup job --- .github/workflows/role-contract.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/role-contract.yml b/.github/workflows/role-contract.yml index 1b7288a5d..fa8f663f4 100644 --- a/.github/workflows/role-contract.yml +++ b/.github/workflows/role-contract.yml @@ -17,7 +17,7 @@ on: workflow_dispatch: permissions: - contents: write + contents: read concurrency: group: role-contract-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -25,7 +25,7 @@ concurrency: jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 5 steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -39,14 +39,18 @@ jobs: branch-fixup: if: github.event_name == 'pull_request' && github.head_ref == 'feat/role-contract-fix' + permissions: + contents: write runs-on: ubuntu-24.04 timeout-minutes: 30 + env: + GH_TOKEN: ${{ github.token }} steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 with: ref: feat/role-contract-fix fetch-depth: 0 - persist-credentials: true + persist-credentials: false - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 with: toolchain: stable @@ -67,6 +71,8 @@ jobs: run: cargo clippy --locked --all-targets -- -D warnings - name: Commit tested fixes and restore the permanent workflow run: | + set -euo pipefail + gh auth setup-git git fetch origin main --depth=1 git show FETCH_HEAD:.github/workflows/role-contract.yml > .github/workflows/role-contract.yml rm -f .github/workflows/branch-fixup.yml tools/branch_fixup.py From 9ddc0b28e882ed334251b1dab16b203616a460d6 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:33:14 -0500 Subject: [PATCH 6/9] test: register dynamic fleet module before dataclass execution --- tests/role-contract/test_github_interface_fleet.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/role-contract/test_github_interface_fleet.py b/tests/role-contract/test_github_interface_fleet.py index 555d908f9..31d0464ee 100644 --- a/tests/role-contract/test_github_interface_fleet.py +++ b/tests/role-contract/test_github_interface_fleet.py @@ -2,6 +2,7 @@ import importlib.util import json +import sys import tempfile import unittest from pathlib import Path @@ -15,6 +16,7 @@ SPEC = importlib.util.spec_from_file_location("github_interface_fleet", SCRIPT) assert SPEC is not None and SPEC.loader is not None MODULE = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) From 3424318982068573345bd3e08c01fa631d040822 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:41:17 -0500 Subject: [PATCH 7/9] style: apply Rust 1.98.1 formatter baseline --- src/bin/zed-env-contract.rs | 290 +++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 69 deletions(-) diff --git a/src/bin/zed-env-contract.rs b/src/bin/zed-env-contract.rs index c01c94293..c7997fe2c 100644 --- a/src/bin/zed-env-contract.rs +++ b/src/bin/zed-env-contract.rs @@ -1,6 +1,10 @@ -use std::{collections::{BTreeMap, BTreeSet}, env, fs, path::{Path, PathBuf}}; +use std::{ + collections::{BTreeMap, BTreeSet}, + env, fs, + path::{Path, PathBuf}, +}; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use toml::Value; #[derive(Debug, Clone)] @@ -35,7 +39,13 @@ fn run() -> Result<()> { "check" => check_values(&vars), "list" => { for var in vars.values() { - println!("{}\t{}\t{}\t{}", var.name, var.kind, requirement(var), if var.secret { "secret" } else { "plain" }); + println!( + "{}\t{}\t{}\t{}", + var.name, + var.kind, + requirement(var), + if var.secret { "secret" } else { "plain" } + ); } Ok(()) } @@ -45,67 +55,123 @@ fn run() -> Result<()> { println!("# {description}"); } println!("# {} ({})", requirement(var), var.kind); - let value = if var.secret { "" } else { var.default.as_deref().unwrap_or("") }; + let value = if var.secret { + "" + } else { + var.default.as_deref().unwrap_or("") + }; println!("{}={}\n", var.name, value); } Ok(()) } "json" => { - let rows = vars.values().map(|v| serde_json::json!({ - "name": v.name, - "type": v.kind, - "required": v.required, - "required_when": v.required_when, - "default": if v.secret { None:: } else { v.default.clone() }, - "secret": v.secret, - "description": v.description, - "enum": v.allowed, - "deprecated": v.deprecated, - "replacement": v.replacement, - })).collect::>(); + let rows = vars + .values() + .map(|v| { + serde_json::json!({ + "name": v.name, + "type": v.kind, + "required": v.required, + "required_when": v.required_when, + "default": if v.secret { None:: } else { v.default.clone() }, + "secret": v.secret, + "description": v.description, + "enum": v.allowed, + "deprecated": v.deprecated, + "replacement": v.replacement, + }) + }) + .collect::>(); println!("{}", serde_json::to_string_pretty(&rows)?); Ok(()) } - other => bail!("unknown env-contract command `{other}`; expected check, list, template, or json"), + other => { + bail!("unknown env-contract command `{other}`; expected check, list, template, or json") + } } } fn manifest_path(explicit: Option) -> Result { - if let Some(path) = explicit { return Ok(path); } + if let Some(path) = explicit { + return Ok(path); + } let mut current = env::current_dir()?; loop { let candidate = current.join(".zpkg.toml"); - if candidate.is_file() { return Ok(candidate); } - if !current.pop() { break; } + if candidate.is_file() { + return Ok(candidate); + } + if !current.pop() { + break; + } } bail!("could not find .zpkg.toml in this directory or any parent") } fn load_contract(path: &Path) -> Result> { - let text = fs::read_to_string(path).with_context(|| format!("failed to read {}", path.display()))?; - let root: Value = text.parse().with_context(|| format!("invalid TOML in {}", path.display()))?; - let Some(env_table) = root.get("env").and_then(Value::as_table) else { return Ok(BTreeMap::new()); }; - let Some(rows) = env_table.get("vars").and_then(Value::as_array) else { return Ok(BTreeMap::new()); }; + let text = + fs::read_to_string(path).with_context(|| format!("failed to read {}", path.display()))?; + let root: Value = text + .parse() + .with_context(|| format!("invalid TOML in {}", path.display()))?; + let Some(env_table) = root.get("env").and_then(Value::as_table) else { + return Ok(BTreeMap::new()); + }; + let Some(rows) = env_table.get("vars").and_then(Value::as_array) else { + return Ok(BTreeMap::new()); + }; let mut out = BTreeMap::new(); for row in rows { - let table = row.as_table().context("each [[env.vars]] entry must be a table")?; + let table = row + .as_table() + .context("each [[env.vars]] entry must be a table")?; let name = string(table, "name")?.to_string(); - if out.contains_key(&name) { bail!("duplicate env contract variable `{name}`"); } - let allowed = table.get("enum").and_then(Value::as_array).map(|values| { - values.iter().map(|v| v.as_str().context("env var enum values must be strings").map(str::to_owned)).collect::>>() - }).transpose()?.unwrap_or_default(); - out.insert(name.clone(), EnvVar { - name, - kind: table.get("type").and_then(Value::as_str).unwrap_or("string").to_string(), - required: table.get("required").and_then(Value::as_bool).unwrap_or(false), - required_when: opt_string(table, "required_when")?, - default: opt_scalar_string(table, "default")?, - secret: table.get("secret").and_then(Value::as_bool).unwrap_or(false), - description: opt_string(table, "description")?, - allowed, - deprecated: table.get("deprecated").and_then(Value::as_bool).unwrap_or(false), - replacement: opt_string(table, "replacement")?, - }); + if out.contains_key(&name) { + bail!("duplicate env contract variable `{name}`"); + } + let allowed = table + .get("enum") + .and_then(Value::as_array) + .map(|values| { + values + .iter() + .map(|v| { + v.as_str() + .context("env var enum values must be strings") + .map(str::to_owned) + }) + .collect::>>() + }) + .transpose()? + .unwrap_or_default(); + out.insert( + name.clone(), + EnvVar { + name, + kind: table + .get("type") + .and_then(Value::as_str) + .unwrap_or("string") + .to_string(), + required: table + .get("required") + .and_then(Value::as_bool) + .unwrap_or(false), + required_when: opt_string(table, "required_when")?, + default: opt_scalar_string(table, "default")?, + secret: table + .get("secret") + .and_then(Value::as_bool) + .unwrap_or(false), + description: opt_string(table, "description")?, + allowed, + deprecated: table + .get("deprecated") + .and_then(Value::as_bool) + .unwrap_or(false), + replacement: opt_string(table, "replacement")?, + }, + ); } Ok(out) } @@ -113,19 +179,41 @@ fn load_contract(path: &Path) -> Result> { fn validate_contract(vars: &BTreeMap) -> Result<()> { const TYPES: &[&str] = &["string", "integer", "boolean", "url", "json"]; for var in vars.values() { - if !valid_env_name(&var.name) { bail!("invalid environment variable name `{}`", var.name); } - if !TYPES.contains(&var.kind.as_str()) { bail!("unsupported type `{}` for `{}`", var.kind, var.name); } - if var.secret && var.default.is_some() { bail!("secret `{}` must not declare a default value", var.name); } + if !valid_env_name(&var.name) { + bail!("invalid environment variable name `{}`", var.name); + } + if !TYPES.contains(&var.kind.as_str()) { + bail!("unsupported type `{}` for `{}`", var.kind, var.name); + } + if var.secret && var.default.is_some() { + bail!("secret `{}` must not declare a default value", var.name); + } if let Some(default) = &var.default { - validate_value(var, default).with_context(|| format!("invalid default for `{}`", var.name))?; + validate_value(var, default) + .with_context(|| format!("invalid default for `{}`", var.name))?; } if let Some(replacement) = &var.replacement { - if !var.deprecated { bail!("`{}` declares replacement without deprecated=true", var.name); } - if !vars.contains_key(replacement) { bail!("replacement `{replacement}` for `{}` is not declared", var.name); } + if !var.deprecated { + bail!( + "`{}` declares replacement without deprecated=true", + var.name + ); + } + if !vars.contains_key(replacement) { + bail!( + "replacement `{replacement}` for `{}` is not declared", + var.name + ); + } } if let Some(condition) = &var.required_when { let (dependency, _, _) = parse_condition(condition)?; - if !vars.contains_key(dependency) { bail!("required_when for `{}` references undeclared `{dependency}`", var.name); } + if !vars.contains_key(dependency) { + bail!( + "required_when for `{}` references undeclared `{dependency}`", + var.name + ); + } } } Ok(()) @@ -135,24 +223,53 @@ fn check_values(vars: &BTreeMap) -> Result<()> { let snapshot = env::vars().collect::>(); let mut missing = BTreeSet::new(); for var in vars.values() { - let needed = var.required || var.required_when.as_deref().map(|c| condition_matches(c, &snapshot)).transpose()?.unwrap_or(false); + let needed = var.required + || var + .required_when + .as_deref() + .map(|c| condition_matches(c, &snapshot)) + .transpose()? + .unwrap_or(false); match snapshot.get(&var.name) { - Some(value) => validate_value(var, value).with_context(|| format!("invalid value for `{}`", var.name))?, - None if needed && var.default.is_none() => { missing.insert(var.name.clone()); }, + Some(value) => validate_value(var, value) + .with_context(|| format!("invalid value for `{}`", var.name))?, + None if needed && var.default.is_none() => { + missing.insert(var.name.clone()); + } None => {} } } - if !missing.is_empty() { bail!("missing required environment variables: {}", missing.into_iter().collect::>().join(", ")); } + if !missing.is_empty() { + bail!( + "missing required environment variables: {}", + missing.into_iter().collect::>().join(", ") + ); + } println!("environment contract ok ({} variables)", vars.len()); Ok(()) } fn validate_value(var: &EnvVar, value: &str) -> Result<()> { match var.kind.as_str() { - "integer" => { value.parse::().context("expected integer")?; } - "boolean" => { if !matches!(value.to_ascii_lowercase().as_str(), "true"|"false"|"1"|"0"|"yes"|"no"|"on"|"off") { bail!("expected boolean"); } } - "json" => { serde_json::from_str::(value).context("expected JSON")?; } - "url" => { if !value.contains("://") { bail!("expected absolute URL"); } } + "integer" => { + value.parse::().context("expected integer")?; + } + "boolean" => { + if !matches!( + value.to_ascii_lowercase().as_str(), + "true" | "false" | "1" | "0" | "yes" | "no" | "on" | "off" + ) { + bail!("expected boolean"); + } + } + "json" => { + serde_json::from_str::(value).context("expected JSON")?; + } + "url" => { + if !value.contains("://") { + bail!("expected absolute URL"); + } + } "string" => {} _ => unreachable!(), } @@ -165,15 +282,27 @@ fn validate_value(var: &EnvVar, value: &str) -> Result<()> { fn condition_matches(condition: &str, values: &BTreeMap) -> Result { let (name, op, expected) = parse_condition(condition)?; let actual = values.get(name).map(String::as_str).unwrap_or(""); - Ok(if op == "==" { actual == expected } else { actual != expected }) + Ok(if op == "==" { + actual == expected + } else { + actual != expected + }) } fn parse_condition(input: &str) -> Result<(&str, &str, &str)> { - let (name, op, rhs) = if let Some((a,b)) = input.split_once(" == ") { (a.trim(), "==", b.trim()) } - else if let Some((a,b)) = input.split_once(" != ") { (a.trim(), "!=", b.trim()) } - else { bail!("required_when supports only `VAR == 'value'` and `VAR != 'value'`"); }; - if !valid_env_name(name) { bail!("invalid variable `{name}` in required_when"); } - let expected = rhs.strip_prefix('\'').and_then(|v| v.strip_suffix('\'')) + let (name, op, rhs) = if let Some((a, b)) = input.split_once(" == ") { + (a.trim(), "==", b.trim()) + } else if let Some((a, b)) = input.split_once(" != ") { + (a.trim(), "!=", b.trim()) + } else { + bail!("required_when supports only `VAR == 'value'` and `VAR != 'value'`"); + }; + if !valid_env_name(name) { + bail!("invalid variable `{name}` in required_when"); + } + let expected = rhs + .strip_prefix('\'') + .and_then(|v| v.strip_suffix('\'')) .or_else(|| rhs.strip_prefix('"').and_then(|v| v.strip_suffix('"'))) .context("required_when value must be quoted")?; Ok((name, op, expected)) @@ -181,21 +310,44 @@ fn parse_condition(input: &str) -> Result<(&str, &str, &str)> { fn valid_env_name(name: &str) -> bool { let mut chars = name.chars(); - matches!(chars.next(), Some('A'..='Z' | '_')) && chars.all(|c| matches!(c, 'A'..='Z' | '0'..='9' | '_')) + matches!(chars.next(), Some('A'..='Z' | '_')) + && chars.all(|c| matches!(c, 'A'..='Z' | '0'..='9' | '_')) } fn requirement(var: &EnvVar) -> String { - if var.required { "required".into() } - else if let Some(c) = &var.required_when { format!("required when {c}") } - else { "optional".into() } + if var.required { + "required".into() + } else if let Some(c) = &var.required_when { + format!("required when {c}") + } else { + "optional".into() + } } fn string<'a>(table: &'a toml::map::Map, key: &str) -> Result<&'a str> { - table.get(key).and_then(Value::as_str).with_context(|| format!("missing string `{key}` in [[env.vars]]")) + table + .get(key) + .and_then(Value::as_str) + .with_context(|| format!("missing string `{key}` in [[env.vars]]")) } fn opt_string(table: &toml::map::Map, key: &str) -> Result> { - table.get(key).map(|v| v.as_str().map(str::to_owned).with_context(|| format!("`{key}` must be a string"))).transpose() + table + .get(key) + .map(|v| { + v.as_str() + .map(str::to_owned) + .with_context(|| format!("`{key}` must be a string")) + }) + .transpose() } fn opt_scalar_string(table: &toml::map::Map, key: &str) -> Result> { - table.get(key).map(|v| match v { Value::String(s) => Ok(s.clone()), Value::Integer(v) => Ok(v.to_string()), Value::Boolean(v) => Ok(v.to_string()), _ => bail!("`{key}` must be a string, integer, or boolean") }).transpose() + table + .get(key) + .map(|v| match v { + Value::String(s) => Ok(s.clone()), + Value::Integer(v) => Ok(v.to_string()), + Value::Boolean(v) => Ok(v.to_string()), + _ => bail!("`{key}` must be a string, integer, or boolean"), + }) + .transpose() } From 955937a44e48b6b5882eedd731a1f61e0d5d6d37 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:41:31 -0500 Subject: [PATCH 8/9] style: format env contract tests --- tests/env_contract.rs | 52 ++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/tests/env_contract.rs b/tests/env_contract.rs index 3680dc7f6..8051fdc26 100644 --- a/tests/env_contract.rs +++ b/tests/env_contract.rs @@ -1,7 +1,14 @@ -use std::{fs, process::Command, time::{SystemTime, UNIX_EPOCH}}; +use std::{ + fs, + process::Command, + time::{SystemTime, UNIX_EPOCH}, +}; fn fixture(contents: &str) -> std::path::PathBuf { - let suffix = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos(); + let suffix = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(); let dir = std::env::temp_dir().join(format!("zed-env-contract-{suffix}")); fs::create_dir_all(&dir).unwrap(); let path = dir.join(".zpkg.toml"); @@ -11,7 +18,8 @@ fn fixture(contents: &str) -> std::path::PathBuf { #[test] fn accepts_conditional_requirements_when_not_selected() { - let manifest = fixture(r#" + let manifest = fixture( + r#" [package] name = "locks" @@ -25,17 +33,22 @@ name = "REDIS_URL" type = "url" secret = true required_when = "ORES_LOCK_BACKEND == 'redis'" -"#); +"#, + ); let status = Command::new(env!("CARGO_BIN_EXE_zed-env-contract")) - .arg("check").arg(&manifest) - .env_remove("ORES_LOCK_BACKEND").env_remove("REDIS_URL") - .status().unwrap(); + .arg("check") + .arg(&manifest) + .env_remove("ORES_LOCK_BACKEND") + .env_remove("REDIS_URL") + .status() + .unwrap(); assert!(status.success()); } #[test] fn requires_conditionally_selected_secret() { - let manifest = fixture(r#" + let manifest = fixture( + r#" [[env.vars]] name = "ORES_LOCK_BACKEND" enum = ["postgres", "redis"] @@ -45,25 +58,34 @@ name = "REDIS_URL" type = "url" secret = true required_when = "ORES_LOCK_BACKEND == 'redis'" -"#); +"#, + ); let output = Command::new(env!("CARGO_BIN_EXE_zed-env-contract")) - .arg("check").arg(&manifest) - .env("ORES_LOCK_BACKEND", "redis").env_remove("REDIS_URL") - .output().unwrap(); + .arg("check") + .arg(&manifest) + .env("ORES_LOCK_BACKEND", "redis") + .env_remove("REDIS_URL") + .output() + .unwrap(); assert!(!output.status.success()); assert!(String::from_utf8_lossy(&output.stderr).contains("REDIS_URL")); } #[test] fn rejects_secret_defaults() { - let manifest = fixture(r#" + let manifest = fixture( + r#" [[env.vars]] name = "TOKEN" secret = true default = "do-not-do-this" -"#); +"#, + ); let output = Command::new(env!("CARGO_BIN_EXE_zed-env-contract")) - .arg("check").arg(&manifest).output().unwrap(); + .arg("check") + .arg(&manifest) + .output() + .unwrap(); assert!(!output.status.success()); assert!(String::from_utf8_lossy(&output.stderr).contains("must not declare a default")); } From b2ae0c440b1992e465fff2696e3e985349efb073 Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Tue, 15 Sep 2026 15:41:49 -0500 Subject: [PATCH 9/9] style: format TOML contract tests --- tests/toml_contract.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/toml_contract.rs b/tests/toml_contract.rs index 04b406f49..1a4ec8bbd 100644 --- a/tests/toml_contract.rs +++ b/tests/toml_contract.rs @@ -9,8 +9,7 @@ fn root() -> PathBuf { fn parse_toml(path: &Path) -> toml::Value { let text = fs::read_to_string(path) .unwrap_or_else(|error| panic!("failed to read {}: {error}", path.display())); - toml::from_str(&text) - .unwrap_or_else(|error| panic!("invalid TOML {}: {error}", path.display())) + toml::from_str(&text).unwrap_or_else(|error| panic!("invalid TOML {}: {error}", path.display())) } fn string_at<'a>(value: &'a toml::Value, path: &[&str]) -> &'a str { @@ -133,7 +132,10 @@ fn global_flags_do_not_reuse_environment_keys_or_public_aliases() { if alias == canonical_alias { continue; } - assert!(aliases.insert(alias.to_owned()), "duplicate global flag alias: {alias}"); + assert!( + aliases.insert(alias.to_owned()), + "duplicate global flag alias: {alias}" + ); } } }