Skip to content

Commit c642cc0

Browse files
committed
progress
1 parent d9e317b commit c642cc0

File tree

1 file changed

+73
-28
lines changed

1 file changed

+73
-28
lines changed

crates/pgt_workspace/src/configuration.rs

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -473,57 +473,102 @@ impl PartialConfigurationExt for PartialConfiguration {
473473
/// Normalizes a path, resolving '..' and '.' segments without requiring the path to exist
474474
fn normalize_path(path: &Path) -> PathBuf {
475475
let mut components = Vec::new();
476-
let mut has_root_or_prefix = false;
476+
let mut prefix_component = None;
477+
let mut is_absolute = false;
477478

478479
for component in path.components() {
479480
match component {
481+
std::path::Component::Prefix(prefix) => {
482+
prefix_component = Some(component);
483+
components.clear();
484+
}
485+
std::path::Component::RootDir => {
486+
is_absolute = true;
487+
components.clear();
488+
}
480489
std::path::Component::ParentDir => {
481-
if !components.is_empty()
482-
&& !matches!(components.last(), Some(c) if matches!(Path::new(c).components().next(),
483-
Some(std::path::Component::Prefix(_))))
484-
{
490+
if !components.is_empty() {
485491
components.pop();
492+
} else if !is_absolute && prefix_component.is_none() {
493+
// Only keep parent dir if we're not absolute and have no prefix
494+
components.push(component.as_os_str());
486495
}
487496
}
488-
std::path::Component::Normal(c) => components.push(c),
489-
std::path::Component::CurDir => {}
490-
c @ std::path::Component::RootDir => {
491-
has_root_or_prefix = true;
492-
components.clear();
493-
components.push(c.as_os_str());
497+
std::path::Component::Normal(c) => {
498+
components.push(c);
494499
}
495-
c @ std::path::Component::Prefix(_) => {
496-
has_root_or_prefix = true;
497-
components.clear();
498-
components.push(c.as_os_str());
500+
std::path::Component::CurDir => {
501+
// Skip current directory components
499502
}
500503
}
501504
}
502505

503-
if components.is_empty() {
504-
if has_root_or_prefix {
505-
// On Windows, this would be something like "C:\" or "\"
506-
path.ancestors()
506+
let mut result = PathBuf::new();
507+
508+
// Add prefix component (like C: on Windows)
509+
if let Some(prefix) = prefix_component {
510+
result.push(prefix.as_os_str());
511+
}
512+
513+
// Add root directory if path is absolute
514+
if is_absolute {
515+
result.push(std::path::Component::RootDir.as_os_str());
516+
}
517+
518+
// Add normalized components
519+
for component in components {
520+
result.push(component);
521+
}
522+
523+
// Handle edge cases
524+
if result.as_os_str().is_empty() {
525+
if prefix_component.is_some() || is_absolute {
526+
// This shouldn't happen with proper input, but fallback to original path's root
527+
return path
528+
.ancestors()
507529
.last()
508530
.unwrap_or(Path::new(""))
509-
.to_path_buf()
531+
.to_path_buf();
510532
} else {
511-
// Return current directory as a relative path
512-
PathBuf::from(".")
513-
}
514-
} else {
515-
let mut result = PathBuf::new();
516-
for component in components {
517-
result.push(component);
533+
return PathBuf::from(".");
518534
}
519-
result
520535
}
536+
537+
result
521538
}
522539

523540
#[cfg(test)]
524541
mod tests {
525542
use super::*;
526543

544+
#[test]
545+
fn test_normalize_path_windows_drive() {
546+
if cfg!(windows) {
547+
let path = Path::new(r"z:\workspace\test_one\..\postgrestools.jsonc");
548+
let normalized = normalize_path(path);
549+
assert_eq!(
550+
normalized,
551+
PathBuf::from(r"z:\workspace\postgrestools.jsonc")
552+
);
553+
}
554+
}
555+
556+
#[test]
557+
fn test_normalize_path_relative() {
558+
let path = Path::new("workspace/test_one/../postgrestools.jsonc");
559+
let normalized = normalize_path(path);
560+
assert_eq!(normalized, PathBuf::from("workspace/postgrestools.jsonc"));
561+
}
562+
563+
#[test]
564+
fn test_normalize_path_multiple_parent_dirs() {
565+
if cfg!(windows) {
566+
let path = Path::new(r"c:\a\b\c\..\..\d");
567+
let normalized = normalize_path(path);
568+
assert_eq!(normalized, PathBuf::from(r"c:\a\d"));
569+
}
570+
}
571+
527572
#[test]
528573
fn test_strip_jsonc_comments_line_comments() {
529574
let input = r#"{

0 commit comments

Comments
 (0)