test(cli): RED — a fresh scaffold leaves no resolvable HEAD (#243)

aura new git-inits but never commits, so the first run stamps empty
project provenance. RED pin:
new_outside_a_work_tree_leaves_a_resolvable_head.

refs #243
This commit is contained in:
2026-07-12 18:54:11 +02:00
parent 1605205fc2
commit bb58442087
+51
View File
@@ -220,6 +220,57 @@ fn new_outside_a_work_tree_initializes_git() {
let _ = std::fs::remove_dir_all(&base); let _ = std::fs::remove_dir_all(&base);
} }
/// Property (#243): a freshly scaffolded project stamps resolvable
/// provenance from its very first run. Outside any enclosing work tree
/// `aura new` owns the scaffold's history, so it must leave the project with
/// a HEAD — `git rev-parse HEAD` resolves — and the first advertised
/// quickstart `aura run` therefore stamps a `manifest.project.commit`, rather
/// than the empty `"project":{}` that a bare `git init` with no commit yields
/// (a first manifest that is silently un-reproducible-by-commit). This is the
/// property the neighbouring loop headline can only reach today via a manual
/// `init_and_commit` on the enclosing tree.
#[test]
fn new_outside_a_work_tree_leaves_a_resolvable_head() {
let base = tmp("headprov");
let out = aura(&["new", "demo-lab"], &base);
assert!(
out.status.success(),
"aura new failed: {}",
String::from_utf8_lossy(&out.stderr)
);
let proj = base.join("demo-lab");
// The scaffold has its own repo (guarded elsewhere) AND that repo has a
// HEAD: `git rev-parse HEAD` resolves. A bare `git init` with no commit
// leaves HEAD unborn and this fails.
let head = Command::new("git")
.args(["rev-parse", "HEAD"])
.current_dir(&proj)
.output()
.expect("run git rev-parse HEAD");
assert!(
head.status.success(),
"fresh scaffold has no HEAD (`git rev-parse HEAD` failed): {}",
String::from_utf8_lossy(&head.stderr)
);
// ...so the first quickstart run stamps a commit into the manifest, not
// an empty provenance block.
let run = aura(&["run", "blueprints/signal.json"], &proj);
assert!(
run.status.success(),
"run failed: {}",
String::from_utf8_lossy(&run.stderr)
);
let v: serde_json::Value = serde_json::from_slice(&run.stdout).expect("report is JSON");
let p = &v["manifest"]["project"];
assert!(
p.get("commit").is_some(),
"first run of a fresh scaffold must stamp a commit, not empty provenance: {p}"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test] #[test]
fn new_works_inside_an_unbuilt_project_tree() { fn new_works_inside_an_unbuilt_project_tree() {
// Scaffold once, then scaffold AGAIN from inside that tree: the // Scaffold once, then scaffold AGAIN from inside that tree: the