mirror of
https://github.com/openai/codex.git
synced 2026-05-05 05:42:33 +03:00
Refactor config loading to use filesystem abstraction (#18209)
Initial pass propagating FileSystem through config loading.
This commit is contained in:
@@ -4,6 +4,7 @@ use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use codex_exec_server::ExecutorFileSystem;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use futures::future::join_all;
|
||||
use schemars::JsonSchema;
|
||||
@@ -618,30 +619,38 @@ async fn diff_against_sha(cwd: &Path, sha: &GitSha) -> Option<String> {
|
||||
/// `[get_git_repo_root]`, but resolves to the root of the main
|
||||
/// repository. Handles worktrees via filesystem inspection without invoking
|
||||
/// the `git` executable.
|
||||
pub async fn resolve_root_git_project_for_trust(cwd: &Path) -> Option<PathBuf> {
|
||||
let base = if cwd.is_dir() { cwd } else { cwd.parent()? };
|
||||
let (repo_root, dot_git) = find_ancestor_git_entry(base)?;
|
||||
if dot_git.is_dir() {
|
||||
return Some(canonicalize_or_raw(repo_root));
|
||||
pub async fn resolve_root_git_project_for_trust(
|
||||
fs: &dyn ExecutorFileSystem,
|
||||
cwd: &AbsolutePathBuf,
|
||||
) -> Option<AbsolutePathBuf> {
|
||||
let base = match fs.get_metadata(cwd, /*sandbox*/ None).await {
|
||||
Ok(metadata) if metadata.is_directory => cwd.clone(),
|
||||
_ => cwd.parent()?,
|
||||
};
|
||||
let (repo_root, dot_git) = find_ancestor_git_entry_with_fs(fs, &base).await?;
|
||||
if fs
|
||||
.get_metadata(&dot_git, /*sandbox*/ None)
|
||||
.await
|
||||
.ok()?
|
||||
.is_directory
|
||||
{
|
||||
return Some(repo_root);
|
||||
}
|
||||
|
||||
let git_dir_s = std::fs::read_to_string(&dot_git).ok()?;
|
||||
let git_dir_s = fs.read_file_text(&dot_git, /*sandbox*/ None).await.ok()?;
|
||||
let git_dir_rel = git_dir_s.trim().strip_prefix("gitdir:")?.trim();
|
||||
if git_dir_rel.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let git_dir_path = canonicalize_or_raw(
|
||||
AbsolutePathBuf::resolve_path_against_base(git_dir_rel, &repo_root).into_path_buf(),
|
||||
);
|
||||
let git_dir_path = AbsolutePathBuf::resolve_path_against_base(git_dir_rel, repo_root.as_path());
|
||||
let worktrees_dir = git_dir_path.parent()?;
|
||||
if worktrees_dir.file_name() != Some(OsStr::new("worktrees")) {
|
||||
if worktrees_dir.as_path().file_name() != Some(OsStr::new("worktrees")) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let common_dir = worktrees_dir.parent()?;
|
||||
let main_repo_root = common_dir.parent()?;
|
||||
Some(canonicalize_or_raw(main_repo_root.to_path_buf()))
|
||||
common_dir.parent()
|
||||
}
|
||||
|
||||
fn find_ancestor_git_entry(base_dir: &Path) -> Option<(PathBuf, PathBuf)> {
|
||||
@@ -663,8 +672,17 @@ fn find_ancestor_git_entry(base_dir: &Path) -> Option<(PathBuf, PathBuf)> {
|
||||
None
|
||||
}
|
||||
|
||||
fn canonicalize_or_raw(path: PathBuf) -> PathBuf {
|
||||
std::fs::canonicalize(&path).unwrap_or(path)
|
||||
async fn find_ancestor_git_entry_with_fs(
|
||||
fs: &dyn ExecutorFileSystem,
|
||||
base_dir: &AbsolutePathBuf,
|
||||
) -> Option<(AbsolutePathBuf, AbsolutePathBuf)> {
|
||||
for dir in base_dir.ancestors() {
|
||||
let dot_git = dir.join(".git");
|
||||
if fs.get_metadata(&dot_git, /*sandbox*/ None).await.is_ok() {
|
||||
return Some((dir, dot_git));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns a list of local git branches.
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod apply;
|
||||
mod branch;
|
||||
mod errors;
|
||||
@@ -16,6 +13,8 @@ pub use apply::extract_paths_from_patch;
|
||||
pub use apply::parse_git_apply_output;
|
||||
pub use apply::stage_paths;
|
||||
pub use branch::merge_base_with_head;
|
||||
pub use codex_protocol::models::GhostCommit;
|
||||
pub use codex_protocol::protocol::GitSha;
|
||||
pub use errors::GitToolingError;
|
||||
pub use ghost_commits::CreateGhostCommitOptions;
|
||||
pub use ghost_commits::GhostSnapshotConfig;
|
||||
@@ -45,72 +44,3 @@ pub use info::local_git_branches;
|
||||
pub use info::recent_commits;
|
||||
pub use info::resolve_root_git_project_for_trust;
|
||||
pub use platform::create_symlink;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use ts_rs::TS;
|
||||
|
||||
type CommitID = String;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, TS)]
|
||||
#[serde(transparent)]
|
||||
#[ts(type = "string")]
|
||||
pub struct GitSha(pub String);
|
||||
|
||||
impl GitSha {
|
||||
pub fn new(sha: &str) -> Self {
|
||||
Self(sha.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Details of a ghost commit created from a repository state.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
|
||||
pub struct GhostCommit {
|
||||
id: CommitID,
|
||||
parent: Option<CommitID>,
|
||||
preexisting_untracked_files: Vec<PathBuf>,
|
||||
preexisting_untracked_dirs: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl GhostCommit {
|
||||
/// Create a new ghost commit wrapper from a raw commit ID and optional parent.
|
||||
pub fn new(
|
||||
id: CommitID,
|
||||
parent: Option<CommitID>,
|
||||
preexisting_untracked_files: Vec<PathBuf>,
|
||||
preexisting_untracked_dirs: Vec<PathBuf>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
parent,
|
||||
preexisting_untracked_files,
|
||||
preexisting_untracked_dirs,
|
||||
}
|
||||
}
|
||||
|
||||
/// Commit ID for the snapshot.
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
/// Parent commit ID, if the repository had a `HEAD` at creation time.
|
||||
pub fn parent(&self) -> Option<&str> {
|
||||
self.parent.as_deref()
|
||||
}
|
||||
|
||||
/// Untracked or ignored files that already existed when the snapshot was captured.
|
||||
pub fn preexisting_untracked_files(&self) -> &[PathBuf] {
|
||||
&self.preexisting_untracked_files
|
||||
}
|
||||
|
||||
/// Untracked or ignored directories that already existed when the snapshot was captured.
|
||||
pub fn preexisting_untracked_dirs(&self) -> &[PathBuf] {
|
||||
&self.preexisting_untracked_dirs
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GhostCommit {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user