From f6920a87ad2d03fe350a39b4c66dd48630fc559d Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 23 Mar 2026 18:28:14 +0000 Subject: [PATCH] storkit: merge 375_bug_default_project_toml_contains_rust_specific_setup_commands_for_non_rust_projects --- server/src/io/fs.rs | 85 +++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/server/src/io/fs.rs b/server/src/io/fs.rs index 1d78da4..b55d237 100644 --- a/server/src/io/fs.rs +++ b/server/src/io/fs.rs @@ -184,31 +184,11 @@ pub fn detect_components_toml(root: &Path) -> String { } if sections.is_empty() { - // No tech stack markers detected — emit two example components so that - // the scaffold is immediately usable and agents can see the expected - // format. The ONBOARDING_PROMPT instructs the chat agent to inspect - // the project and replace these placeholders with real definitions. + // No tech stack markers detected — emit a single generic component + // with an empty setup list. The ONBOARDING_PROMPT instructs the chat + // agent to inspect the project and replace this with real definitions. sections.push( - "# EXAMPLE: Replace with your actual backend component.\n\ - # Common patterns: \"cargo check\" (Rust), \"go build ./...\" (Go),\n\ - # \"python -m pytest\" (Python), \"mvn verify\" (Java)\n\ - [[component]]\n\ - name = \"backend\"\n\ - path = \".\"\n\ - setup = [\"cargo check\"]\n\ - teardown = []\n" - .to_string(), - ); - sections.push( - "# EXAMPLE: Replace with your actual frontend component.\n\ - # Common patterns: \"pnpm install\" (pnpm), \"npm install\" (npm),\n\ - # \"yarn\" (Yarn), \"bun install\" (Bun)\n\ - [[component]]\n\ - name = \"frontend\"\n\ - path = \".\"\n\ - setup = [\"pnpm install\"]\n\ - teardown = []\n" - .to_string(), + "[[component]]\nname = \"app\"\npath = \".\"\nsetup = []\n".to_string(), ); } @@ -1576,10 +1556,19 @@ mod tests { toml.contains("[[component]]"), "should always emit at least one component" ); - // The fallback should include example backend and frontend entries + // Fallback should use a generic app component with empty setup assert!( - toml.contains("name = \"backend\"") || toml.contains("name = \"frontend\""), - "fallback should include example component entries" + toml.contains("name = \"app\""), + "fallback should use generic 'app' component name" + ); + assert!( + toml.contains("setup = []"), + "fallback should have empty setup list" + ); + // Must not contain Rust-specific commands in a non-Rust project + assert!( + !toml.contains("cargo"), + "fallback must not contain Rust-specific commands" ); } @@ -1666,6 +1655,38 @@ mod tests { assert!(toml.contains("setup = [\"bundle install\"]")); } + // --- Bug 375: no Rust-specific commands for non-Rust projects --- + + #[test] + fn no_rust_commands_in_go_project() { + let dir = tempdir().unwrap(); + fs::write(dir.path().join("go.mod"), "module example.com/app\n").unwrap(); + + let toml = detect_components_toml(dir.path()); + assert!(!toml.contains("cargo"), "go project must not contain cargo commands"); + assert!(toml.contains("go build"), "go project must use Go tooling"); + } + + #[test] + fn no_rust_commands_in_node_project() { + let dir = tempdir().unwrap(); + fs::write(dir.path().join("package.json"), "{}").unwrap(); + + let toml = detect_components_toml(dir.path()); + assert!(!toml.contains("cargo"), "node project must not contain cargo commands"); + assert!(toml.contains("npm install"), "node project must use npm tooling"); + } + + #[test] + fn no_rust_commands_when_no_stack_detected() { + let dir = tempdir().unwrap(); + + let toml = detect_components_toml(dir.path()); + assert!(!toml.contains("cargo"), "unknown stack must not contain cargo commands"); + // setup list must be empty + assert!(toml.contains("setup = []"), "unknown stack must have empty setup list"); + } + #[test] fn detect_multiple_markers_generates_multiple_components() { let dir = tempdir().unwrap(); @@ -1867,10 +1888,14 @@ mod tests { content.contains("[[component]]"), "project.toml should always have at least one component" ); - // Fallback emits example components so the scaffold is immediately usable + // Fallback uses generic app component with empty setup — no Rust-specific commands assert!( - content.contains("name = \"backend\"") || content.contains("name = \"frontend\""), - "fallback should include example component entries" + content.contains("name = \"app\""), + "fallback should use generic 'app' component name" + ); + assert!( + !content.contains("cargo"), + "fallback must not contain Rust-specific commands for non-Rust projects" ); }