diff --git a/src/commands/new.rs b/src/commands/new.rs index 215da06..c2c5431 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -103,11 +103,15 @@ fn cmd_new_spel( target: &Path, bootstrap_cache: &std::path::Path, ) -> DynResult<()> { - let spel_bin = find_spel_on_path().context( - "spel binary not found on PATH.\n\ - Install it first:\n \ - cargo install --git https://github.com/logos-co/spel.git --tag v0.5.0 spel", - )?; + let spel_bin = find_spel_on_path().with_context(|| { + format!( + "spel binary not found on PATH.\n\ + Install it first:\n \ + cargo install --git https://github.com/logos-co/spel.git --tag {} spel", + DEFAULT_SPEL.tag + ) + })?; + check_spel_version(&spel_bin); if cmd.lez_path.is_some() { anyhow::bail!( @@ -313,6 +317,31 @@ fn build_scaffold_config( } } +/// Warn if the installed `spel` version does not match `DEFAULT_SPEL.tag`. +/// A mismatch is non-fatal — the user may have a newer version — but silently +/// using the wrong version produces hard-to-diagnose mismatches at first +/// `lgs build idl` or `lgs setup`. +fn check_spel_version(spel_bin: &std::path::Path) { + let output = match std::process::Command::new(spel_bin) + .arg("--version") + .output() + { + Ok(o) => o, + Err(_) => return, + }; + let stdout = String::from_utf8_lossy(&output.stdout); + if !stdout.contains(DEFAULT_SPEL.tag) { + eprintln!( + "warning: installed spel version ({}) does not match the expected {} pinned by scaffold.\n\ + This may cause unexpected behaviour. Install the pinned version with:\n \ + cargo install --git https://github.com/logos-co/spel.git --tag {} spel", + stdout.trim(), + DEFAULT_SPEL.tag, + DEFAULT_SPEL.tag, + ); + } +} + /// Locate the `spel` binary by walking PATH entries. fn find_spel_on_path() -> anyhow::Result { let path_var = std::env::var_os("PATH").unwrap_or_default(); diff --git a/src/commands/run_state.rs b/src/commands/run_state.rs index 8c996c1..a07bd1a 100644 --- a/src/commands/run_state.rs +++ b/src/commands/run_state.rs @@ -86,7 +86,7 @@ pub(crate) fn compute_program_hashes(project: &Project) -> DynResult DynResult.json` produced by `build idl`). // Missing it would mean we cache a partial digest and silently // skip deploys after later ABI-only edits. Bail loudly. diff --git a/src/template/project.rs b/src/template/project.rs index c011d7c..bbe805c 100644 --- a/src/template/project.rs +++ b/src/template/project.rs @@ -137,6 +137,11 @@ pub(crate) fn available_templates() -> Vec { }) .filter(|s| !s.is_empty()) .collect(); + // `spel` is handled by delegating to `spel init` rather than an embedded + // template directory, so it does not appear in TEMPLATES_DIR. + if !names.contains(&"spel".to_string()) { + names.push("spel".to_string()); + } names.sort(); names }