feat(cli): three-way unresolved-namespace hint (#241 T3)
A project-namespaced (::) unknown type id now hints by tier: outside any project the existing "no Aura.toml was found" text stays byte-identical; inside a data-only project the hint names the missing node crate and the attach verb (aura nodes new); a loaded node crate gets no hint (the vocabulary error carries the message). refs #241
This commit is contained in:
@@ -376,18 +376,25 @@ fn gang_fault_prose(e: &CompileError) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// (#185) When an unresolved type id LOOKS project-namespaced (`::`) but no
|
||||
/// project was loaded for this invocation (`env.provenance()` is `None`),
|
||||
/// append a hint pointing at the missing `Aura.toml` — the likeliest cause is
|
||||
/// "ran outside the project directory", not "genuinely unknown std id". Bare
|
||||
/// std-vocabulary ids (no `::`) and invocations that DO have a project loaded
|
||||
/// get no hint.
|
||||
/// (#185/#241) When an unresolved type id LOOKS project-namespaced (`::`),
|
||||
/// the likeliest causes are environmental, tiered: outside any project the
|
||||
/// hint points at the missing `Aura.toml`; inside a data-only project it
|
||||
/// points at the missing node crate. Bare std ids (no `::`) and invocations
|
||||
/// with a loaded node crate get no hint (the vocabulary error carries the
|
||||
/// message).
|
||||
pub(crate) fn unresolved_namespace_hint(e: &LoadError, env: &crate::project::Env) -> Option<String> {
|
||||
match e {
|
||||
LoadError::UnknownNodeType(t) if t.contains("::") && env.provenance().is_none() => Some(
|
||||
"type id looks project-namespaced but no Aura.toml was found — run inside a project directory"
|
||||
.to_string(),
|
||||
),
|
||||
LoadError::UnknownNodeType(t) if t.contains("::") => match env.provenance() {
|
||||
None => Some(
|
||||
"type id looks project-namespaced but no Aura.toml was found — run inside a project directory"
|
||||
.to_string(),
|
||||
),
|
||||
Some(p) if p.namespace.is_none() => Some(
|
||||
"type id looks project-namespaced but this project binds no node crate — attach one with `aura nodes new <name>`"
|
||||
.to_string(),
|
||||
),
|
||||
Some(_) => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,6 +365,27 @@ fn nodes_pointer_crate_resolves_and_stamps_its_namespace() {
|
||||
);
|
||||
}
|
||||
|
||||
/// #241: inside a data-only project, a project-namespaced type id gets the
|
||||
/// "binds no node crate" hint (not the outside-project "no Aura.toml" text).
|
||||
#[test]
|
||||
fn data_only_project_hints_attach_for_namespaced_ids() {
|
||||
let tmp = std::env::temp_dir().join(format!("aura-dataonly-hint-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&tmp).unwrap();
|
||||
std::fs::write(tmp.join("Aura.toml"), "").unwrap();
|
||||
let bp = tmp.join("bp.json");
|
||||
std::fs::write(&bp, r#"{"format_version":1,"blueprint":{"name":"x","nodes":[{"primitive":{"type":"nosuch::Node"}}],"edges":[],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0}],"source":"F64"}],"output":[{"node":0,"field":0,"name":"bias"}]}}"#).unwrap();
|
||||
let out = std::process::Command::new(env!("CARGO_BIN_EXE_aura"))
|
||||
.args(["run", bp.to_str().unwrap()])
|
||||
.current_dir(&tmp)
|
||||
.output()
|
||||
.expect("spawn aura");
|
||||
assert_eq!(out.status.code(), Some(2), "stderr: {}", String::from_utf8_lossy(&out.stderr));
|
||||
let err = String::from_utf8_lossy(&out.stderr);
|
||||
assert!(err.contains("binds no node crate"), "{err}");
|
||||
assert!(err.contains("aura nodes new"), "{err}");
|
||||
std::fs::remove_dir_all(&tmp).ok();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_artifact_refuses_with_build_hint() {
|
||||
// A minimal never-built project: valid cargo metadata, no dylib on disk.
|
||||
|
||||
Reference in New Issue
Block a user