mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
render workspace git context as xml
This commit is contained in:
@@ -1874,7 +1874,7 @@ impl Session {
|
||||
fn build_workspace_configuration(
|
||||
cwd: &Path,
|
||||
git_info: Option<&codex_protocol::protocol::GitInfo>,
|
||||
remote_urls: Option<&Vec<String>>,
|
||||
remote_urls: Option<&BTreeMap<String, String>>,
|
||||
) -> Option<WorkspaceConfiguration> {
|
||||
let latest_git_commit_hash = git_info.and_then(|info| info.commit_hash.clone());
|
||||
let associated_remote_urls = remote_urls.cloned();
|
||||
|
||||
@@ -72,7 +72,7 @@ pub(crate) struct WorkspaceConfiguration {
|
||||
pub(crate) struct WorkspaceEntry {
|
||||
pub hint: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub associated_remote_urls: Option<Vec<String>>,
|
||||
pub associated_remote_urls: Option<BTreeMap<String, String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub latest_git_commit_hash: Option<String>,
|
||||
}
|
||||
@@ -97,12 +97,31 @@ impl EnvironmentContext {
|
||||
let shell_name = self.shell.name();
|
||||
lines.push(format!(" <shell>{shell_name}</shell>"));
|
||||
|
||||
if let Some(workspace_configuration) = self.workspace_configuration
|
||||
&& let Ok(json) = serde_json::to_string_pretty(&workspace_configuration)
|
||||
{
|
||||
if let Some(workspace_configuration) = self.workspace_configuration {
|
||||
lines.push(" <workspace_configuration>".to_string());
|
||||
for line in json.lines() {
|
||||
lines.push(format!(" {line}"));
|
||||
for (path, workspace) in workspace_configuration.workspaces {
|
||||
lines.push(format!(
|
||||
" <workspace path=\"{path}\" hint=\"{}\">",
|
||||
workspace.hint
|
||||
));
|
||||
|
||||
if let Some(latest_git_commit_hash) = workspace.latest_git_commit_hash {
|
||||
lines.push(format!(
|
||||
" <latest_git_commit_hash>{latest_git_commit_hash}</latest_git_commit_hash>"
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(associated_remote_urls) = workspace.associated_remote_urls
|
||||
&& !associated_remote_urls.is_empty()
|
||||
{
|
||||
lines.push(" <associated_remote_urls>".to_string());
|
||||
for (name, url) in associated_remote_urls {
|
||||
lines.push(format!(" <remote name=\"{name}\">{url}</remote>"));
|
||||
}
|
||||
lines.push(" </associated_remote_urls>".to_string());
|
||||
}
|
||||
|
||||
lines.push(" </workspace>".to_string());
|
||||
}
|
||||
lines.push(" </workspace_configuration>".to_string());
|
||||
}
|
||||
@@ -257,9 +276,10 @@ mod tests {
|
||||
cwd.to_string_lossy().to_string(),
|
||||
WorkspaceEntry {
|
||||
hint: "repo".to_string(),
|
||||
associated_remote_urls: Some(vec![
|
||||
"origin: https://example.com/repo.git".to_string(),
|
||||
]),
|
||||
associated_remote_urls: Some(BTreeMap::from([(
|
||||
"origin".to_string(),
|
||||
"https://example.com/repo.git".to_string(),
|
||||
)])),
|
||||
latest_git_commit_hash: Some("abc123".to_string()),
|
||||
},
|
||||
);
|
||||
@@ -274,17 +294,12 @@ mod tests {
|
||||
<cwd>/repo</cwd>
|
||||
<shell>bash</shell>
|
||||
<workspace_configuration>
|
||||
{
|
||||
"workspaces": {
|
||||
"/repo": {
|
||||
"hint": "repo",
|
||||
"associated_remote_urls": [
|
||||
"origin: https://example.com/repo.git"
|
||||
],
|
||||
"latest_git_commit_hash": "abc123"
|
||||
}
|
||||
}
|
||||
}
|
||||
<workspace path="/repo" hint="repo">
|
||||
<latest_git_commit_hash>abc123</latest_git_commit_hash>
|
||||
<associated_remote_urls>
|
||||
<remote name="origin">https://example.com/repo.git</remote>
|
||||
</associated_remote_urls>
|
||||
</workspace>
|
||||
</workspace_configuration>
|
||||
</environment_context>"#;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
@@ -110,8 +110,8 @@ pub async fn collect_git_info(cwd: &Path) -> Option<GitInfo> {
|
||||
Some(git_info)
|
||||
}
|
||||
|
||||
/// Collect fetch remotes in a multi-root-friendly format: ["origin: https://..."].
|
||||
pub async fn get_git_remote_urls(cwd: &Path) -> Option<Vec<String>> {
|
||||
/// Collect fetch remotes in a multi-root-friendly format: {"origin": "https://..."}.
|
||||
pub async fn get_git_remote_urls(cwd: &Path) -> Option<BTreeMap<String, String>> {
|
||||
let is_git_repo = run_git_command_with_timeout(&["rev-parse", "--git-dir"], cwd)
|
||||
.await?
|
||||
.status
|
||||
@@ -126,21 +126,21 @@ pub async fn get_git_remote_urls(cwd: &Path) -> Option<Vec<String>> {
|
||||
}
|
||||
|
||||
let stdout = String::from_utf8(output.stdout).ok()?;
|
||||
let mut remotes = BTreeSet::new();
|
||||
let mut remotes = BTreeMap::new();
|
||||
for line in stdout.lines() {
|
||||
if !line.contains("(fetch)") {
|
||||
continue;
|
||||
}
|
||||
let mut parts = line.split_whitespace();
|
||||
if let (Some(name), Some(url)) = (parts.next(), parts.next()) {
|
||||
remotes.insert(format!("{name}: {url}"));
|
||||
remotes.insert(name.to_string(), url.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if remotes.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(remotes.into_iter().collect())
|
||||
Some(remotes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user