mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## What changed - Export `ProjectTrustPath` and make `ProjectTrustLookup::from_paths` accept an explicit working directory and optional repository root instead of an arbitrary sequence of path pairs. - Defer repository-root canonicalization until neither working-directory key matches, avoiding unnecessary filesystem access while preserving lookup precedence. ## Testing Extend the active-project regression test to cover repository-root fallback and ensure a working-directory entry without a trust level takes precedence over a trusted root. Adapt the existing POSIX and Windows lookup tests to the new API. GitOrigin-RevId: ba5dc0df1ef9d5109933df00c055eef04434601f
109 lines
3.8 KiB
Rust
109 lines
3.8 KiB
Rust
//! Match merged project settings against ordered native path spellings.
|
|
|
|
use crate::config_toml::ConfigToml;
|
|
use crate::config_toml::ProjectConfig;
|
|
use codex_utils_path::normalize_for_path_comparison;
|
|
use codex_utils_path_uri::PathConvention;
|
|
use std::path::Path;
|
|
|
|
/// Original and executor-normalized canonical spellings of one native path.
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub struct ProjectTrustPath {
|
|
pub original: String,
|
|
pub canonical: Option<String>,
|
|
}
|
|
|
|
/// Ordered project lookup keys for one executor working directory.
|
|
///
|
|
/// Resolve this independently of configuration layers, then apply it after all
|
|
/// local and cloud projects maps have been merged. Cwd entries, including an
|
|
/// entry without a trust level, take precedence over repository-root entries.
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub struct ProjectTrustLookup {
|
|
convention: PathConvention,
|
|
keys: Vec<String>,
|
|
}
|
|
|
|
impl ProjectTrustLookup {
|
|
pub(crate) fn from_native_path(path: &Path) -> Self {
|
|
Self::from_paths(
|
|
PathConvention::native(),
|
|
ProjectTrustPath {
|
|
original: path.to_string_lossy().into_owned(),
|
|
canonical: normalize_for_path_comparison(path)
|
|
.ok()
|
|
.map(|path| path.to_string_lossy().into_owned()),
|
|
},
|
|
/*repo_root*/ None,
|
|
)
|
|
}
|
|
|
|
/// Build lookup keys for a cwd and optional repository root.
|
|
///
|
|
/// Cwd keys always take precedence over repository-root keys. Each
|
|
/// canonical spelling is tried before its original spelling; `None` uses
|
|
/// only the original. This method performs no filesystem access or path
|
|
/// resolution. Callers must supply executor-normalized canonical spellings,
|
|
/// including Windows extended-length prefixes and WSL mounted-drive folding
|
|
/// where applicable. Original spellings remain literal. Windows keys are
|
|
/// matched without ASCII case distinctions; POSIX keys remain case-sensitive.
|
|
pub fn from_paths(
|
|
convention: PathConvention,
|
|
cwd: ProjectTrustPath,
|
|
repo_root: Option<ProjectTrustPath>,
|
|
) -> Self {
|
|
let mut keys = Vec::new();
|
|
for ProjectTrustPath {
|
|
original,
|
|
canonical,
|
|
} in std::iter::once(cwd).chain(repo_root)
|
|
{
|
|
let original = normalize_lookup_key(&original, convention);
|
|
let canonical = canonical
|
|
.map(|key| normalize_lookup_key(&key, convention))
|
|
.unwrap_or_else(|| original.clone());
|
|
if canonical != original {
|
|
keys.push(canonical);
|
|
}
|
|
keys.push(original);
|
|
}
|
|
Self { convention, keys }
|
|
}
|
|
}
|
|
|
|
impl ConfigToml {
|
|
/// Select the active project from the final merged projects map.
|
|
pub fn get_active_project_for_lookup(
|
|
&self,
|
|
lookup: &ProjectTrustLookup,
|
|
) -> Option<ProjectConfig> {
|
|
let projects = self.projects.as_ref()?;
|
|
for key in &lookup.keys {
|
|
if let Some(project) = projects.get(key) {
|
|
return Some(project.clone());
|
|
}
|
|
// Preserve native exact-key preference and deterministic selection
|
|
// when multiple Windows keys differ only in ASCII case.
|
|
if let Some((_, project)) = projects
|
|
.iter()
|
|
.filter(|(candidate, _)| normalize_lookup_key(candidate, lookup.convention) == *key)
|
|
.min_by_key(|(candidate, _)| *candidate)
|
|
{
|
|
return Some(project.clone());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
}
|
|
|
|
fn normalize_lookup_key(key: &str, convention: PathConvention) -> String {
|
|
match convention {
|
|
PathConvention::Windows => key.to_ascii_lowercase(),
|
|
PathConvention::Posix => key.to_owned(),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "project_trust_tests.rs"]
|
|
mod tests;
|