Skip to content

Commit 2ccd076

Browse files
authored
fix(cli): normalize workspace path to forward slashes for CMake templates (#3040)
* fix(cli): normalize workspace path to forward slashes for CMake templates workspace_dir() returned a raw Windows path (backslash-separated), which gets substituted verbatim into __DORA_PATH__ in the generated CMakeLists.txt for --lang c/cxx --internal-create-with-path-dependencies. CMake treats backslash as a string escape character, so cmake -B failed immediately with 'Invalid character escape' before any compiler logic ran. Normalize to forward slashes, which both CMake and Windows accept. Also box the large Cached variant of CachedResult in the coordinator (pre-existing clippy::large_enum_variant failure surfaced while running clippy locally, related to #2979). * fix: address review feedback - drop unrelated coordinator change, use OS-independent test The CachedResult::Cached boxing fix duplicated the already-open PR #3001, so it's dropped here to avoid merge conflicts (per 'don't fix unrelated warnings in PRs' convention). The regression test now asserts against a hardcoded Windows-style sample path instead of the live workspace_dir() output, since on Linux/macOS CI the real path never contains a backslash and the old assertion passed trivially without exercising the normalization logic.
1 parent 4402584 commit 2ccd076

3 files changed

Lines changed: 31 additions & 7 deletions

File tree

binaries/cli/src/template/c/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn create_cmakefile(root: PathBuf, use_path_deps: bool) -> Result<(), eyre::ErrR
8080
const CMAKEFILE: &str = include_str!("cmake-template.txt");
8181

8282
let cmake_file = if use_path_deps {
83-
CMAKEFILE.replace("__DORA_PATH__", super::workspace_dir()?)
83+
CMAKEFILE.replace("__DORA_PATH__", &super::workspace_dir()?)
8484
} else {
8585
CMAKEFILE.replace("__DORA_PATH__", "")
8686
};
@@ -136,7 +136,7 @@ fn create_node_cmakefile(
136136
let cmake_content = if use_path_deps {
137137
NODE_CMAKE
138138
.replace("___name___", name)
139-
.replace("__DORA_PATH__", super::workspace_dir()?)
139+
.replace("__DORA_PATH__", &super::workspace_dir()?)
140140
} else {
141141
NODE_CMAKE
142142
.replace("___name___", name)

binaries/cli/src/template/cxx/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn create_cmakefile(root: PathBuf, use_path_deps: bool) -> Result<(), eyre::ErrR
7979
const CMAKEFILE: &str = include_str!("cmake-template.txt");
8080

8181
let cmake_file = if use_path_deps {
82-
CMAKEFILE.replace("__DORA_PATH__", super::workspace_dir()?)
82+
CMAKEFILE.replace("__DORA_PATH__", &super::workspace_dir()?)
8383
} else {
8484
CMAKEFILE.replace("__DORA_PATH__", "")
8585
};
@@ -132,7 +132,7 @@ fn create_node_cmakefile(
132132
let cmake_content = if use_path_deps {
133133
NODE_CMAKE
134134
.replace("___name___", name)
135-
.replace("__DORA_PATH__", super::workspace_dir()?)
135+
.replace("__DORA_PATH__", &super::workspace_dir()?)
136136
} else {
137137
NODE_CMAKE
138138
.replace("___name___", name)

binaries/cli/src/template/mod.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,38 @@ mod rust;
99
/// Path to the dora workspace root (two levels above the CLI crate
1010
/// manifest), used by the C/C++ templates to reference dora via path
1111
/// dependencies when `use_path_deps` is set.
12-
fn workspace_dir() -> eyre::Result<&'static str> {
13-
Path::new(env!("CARGO_MANIFEST_DIR"))
12+
fn workspace_dir() -> eyre::Result<String> {
13+
let dir = Path::new(env!("CARGO_MANIFEST_DIR"))
1414
.parent()
1515
.context("Could not get manifest parent folder")?
1616
.parent()
1717
.context("Could not get manifest grandparent folder")?
1818
.to_str()
19-
.context("dora workspace path is not valid UTF-8")
19+
.context("dora workspace path is not valid UTF-8")?;
20+
Ok(normalize_for_cmake(dir))
21+
}
22+
23+
// CMake treats `\` as a string escape character, so a raw Windows path
24+
// (e.g. `C:\Users\...`) substituted into CMakeLists.txt fails to parse.
25+
// Both CMake and Windows accept `/`, so normalize before substitution.
26+
fn normalize_for_cmake(path: &str) -> String {
27+
path.replace('\\', "/")
28+
}
29+
30+
#[cfg(test)]
31+
mod tests {
32+
use super::*;
33+
34+
// Uses a hardcoded Windows-style sample path rather than the live
35+
// `workspace_dir()` output, since on Linux/macOS CI runners the real
36+
// path never contains a backslash and the assertion would pass
37+
// trivially without exercising the normalization at all.
38+
#[test]
39+
fn normalize_for_cmake_replaces_backslashes() {
40+
let normalized = normalize_for_cmake(r"C:\Users\example\dora");
41+
assert_eq!(normalized, "C:/Users/example/dora");
42+
assert!(!normalized.contains('\\'));
43+
}
2044
}
2145

2246
pub fn create(args: crate::CommandNew, use_path_deps: bool) -> eyre::Result<()> {

0 commit comments

Comments
 (0)