Skip to content

Commit 9401e5f

Browse files
committed
fix: tolerate windows trust path aliases
Co-authored-by: Codex noreply@openai.com
1 parent 409c08f commit 9401e5f

File tree

2 files changed

+89
-55
lines changed

2 files changed

+89
-55
lines changed

codex-rs/core/src/config/mod.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,48 +1691,49 @@ impl ConfigToml {
16911691
/// Resolves the cwd to an existing project, or returns None if ConfigToml
16921692
/// does not contain a project corresponding to cwd or a git repo for cwd
16931693
pub fn get_active_project(&self, resolved_cwd: &Path) -> Option<ProjectConfig> {
1694-
let projects = self
1695-
.projects
1696-
.clone()
1697-
.unwrap_or_default()
1698-
.into_iter()
1699-
.map(|(key, project_config)| {
1700-
let key_path = Path::new(&key);
1701-
let normalized_key = if key_path.is_absolute() {
1702-
Self::normalized_project_lookup_key(key_path)
1703-
} else {
1704-
Self::normalize_project_lookup_key_string(key)
1705-
};
1706-
(normalized_key, project_config)
1707-
})
1708-
.collect::<HashMap<_, _>>();
1709-
1710-
let normalized_cwd = Self::normalized_project_lookup_key(resolved_cwd);
1694+
let mut projects = HashMap::new();
1695+
for (key, project_config) in self.projects.clone().unwrap_or_default() {
1696+
for normalized_key in Self::normalized_project_lookup_keys(Path::new(&key)) {
1697+
projects.insert(normalized_key, project_config.clone());
1698+
}
1699+
}
17111700

1712-
if let Some(project_config) = projects.get(&normalized_cwd) {
1713-
return Some(project_config.clone());
1701+
for normalized_cwd in Self::normalized_project_lookup_keys(resolved_cwd) {
1702+
if let Some(project_config) = projects.get(&normalized_cwd) {
1703+
return Some(project_config.clone());
1704+
}
17141705
}
17151706

17161707
// If cwd lives inside a git repo/worktree, check whether the root git project
17171708
// (the primary repository working directory) is trusted. This lets
17181709
// worktrees inherit trust from the main project.
17191710
if let Some(repo_root) = resolve_root_git_project_for_trust(resolved_cwd)
1720-
&& let Some(project_config_for_root) =
1721-
projects.get(&Self::normalized_project_lookup_key(&repo_root))
17221711
{
1723-
return Some(project_config_for_root.clone());
1712+
for normalized_repo_root in Self::normalized_project_lookup_keys(&repo_root) {
1713+
if let Some(project_config_for_root) = projects.get(&normalized_repo_root) {
1714+
return Some(project_config_for_root.clone());
1715+
}
1716+
}
17241717
}
17251718

17261719
None
17271720
}
17281721

1729-
fn normalized_project_lookup_key(path: &Path) -> String {
1730-
Self::normalize_project_lookup_key_string(
1722+
fn normalized_project_lookup_keys(path: &Path) -> Vec<String> {
1723+
let normalized_path = Self::normalize_project_lookup_key_string(
1724+
path.to_string_lossy().to_string(),
1725+
);
1726+
let normalized_canonical_path = Self::normalize_project_lookup_key_string(
17311727
normalize_path(path)
17321728
.unwrap_or_else(|_| path.to_path_buf())
17331729
.to_string_lossy()
17341730
.to_string(),
1735-
)
1731+
);
1732+
if normalized_path == normalized_canonical_path {
1733+
vec![normalized_path]
1734+
} else {
1735+
vec![normalized_path, normalized_canonical_path]
1736+
}
17361737
}
17371738

17381739
fn normalize_project_lookup_key_string(key: String) -> String {

codex-rs/core/src/config_loader/mod.rs

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,9 @@ async fn load_requirements_from_legacy_scheme(
532532
struct ProjectTrustContext {
533533
project_root: AbsolutePathBuf,
534534
project_root_key: String,
535+
project_root_lookup_keys: Vec<String>,
535536
repo_root_key: Option<String>,
537+
repo_root_lookup_keys: Option<Vec<String>>,
536538
projects_trust: std::collections::HashMap<String, TrustLevel>,
537539
user_config_file: AbsolutePathBuf,
538540
}
@@ -555,28 +557,33 @@ impl ProjectTrustDecision {
555557

556558
impl ProjectTrustContext {
557559
fn decision_for_dir(&self, dir: &AbsolutePathBuf) -> ProjectTrustDecision {
558-
let dir_key = normalized_project_trust_key(dir.as_path());
559-
if let Some(trust_level) = self.projects_trust.get(&dir_key).copied() {
560-
return ProjectTrustDecision {
561-
trust_level: Some(trust_level),
562-
trust_key: dir_key,
563-
};
560+
for dir_key in normalized_project_trust_keys(dir.as_path()) {
561+
if let Some(trust_level) = self.projects_trust.get(&dir_key).copied() {
562+
return ProjectTrustDecision {
563+
trust_level: Some(trust_level),
564+
trust_key: dir_key,
565+
};
566+
}
564567
}
565568

566-
if let Some(trust_level) = self.projects_trust.get(&self.project_root_key).copied() {
567-
return ProjectTrustDecision {
568-
trust_level: Some(trust_level),
569-
trust_key: self.project_root_key.clone(),
570-
};
569+
for project_root_key in &self.project_root_lookup_keys {
570+
if let Some(trust_level) = self.projects_trust.get(project_root_key).copied() {
571+
return ProjectTrustDecision {
572+
trust_level: Some(trust_level),
573+
trust_key: project_root_key.clone(),
574+
};
575+
}
571576
}
572577

573-
if let Some(repo_root_key) = self.repo_root_key.as_ref()
574-
&& let Some(trust_level) = self.projects_trust.get(repo_root_key).copied()
575-
{
576-
return ProjectTrustDecision {
577-
trust_level: Some(trust_level),
578-
trust_key: repo_root_key.clone(),
579-
};
578+
if let Some(repo_root_lookup_keys) = self.repo_root_lookup_keys.as_ref() {
579+
for repo_root_key in repo_root_lookup_keys {
580+
if let Some(trust_level) = self.projects_trust.get(repo_root_key).copied() {
581+
return ProjectTrustDecision {
582+
trust_level: Some(trust_level),
583+
trust_key: repo_root_key.clone(),
584+
};
585+
}
586+
}
580587
}
581588

582589
ProjectTrustDecision {
@@ -641,45 +648,71 @@ async fn project_trust_context(
641648
let project_root = find_project_root(cwd, project_root_markers).await?;
642649
let projects = project_trust_config.projects.unwrap_or_default();
643650

644-
let project_root_key = normalized_project_trust_key(project_root.as_path());
651+
let project_root_lookup_keys = normalized_project_trust_keys(project_root.as_path());
652+
let project_root_key = project_root_lookup_keys
653+
.first()
654+
.cloned()
655+
.unwrap_or_else(|| normalized_project_trust_key(project_root.as_path()));
645656
let repo_root = resolve_root_git_project_for_trust(cwd.as_path());
646-
let repo_root_key = repo_root
657+
let repo_root_lookup_keys = repo_root
647658
.as_ref()
648-
.map(|root| normalized_project_trust_key(root));
659+
.map(|root| normalized_project_trust_keys(root));
660+
let repo_root_key = repo_root_lookup_keys
661+
.as_ref()
662+
.and_then(|keys| keys.first().cloned());
649663

650664
let projects_trust = projects
651665
.into_iter()
652-
.filter_map(|(key, project)| {
653-
project
654-
.trust_level
655-
.map(|trust_level| (normalized_project_trust_key_str(&key), trust_level))
666+
.flat_map(|(key, project)| {
667+
project.trust_level.into_iter().flat_map(move |trust_level| {
668+
normalized_project_trust_key_strs(&key)
669+
.into_iter()
670+
.map(move |normalized_key| (normalized_key, trust_level))
671+
})
656672
})
657673
.collect();
658674

659675
Ok(ProjectTrustContext {
660676
project_root,
661677
project_root_key,
678+
project_root_lookup_keys,
662679
repo_root_key,
680+
repo_root_lookup_keys,
663681
projects_trust,
664682
user_config_file: user_config_file.clone(),
665683
})
666684
}
667685

668686
fn normalized_project_trust_key(path: &Path) -> String {
669-
normalize_project_trust_lookup_key(
687+
normalized_project_trust_keys(path)
688+
.into_iter()
689+
.next()
690+
.unwrap_or_else(|| normalize_project_trust_lookup_key(path.to_string_lossy().to_string()))
691+
}
692+
693+
fn normalized_project_trust_keys(path: &Path) -> Vec<String> {
694+
let normalized_path = normalize_project_trust_lookup_key(path.to_string_lossy().to_string());
695+
let normalized_canonical_path = normalize_project_trust_lookup_key(
670696
normalize_path(path)
671697
.unwrap_or_else(|_| path.to_path_buf())
672698
.to_string_lossy()
673699
.to_string(),
674-
)
700+
);
701+
if normalized_path == normalized_canonical_path {
702+
vec![normalized_path]
703+
} else {
704+
vec![normalized_path, normalized_canonical_path]
705+
}
675706
}
676707

677-
fn normalized_project_trust_key_str(path: &str) -> String {
708+
fn normalized_project_trust_key_strs(path: &str) -> Vec<String> {
678709
let path = Path::new(path);
679710
if path.is_absolute() {
680-
normalized_project_trust_key(path)
711+
normalized_project_trust_keys(path)
681712
} else {
682-
normalize_project_trust_lookup_key(path.to_string_lossy().to_string())
713+
vec![normalize_project_trust_lookup_key(
714+
path.to_string_lossy().to_string(),
715+
)]
683716
}
684717
}
685718

0 commit comments

Comments
 (0)