From e977bb29a2a5528c57c33799b54b57c7578bd80d Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 10 Jun 2026 14:24:51 +0200 Subject: [PATCH 1/5] Adds FormatInitTemplate type and format_init_template trait method --- crates/core/src/lib.rs | 4 ++-- crates/core/src/plugins/mod.rs | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 0f0d19c..94309c4 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -46,8 +46,8 @@ pub use config::{AssetsField, PluginAssets, PluginSection, Spine}; // Plugin trait and context pub use plugins::{ - AssetConfig, CompiledHtmlVertebra, FormatPlugin, LinkStrategy, OpenHandle, PackageAssets, - PluginContext, ResolvedPackage, ServerHandle, SpineOptions, + AssetConfig, CompiledHtmlVertebra, FormatInitTemplate, FormatPlugin, LinkStrategy, OpenHandle, + PackageAssets, PluginContext, ResolvedPackage, ServerHandle, SpineOptions, }; pub use reticulate::types::RheoValue; diff --git a/crates/core/src/plugins/mod.rs b/crates/core/src/plugins/mod.rs index 9277d39..27b5549 100644 --- a/crates/core/src/plugins/mod.rs +++ b/crates/core/src/plugins/mod.rs @@ -77,6 +77,21 @@ pub struct Asset { pub built_relative_path: String, } +/// Template data contributed by a plugin for `rheo init`. +/// +/// Combines the former `init_template_files` and +/// `init_rheo_toml_section_template` into a single struct returned by +/// [`FormatPlugin::format_init_template`]. +#[derive(Debug, Clone, Default)] +pub struct FormatInitTemplate { + /// `(relative_path, content)` pairs written verbatim by `rheo init`. + /// Was `init_template_files`. + pub files: Vec<(&'static str, &'static str)>, + /// TOML snippet embedded under `[.*]` in the generated `rheo.toml`. + /// Was `init_rheo_toml_section_template`. + pub options_toml: Option<&'static str>, +} + /// Context passed to plugin.compile() for each compilation unit. pub struct PluginContext<'a> { pub project: &'a ProjectConfig, @@ -639,6 +654,15 @@ pub trait FormatPlugin: Send + Sync { None } + /// Combined init template: files and TOML config section for `rheo init`. + /// + /// Supersedes [`init_template_files`](Self::init_template_files) and + /// [`init_rheo_toml_section_template`](Self::init_rheo_toml_section_template). + /// The default returns an empty template (no files, no TOML section). + fn format_init_template(&self) -> FormatInitTemplate { + FormatInitTemplate::default() + } + /// Provide Typst library code to inject into all compiled files. /// /// This method allows plugins to contribute format-specific Typst functions, From dcec092ada94233f936985f1d14db58544ae5140 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 10 Jun 2026 14:29:08 +0200 Subject: [PATCH 2/5] Migrates plugins and init consumer to format_init_template --- crates/cli/src/lib.rs | 6 ++++-- crates/epub/src/lib.rs | 11 +++++++---- crates/html/src/lib.rs | 29 ++++++++++++++--------------- crates/pdf/src/lib.rs | 9 ++++++--- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 83d855c..8f90ab8 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -249,7 +249,8 @@ fn init_project(target_dir: &Path) -> Result<()> { let mut toml_content = rheo_core::init_templates::RHEO_TOML.replace("{{VERSION}}", manifest_version::CURRENT); for plugin in all_plugins() { - if let Some(section) = plugin.init_rheo_toml_section_template() { + let tmpl = plugin.format_init_template(); + if let Some(section) = tmpl.options_toml { toml_content.push('\n'); toml_content.push_str(&prefix_toml_headers(section, plugin.name())); toml_content.push('\n'); @@ -289,7 +290,8 @@ fn init_project(target_dir: &Path) -> Result<()> { let mut plugin_templates: std::collections::HashMap<&str, (&str, &str)> = std::collections::HashMap::new(); for plugin in all_plugins() { - for (path, content) in plugin.init_template_files() { + let tmpl = plugin.format_init_template(); + for (path, content) in tmpl.files { if let Some((existing_plugin, _)) = plugin_templates.get(path) { return Err(RheoError::project_config(format!( "template path conflict: both '{}' and '{}' plugins want to write '{}'", diff --git a/crates/epub/src/lib.rs b/crates/epub/src/lib.rs index dadf7f4..010f927 100644 --- a/crates/epub/src/lib.rs +++ b/crates/epub/src/lib.rs @@ -11,8 +11,8 @@ use rheo_core::{ DocumentTitle, EcoString, HeadingElem, HtmlDocument, NativeElement, OutlineNode, StyleChain, }; use rheo_core::{ - FormatPlugin, PluginContext, PluginSection, Result, RheoError, Spine, SpineOptions, - compile_document_to_string, eco_format, eco_vec, + FormatInitTemplate, FormatPlugin, PluginContext, PluginSection, Result, RheoError, Spine, + SpineOptions, compile_document_to_string, eco_format, eco_vec, }; use serde::Deserialize; use std::{ @@ -54,8 +54,11 @@ impl FormatPlugin for EpubPlugin { } } - fn init_rheo_toml_section_template(&self) -> Option<&'static str> { - Some(include_str!("templates/init/rheo_section.toml")) + fn format_init_template(&self) -> FormatInitTemplate { + FormatInitTemplate { + files: vec![], + options_toml: Some(include_str!("templates/init/rheo_section.toml")), + } } fn compile(&self, ctx: PluginContext<'_>) -> Result<()> { diff --git a/crates/html/src/lib.rs b/crates/html/src/lib.rs index 277bc5a..37bd1e4 100644 --- a/crates/html/src/lib.rs +++ b/crates/html/src/lib.rs @@ -11,8 +11,8 @@ use serde::Deserialize; pub const DEFAULT_STYLESHEET: &str = include_str!("templates/style.css"); use rheo_core::{ - AssetConfig, CompiledHtmlVertebra, FormatPlugin, OpenHandle, PluginContext, Result, RheoError, - RheoValue, ServerHandle, + AssetConfig, CompiledHtmlVertebra, FormatInitTemplate, FormatPlugin, OpenHandle, + PluginContext, Result, RheoError, RheoValue, ServerHandle, }; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -50,19 +50,18 @@ impl FormatPlugin for HtmlPlugin { PLUGIN_NAME } - fn init_template_files(&self) -> Vec<(&'static str, &'static str)> { - vec![ - // The stylesheet included with the template mirrors the default stylesheet, so that - // users can build from it or start from scratch as they wish. - ("style.css", include_str!("templates/style.css")), - // A demonstrative JS file that just logs to console. See the examples/ directory for - // how to use Rheo with bundled JS. - ("index.js", include_str!("templates/index.js")), - ] - } - - fn init_rheo_toml_section_template(&self) -> Option<&'static str> { - Some(include_str!("templates/init/rheo_section.toml")) + fn format_init_template(&self) -> FormatInitTemplate { + FormatInitTemplate { + files: vec![ + // The stylesheet included with the template mirrors the default stylesheet, so that + // users can build from it or start from scratch as they wish. + ("style.css", include_str!("templates/style.css")), + // A demonstrative JS file that just logs to console. See the examples/ directory for + // how to use Rheo with bundled JS. + ("index.js", include_str!("templates/index.js")), + ], + options_toml: Some(include_str!("templates/init/rheo_section.toml")), + } } fn open(&self, output_dir: &Path, _format_name: &str) -> Result { diff --git a/crates/pdf/src/lib.rs b/crates/pdf/src/lib.rs index d5c6270..022a16f 100644 --- a/crates/pdf/src/lib.rs +++ b/crates/pdf/src/lib.rs @@ -1,4 +1,4 @@ -use rheo_core::{FormatPlugin, LinkStrategy, PluginContext, Result}; +use rheo_core::{FormatInitTemplate, FormatPlugin, LinkStrategy, PluginContext, Result}; pub struct PdfPlugin; const PLUGIN_NAME: &str = "pdf"; @@ -14,8 +14,11 @@ impl FormatPlugin for PdfPlugin { LinkStrategy::PagedLabels } - fn init_rheo_toml_section_template(&self) -> Option<&'static str> { - Some(include_str!("templates/init/rheo_section.toml")) + fn format_init_template(&self) -> FormatInitTemplate { + FormatInitTemplate { + files: vec![], + options_toml: Some(include_str!("templates/init/rheo_section.toml")), + } } fn typst_library(&self) -> Option<&'static str> { From ee8d2d6a3e8432214ae3cbdb656e86763ab20029 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 10 Jun 2026 14:31:07 +0200 Subject: [PATCH 3/5] Removes obsolete init_template_files and init_rheo_toml_section_template --- crates/core/src/plugins/mod.rs | 68 ++-------------------------------- crates/html/src/lib.rs | 4 +- 2 files changed, 5 insertions(+), 67 deletions(-) diff --git a/crates/core/src/plugins/mod.rs b/crates/core/src/plugins/mod.rs index 27b5549..9d95c16 100644 --- a/crates/core/src/plugins/mod.rs +++ b/crates/core/src/plugins/mod.rs @@ -79,16 +79,12 @@ pub struct Asset { /// Template data contributed by a plugin for `rheo init`. /// -/// Combines the former `init_template_files` and -/// `init_rheo_toml_section_template` into a single struct returned by -/// [`FormatPlugin::format_init_template`]. +/// Returned by [`FormatPlugin::format_init_template`]. #[derive(Debug, Clone, Default)] pub struct FormatInitTemplate { /// `(relative_path, content)` pairs written verbatim by `rheo init`. - /// Was `init_template_files`. pub files: Vec<(&'static str, &'static str)>, /// TOML snippet embedded under `[.*]` in the generated `rheo.toml`. - /// Was `init_rheo_toml_section_template`. pub options_toml: Option<&'static str>, } @@ -596,69 +592,11 @@ pub trait FormatPlugin: Send + Sync { vec![] } - /// Provide template files for `rheo init` to write to new projects. - /// - /// This method allows plugins to contribute format-specific template files - /// (e.g., CSS for HTML, custom Typst includes) when initializing a new rheo project. - /// - /// # Return value - /// - /// A vector of `(relative_path, content)` tuples where: - /// - `relative_path` is the file path relative to the project root (e.g., `"style.css"`, `"content/example.typ"`) - /// - `content` is the file contents as a static string - /// - /// # Path conflicts - /// - /// If two plugins claim the same `relative_path`, rheo returns an error at init time. - /// Core templates take precedence over plugin templates (plugins can override core paths - /// only if the core explicitly provides empty placeholders). - /// - /// # Examples - /// - /// ```ignore - /// fn init_template_files(&self) -> Vec<(&'static str, &'static str)> { - /// vec![ - /// ("style.css", include_str!("templates/style.css")), - /// ("content/html-example.typ", include_str!("templates/example.typ")), - /// ] - /// } - /// ``` - /// - /// # Default implementation - /// - /// Returns an empty vector (no template files contributed). - fn init_template_files(&self) -> Vec<(&'static str, &'static str)> { - vec![] - } - - /// Provide a `rheo.toml` configuration section template for `rheo init`. - /// - /// The returned content should use section-relative headers (e.g. `[spine]` - /// rather than `[html.spine]`) — the `init` command automatically prefixes - /// each header with the plugin name when building the final `rheo.toml`. - /// - /// # Return value - /// - /// - `Some(content)` — TOML snippet to embed under `[.*]` in the - /// generated `rheo.toml` - /// - `None` — no config section contributed (default) - /// - /// # Examples - /// - /// ```ignore - /// fn init_rheo_toml_section_template(&self) -> Option<&'static str> { - /// Some(include_str!("templates/init/rheo_section.toml")) - /// } - /// ``` - fn init_rheo_toml_section_template(&self) -> Option<&'static str> { - None - } - /// Combined init template: files and TOML config section for `rheo init`. /// - /// Supersedes [`init_template_files`](Self::init_template_files) and - /// [`init_rheo_toml_section_template`](Self::init_rheo_toml_section_template). /// The default returns an empty template (no files, no TOML section). + /// Override to contribute format-specific template files and/or a config + /// section snippet. fn format_init_template(&self) -> FormatInitTemplate { FormatInitTemplate::default() } diff --git a/crates/html/src/lib.rs b/crates/html/src/lib.rs index 37bd1e4..bce948d 100644 --- a/crates/html/src/lib.rs +++ b/crates/html/src/lib.rs @@ -11,8 +11,8 @@ use serde::Deserialize; pub const DEFAULT_STYLESHEET: &str = include_str!("templates/style.css"); use rheo_core::{ - AssetConfig, CompiledHtmlVertebra, FormatInitTemplate, FormatPlugin, OpenHandle, - PluginContext, Result, RheoError, RheoValue, ServerHandle, + AssetConfig, CompiledHtmlVertebra, FormatInitTemplate, FormatPlugin, OpenHandle, PluginContext, + Result, RheoError, RheoValue, ServerHandle, }; use std::collections::HashMap; use std::path::{Path, PathBuf}; From 3624cd41401a8d2898ebe47148362750c9d1c5be Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 10 Jun 2026 15:01:39 +0200 Subject: [PATCH 4/5] Cleans gitignore for beads --- .gitignore | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.gitignore b/.gitignore index 7ac4bb7..b640f4f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,16 +6,6 @@ result-* # Beads runtime/ephemeral files .beads/ -.beads/bd.sock -.beads/beads.db -.beads/beads.db-shm -.beads/beads.db-wal -.beads/daemon.lock -.beads/daemon.log -.beads/daemon.pid -.beads/.br_history/ -.beads/.write.lock -.beads/last-touched .abacus/ # Claude From f9fbd0d64df00fcdc05a8f58a8bab29ac3aaca98 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 10 Jun 2026 15:29:10 +0200 Subject: [PATCH 5/5] Centralizes rheo CLI invocation behind configurable helper --- crates/tests/src/helpers/cli.rs | 22 ++++ crates/tests/src/helpers/mod.rs | 1 + crates/tests/src/helpers/remote.rs | 13 +- crates/tests/tests/harness.rs | 194 ++++++----------------------- 4 files changed, 65 insertions(+), 165 deletions(-) create mode 100644 crates/tests/src/helpers/cli.rs diff --git a/crates/tests/src/helpers/cli.rs b/crates/tests/src/helpers/cli.rs new file mode 100644 index 0000000..e76c082 --- /dev/null +++ b/crates/tests/src/helpers/cli.rs @@ -0,0 +1,22 @@ +use std::process::Command; + +/// Build a `Command` that invokes the rheo CLI. +/// +/// - If `RHEO_BIN` is set: returns `Command::new()` — caller appends +/// subcommand args directly (no `cargo run` prefix). +/// - Else: returns `Command::new("cargo")` with `run` + optional +/// `--manifest-path ` + `-p rheo --`, reproducing the +/// current monorepo `cargo run -p rheo --` behaviour. +pub fn rheo_cli_command() -> Command { + if let Ok(bin) = std::env::var("RHEO_BIN") { + Command::new(bin) + } else { + let mut cmd = Command::new("cargo"); + cmd.arg("run"); + if let Ok(manifest) = std::env::var("RHEO_MANIFEST") { + cmd.args(["--manifest-path", &manifest]); + } + cmd.args(["-p", "rheo", "--"]); + cmd + } +} diff --git a/crates/tests/src/helpers/mod.rs b/crates/tests/src/helpers/mod.rs index 1eb6dd0..b97b997 100644 --- a/crates/tests/src/helpers/mod.rs +++ b/crates/tests/src/helpers/mod.rs @@ -1,3 +1,4 @@ +pub mod cli; pub mod comparison; pub mod fixtures; pub mod markers; diff --git a/crates/tests/src/helpers/remote.rs b/crates/tests/src/helpers/remote.rs index e3fb60d..35906ef 100644 --- a/crates/tests/src/helpers/remote.rs +++ b/crates/tests/src/helpers/remote.rs @@ -3,6 +3,8 @@ use std::path::Path; use std::path::PathBuf; use std::process::Command; +use super::cli::rheo_cli_command; + /// Clone a public GitHub repo using `git clone --depth 1`. /// /// Destination: `crates/tests/store/compat//`. @@ -90,15 +92,8 @@ pub fn run_compat(url: &str, name: &str) { let cloned_path = clone_repo(url, name); patch_rheo_version(&cloned_path); - let output = Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "compile", - cloned_path.to_str().unwrap(), - ]) + let output = rheo_cli_command() + .args(["compile", cloned_path.to_str().unwrap()]) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() .unwrap_or_else(|e| panic!("Failed to run rheo compile: {}", e)); diff --git a/crates/tests/tests/harness.rs b/crates/tests/tests/harness.rs index d4c0c34..26fa976 100644 --- a/crates/tests/tests/harness.rs +++ b/crates/tests/tests/harness.rs @@ -1,6 +1,7 @@ use ntest::test_case; use rheo_core::{RheoConfig, project::ProjectConfig}; use rheo_tests::helpers::{ + cli::rheo_cli_command, comparison::{verify_epub_output, verify_html_output, verify_pdf_output}, fixtures::TestCase, reference::{update_epub_references, update_html_references, update_pdf_references}, @@ -136,14 +137,7 @@ fn run_test_case(name: &str) { let build_dir = test_store.join("build"); // Build compile command with format flags - let mut compile_args = vec![ - "run", - "-p", - "rheo", - "--", - "compile", - project_path.to_str().unwrap(), - ]; + let mut compile_args = vec!["compile", project_path.to_str().unwrap()]; // Use isolated build directory compile_args.push("--build-dir"); @@ -164,7 +158,7 @@ fn run_test_case(name: &str) { } // Compile the project using rheo CLI logic - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args(&compile_args) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() @@ -286,12 +280,8 @@ fn test_pdf_merge() { let build_dir = test_store.join("build"); // Compile with PDF merge - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--pdf", @@ -378,8 +368,8 @@ Content here. .expect("Failed to write chapter1.typ"); // Try to compile - should fail or warn - let output = std::process::Command::new("cargo") - .args(["run", "--", "compile", test_dir.to_str().unwrap(), "--pdf"]) + let output = rheo_cli_command() + .args(["compile", test_dir.to_str().unwrap(), "--pdf"]) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() .expect("Failed to run rheo compile"); @@ -443,8 +433,8 @@ Content from dir2. .expect("Failed to write dir2/chapter.typ"); // Try to compile - should fail with duplicate label error - let output = std::process::Command::new("cargo") - .args(["run", "--", "compile", test_dir.to_str().unwrap(), "--pdf"]) + let output = rheo_cli_command() + .args(["compile", test_dir.to_str().unwrap(), "--pdf"]) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() .expect("Failed to run rheo compile"); @@ -474,15 +464,8 @@ fn test_html_css_link_injection() { let project_path = test_case.project_path(); // Clean and compile - let clean_output = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "clean", - project_path.to_str().unwrap(), - ]) + let clean_output = rheo_cli_command() + .args(["clean", project_path.to_str().unwrap()]) .output() .expect("Failed to run rheo clean"); @@ -493,16 +476,8 @@ fn test_html_css_link_injection() { ); } - let output = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "compile", - project_path.to_str().unwrap(), - "--html", - ]) + let output = rheo_cli_command() + .args(["compile", project_path.to_str().unwrap(), "--html"]) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() .expect("Failed to run rheo compile"); @@ -563,8 +538,8 @@ fn test_html_css_link_injection() { ); // Clean up - let clean_output = std::process::Command::new("cargo") - .args(["run", "--", "clean", project_path.to_str().unwrap()]) + let clean_output = rheo_cli_command() + .args(["clean", project_path.to_str().unwrap()]) .output() .expect("Failed to run rheo clean"); @@ -583,28 +558,13 @@ fn test_warning_formatting() { let test_dir = PathBuf::from("../../examples/blog_post"); // Clean first - let _ = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "clean", - test_dir.to_str().unwrap(), - ]) + let _ = rheo_cli_command() + .args(["clean", test_dir.to_str().unwrap()]) .output(); // Compile - should succeed with warnings - let output = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "compile", - test_dir.to_str().unwrap(), - "--pdf", - ]) + let output = rheo_cli_command() + .args(["compile", test_dir.to_str().unwrap(), "--pdf"]) .env("TYPST_IGNORE_SYSTEM_FONTS", "1") .output() .expect("Failed to run rheo compile"); @@ -630,15 +590,8 @@ fn test_warning_formatting() { ); // Clean up - let _ = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "clean", - test_dir.to_str().unwrap(), - ]) + let _ = rheo_cli_command() + .args(["clean", test_dir.to_str().unwrap()]) .output(); } @@ -676,12 +629,8 @@ fn test_asset_patterns() { let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -755,12 +704,8 @@ fn test_asset_patterns_multiple_blocks() { let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -822,12 +767,8 @@ fn test_asset_patterns_glob_recursive() { let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -902,12 +843,8 @@ fn test_asset_patterns_dest_preserves_structure() { let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -973,12 +910,8 @@ fn test_asset_dest_subdirectory() { .unwrap(); let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1034,15 +967,8 @@ fn test_rheo_init_and_compile() { } // Run `rheo init` - let init_output = std::process::Command::new("cargo") - .args([ - "run", - "-p", - "rheo", - "--", - "init", - test_dir.to_str().unwrap(), - ]) + let init_output = rheo_cli_command() + .args(["init", test_dir.to_str().unwrap()]) .output() .expect("Failed to run rheo init"); @@ -1067,12 +993,8 @@ fn test_rheo_init_and_compile() { // Compile the initialized project let build_dir = test_dir.join("build"); - let compile_output = std::process::Command::new("cargo") + let compile_output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", test_dir.to_str().unwrap(), "--build-dir", @@ -1129,12 +1051,8 @@ fn test_asset_path_override() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1203,12 +1121,8 @@ fn test_asset_path_override_subdirectory() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1270,12 +1184,8 @@ fn test_asset_multiple_blocks_inject_all() { .unwrap(); let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1342,12 +1252,8 @@ fn test_merged_imports_missing_file() { let build_dir = project_path.join("build"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--pdf", @@ -1419,12 +1325,8 @@ fn test_atom_feed_and_rheo_vars() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1531,12 +1433,8 @@ fn test_atom_feed_author_configurable() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1600,12 +1498,8 @@ fn test_atom_feed_title_configurable() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1676,12 +1570,8 @@ fn test_atom_feed_title_spine_fallback() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1749,12 +1639,8 @@ fn test_atom_feed_with_content_dir() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html", @@ -1816,12 +1702,8 @@ fn test_rheo_var_non_string_error() { ) .expect("Failed to write rheo.toml"); - let output = std::process::Command::new("cargo") + let output = rheo_cli_command() .args([ - "run", - "-p", - "rheo", - "--", "compile", project_path.to_str().unwrap(), "--html",