From 93fe0758d9fe6016fc668c3e9cc1997f78ce4d8a Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 2 Nov 2026 05:15:16 +0700 Subject: [PATCH] A failed build check says where it looked, not app/ for an app edited in place An edit-in-place project's build check said "No project found in app/ yet." although its app is the project folder and there is no app/ (#174). The build check's messages now name where the app is (Workspace::app_place). --- crates/ai/src/rebuild/check.rs | 11 ++++++----- crates/ai/src/rebuild/kinds/mod.rs | 2 +- crates/ai/src/rebuild/tests.rs | 9 ++++++--- crates/engine/src/workspace.rs | 4 ++++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/crates/ai/src/rebuild/check.rs b/crates/ai/src/rebuild/check.rs index d12af70f..4179a485 100644 --- a/crates/ai/src/rebuild/check.rs +++ b/crates/ai/src/rebuild/check.rs @@ -4,7 +4,8 @@ use super::*; /// For non-website builds: run the project's build (its engine's own, for Unity, Unreal and /// Godot) and report whether it succeeded, with a note (the first error lines when it didn't). -pub(super) fn build_check(app: &Path, stack: &str, editor: Option<&Path>, stop: &CancelToken) -> (bool, String) { +/// `place` says where `app` is, for messages (`Workspace::app_place`). +pub(super) fn build_check(app: &Path, place: &str, stack: &str, editor: Option<&Path>, stop: &CancelToken) -> (bool, String) { let run = |prog: &Path, args: &[String], minutes: u64| { let s = stop.clone(); craft_anything_platform::Process::new(prog) @@ -24,7 +25,7 @@ pub(super) fn build_check(app: &Path, stack: &str, editor: Option<&Path>, stop: let result: Result<(bool, String), String> = match (engine_for(stack, app), editor) { (Some(game::Builder::Unity), Some(ed)) => { if !app.join("Assets").is_dir() { - return (false, "No Unity project found in app/ yet.".into()); + return (false, format!("No Unity project found in {place} yet.")); } let args = ["-batchmode", "-quit", "-nographics", "-projectPath", &app_s, "-executeMethod", "CraftBuild.Build", "-logFile", "-"].map(String::from); run(ed, &args, 4 * 60).map(|(ok, out)| { @@ -37,7 +38,7 @@ pub(super) fn build_check(app: &Path, stack: &str, editor: Option<&Path>, stop: } (Some(game::Builder::Unreal), Some(ed)) => { let Some(uproject) = uproject(app) else { - return (false, "No Unreal project (.uproject) found in app/ yet.".into()); + return (false, format!("No Unreal project (.uproject) found in {place} yet.")); }; // The editor is /Engine/Binaries//UnrealEditor; its packager is beside it. let Some(root) = ed.ancestors().nth(4) else { return (false, "Couldn't find Unreal's build tools.".into()) }; @@ -70,7 +71,7 @@ pub(super) fn build_check(app: &Path, stack: &str, editor: Option<&Path>, stop: } (Some(game::Builder::Godot), Some(ed)) => { if !app.join("project.godot").is_file() { - return (false, "No Godot project (project.godot) found in app/ yet.".into()); + return (false, format!("No Godot project (project.godot) found in {place} yet.")); } let import = ["--headless", "--path", &app_s, "--import"].map(String::from); let play = ["--headless", "--path", &app_s, "--quit-after", "120"].map(String::from); @@ -82,7 +83,7 @@ pub(super) fn build_check(app: &Path, stack: &str, editor: Option<&Path>, stop: } _ if app.join("Cargo.toml").is_file() => run(Path::new("cargo"), &["build".into(), "--quiet".into()], 2 * 60), _ if app.join("package.json").is_file() => run(Path::new(if cfg!(windows) { "npm.cmd" } else { "npm" }), &["run".into(), "build".into()], 2 * 60), - _ => return (false, "No project found in app/ yet.".into()), + _ => return (false, format!("No project to build found in {place} yet.")), }; match result { Ok((true, _)) => (true, "Build succeeded.".into()), diff --git a/crates/ai/src/rebuild/kinds/mod.rs b/crates/ai/src/rebuild/kinds/mod.rs index c9ca0a4d..661afeb4 100644 --- a/crates/ai/src/rebuild/kinds/mod.rs +++ b/crates/ai/src/rebuild/kinds/mod.rs @@ -234,7 +234,7 @@ impl Check for BuildCheck { CheckResult::BUILD } fn run(&self, cx: &mut CheckCx) -> Result { - let (passed, note) = build_check(&cx.ws.app_dir(), &cx.ws.manifest.stack, cx.editor(), cx.stop()); + let (passed, note) = build_check(&cx.ws.app_dir(), cx.ws.app_place(), &cx.ws.manifest.stack, cx.editor(), cx.stop()); Ok(CheckResult::new(self.id(), cx.round, passed, note)) } } diff --git a/crates/ai/src/rebuild/tests.rs b/crates/ai/src/rebuild/tests.rs index ec9109d7..7dee1628 100644 --- a/crates/ai/src/rebuild/tests.rs +++ b/crates/ai/src/rebuild/tests.rs @@ -209,9 +209,12 @@ fn engine_stacks_get_their_own_steps_checks_and_play() { let d = tempfile::tempdir().unwrap(); let stop = CancelToken::default(); - assert_eq!(build_check(d.path(), "Unity", Some(ed), &stop), (false, "No Unity project found in app/ yet.".into())); - assert_eq!(build_check(d.path(), "Godot", Some(ed), &stop), (false, "No Godot project (project.godot) found in app/ yet.".into())); - assert!(build_check(d.path(), "Unreal Engine", Some(ed), &stop).1.contains(".uproject")); + assert_eq!(build_check(d.path(), "app/", "Unity", Some(ed), &stop), (false, "No Unity project found in app/ yet.".into())); + assert_eq!(build_check(d.path(), "app/", "Godot", Some(ed), &stop), (false, "No Godot project (project.godot) found in app/ yet.".into())); + assert!(build_check(d.path(), "app/", "Unreal Engine", Some(ed), &stop).1.contains(".uproject")); + // #174: an app edited in place is said to be in the project folder, not in an app/ that isn't there. + let none = build_check(d.path(), "the project folder", "Builder's choice", None, &stop); + assert_eq!(none, (false, "No project to build found in the project folder yet.".into())); // Play: a Godot project opens in Godot; a packaged Unity build runs its own program. std::fs::write(d.path().join("project.godot"), "config_version=5").unwrap(); diff --git a/crates/engine/src/workspace.rs b/crates/engine/src/workspace.rs index f3adefea..5af5ffd3 100644 --- a/crates/engine/src/workspace.rs +++ b/crates/engine/src/workspace.rs @@ -773,6 +773,10 @@ impl Workspace { pub fn app_dir(&self) -> PathBuf { if self.manifest.app_in_root { self.root.clone() } else { self.root.join("app") } } + /// Where the app is, in words for messages: "app/", or "the project folder" (#174). + pub fn app_place(&self) -> &'static str { + if self.manifest.app_in_root { "the project folder" } else { "app/" } + } /// One of Craft Anything's own records in this project (the manifest, the feed, the inbox, /// the person's pictures…), which the builder never changes, even when the app is the