Skip to content

Commit 72d5236

Browse files
committed
cargo-rail: fixing the Windows path issues
1 parent 527eebc commit 72d5236

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/config.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,15 +368,61 @@ pub enum WorkspaceMode {
368368

369369
impl RailConfig {
370370
/// Find config file in search order: rail.toml, .rail.toml, .cargo/rail.toml, .config/rail.toml
371+
///
372+
/// On Windows, this handles path canonicalization issues (UNC paths, 8.3 short names)
373+
/// by checking both the original path and its parent's canonicalization.
371374
pub fn find_config_path(path: &Path) -> Option<PathBuf> {
372-
let candidates = vec![
375+
let candidates = [
373376
path.join("rail.toml"),
374377
path.join(".rail.toml"),
375378
path.join(".cargo").join("rail.toml"),
376379
path.join(".config").join("rail.toml"),
377380
];
378381

379-
candidates.into_iter().find(|p| p.exists())
382+
// First, try the candidates as-is
383+
if let Some(found) = candidates.iter().find(|p| p.exists()) {
384+
return Some(found.to_path_buf());
385+
}
386+
387+
// On Windows, if path is canonicalized (e.g., from cargo metadata),
388+
// we may need to check using the original non-canonicalized path.
389+
// We do this by checking if a de-canonicalized version exists.
390+
#[cfg(target_os = "windows")]
391+
{
392+
// Try to find the config by reconstructing paths from the parent
393+
// This handles cases where:
394+
// 1. cargo metadata returns \\?\C:\Users\RUNNER~1\AppData\Local\Temp\...
395+
// 2. But test wrote file to C:\Users\RUNNER~1\AppData\Local\Temp\...
396+
// Or the short name (8.3) vs long name issue
397+
398+
// Check if we can read the directory to find config files
399+
if let Ok(entries) = std::fs::read_dir(path) {
400+
for entry in entries.flatten() {
401+
let file_name = entry.file_name();
402+
let file_name_str = file_name.to_string_lossy();
403+
404+
// Check if this entry matches any of our config file names
405+
if file_name_str == "rail.toml" || file_name_str == ".rail.toml" {
406+
return Some(entry.path());
407+
}
408+
}
409+
}
410+
411+
// Also check subdirectories .cargo and .config
412+
for subdir in &[".cargo", ".config"] {
413+
let subdir_path = path.join(subdir);
414+
if let Ok(entries) = std::fs::read_dir(&subdir_path) {
415+
for entry in entries.flatten() {
416+
let file_name = entry.file_name();
417+
if file_name.to_string_lossy() == "rail.toml" {
418+
return Some(entry.path());
419+
}
420+
}
421+
}
422+
}
423+
}
424+
425+
None
380426
}
381427

382428
/// Load config from rail.toml (searches multiple locations)

src/workspace/context.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,12 @@ impl WorkspaceContext {
114114
///
115115
/// Use this in commands that require rail.toml configuration.
116116
pub fn require_config(&self) -> RailResult<&Arc<RailConfig>> {
117-
self
118-
.config
119-
.as_ref()
120-
.ok_or_else(|| crate::error::RailError::message("No rail.toml found. Run 'cargo rail init' to create one."))
117+
self.config.as_ref().ok_or_else(|| {
118+
crate::error::RailError::message(format!(
119+
"No rail.toml found in: {}\nSearched: rail.toml, .rail.toml, .cargo/rail.toml, .config/rail.toml\nRun 'cargo rail init' to create one.",
120+
self.workspace_root.display()
121+
))
122+
})
121123
}
122124

123125
/// Get rail config (convenience wrapper for require_config)

0 commit comments

Comments
 (0)