Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
514 changes: 514 additions & 0 deletions crates/rustmotion-cli/src/commands/batch.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions crates/rustmotion-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod batch;
mod geometry;
mod info;
mod render;
Expand All @@ -8,6 +9,7 @@ mod validate_attrs;
mod validate_schema;
pub mod validation;

pub use batch::cmd_batch;
pub use info::cmd_info;
pub use render::{cmd_render, cmd_watch};
pub use schema::cmd_schema;
Expand Down
7 changes: 4 additions & 3 deletions crates/rustmotion-cli/src/commands/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustmotion::error::{Result, RustmotionError};
use std::path::{Path, PathBuf};

use super::geometry::{GeometryViolation, ViolationKind};
use super::validation::{self, ValidationReport, ValidationSource};
use super::validation::{self, ValidationReport, ValidationSource, VarOverrides};

pub fn cmd_validate(
input: &PathBuf,
Expand All @@ -11,8 +11,9 @@ pub fn cmd_validate(
strict_anim: bool,
strict_attrs: bool,
lenient: bool,
overrides: Option<&VarOverrides>,
) -> Result<()> {
let loaded = match validation::load(ValidationSource::File(input)) {
let loaded = match validation::load_with_vars(ValidationSource::File(input), overrides) {
Ok(l) => l,
Err(e) => {
eprintln!("Error: {}", e);
Expand Down Expand Up @@ -49,7 +50,7 @@ pub fn cmd_validate(

// Re-run checks after the fixes so the rest of the function reflects
// the on-disk state.
let reloaded = validation::load(ValidationSource::File(input))?;
let reloaded = validation::load_with_vars(ValidationSource::File(input), overrides)?;
report_out = validation::run_checks(&reloaded, strict_anim);
if strict_attrs {
report_out.promote_attr_warnings();
Expand Down
19 changes: 18 additions & 1 deletion crates/rustmotion-cli/src/commands/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustmotion::error::{Result, RustmotionError};
use rustmotion::include::{self, IncludeSource};
use rustmotion::schema::{ResolvedScenario, Scenario};
use rustmotion::variables;
use std::collections::HashMap;
use std::path::{Path, PathBuf};

use super::geometry::{validate_geometry, validate_geometry_animated, GeometryViolation};
Expand All @@ -25,6 +26,10 @@ pub enum ValidationSource<'a> {
Inline(&'a str),
}

/// Runtime variable overrides from `--props` / `--var` flags.
/// An empty map means "use defaults only".
pub type VarOverrides = HashMap<String, serde_json::Value>;

/// A scenario after parsing, variable resolution, and include resolution.
/// Keeps the raw JSON around so it can be inspected by validators (e.g. for
/// path-based auto-fixes).
Expand Down Expand Up @@ -87,6 +92,14 @@ impl ValidationReport {
/// Load + parse + apply variable defaults + resolve includes. Returns the
/// raw JSON (post-substitution) and the resolved scenario.
pub fn load(source: ValidationSource<'_>) -> Result<LoadedScenario> {
load_with_vars(source, None)
}

/// Like [`load`] but injects runtime variable overrides before substitution.
pub fn load_with_vars(
source: ValidationSource<'_>,
overrides: Option<&VarOverrides>,
) -> Result<LoadedScenario> {
let (json_str, source_path, include_source) = match source {
ValidationSource::File(path) => {
let s = std::fs::read_to_string(path).map_err(|e| RustmotionError::FileRead {
Expand Down Expand Up @@ -119,7 +132,11 @@ pub fn load(source: ValidationSource<'_>) -> Result<LoadedScenario> {
let mut json_value: serde_json::Value =
serde_json::from_str(&json_str).map_err(RustmotionError::from)?;

variables::apply_defaults(&mut json_value)?;
let label = source_path
.as_ref()
.map(|p| p.display().to_string())
.unwrap_or_else(|| "<inline>".to_string());
variables::apply_variables(&mut json_value, overrides, &label)?;

let scenario: Scenario = serde_json::from_value(json_value.clone())?;
let resolved = include::resolve_includes(scenario, &include_source)?;
Expand Down
Loading
Loading