mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
94 lines
3.8 KiB
Rust
94 lines
3.8 KiB
Rust
use codex_git::merge_base_with_head;
|
|
use codex_protocol::protocol::ReviewRequest;
|
|
use codex_protocol::protocol::ReviewTarget;
|
|
use std::path::Path;
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct ResolvedReviewRequest {
|
|
pub target: ReviewTarget,
|
|
pub prompt: String,
|
|
pub user_facing_hint: String,
|
|
}
|
|
|
|
const UNCOMMITTED_PROMPT: &str = "Review the current code changes (staged, unstaged, and untracked files) and provide prioritized findings.";
|
|
|
|
const BASE_BRANCH_PROMPT_BACKUP: &str = "Review the code changes against the base branch '{branch}'. Start by finding the merge diff between the current branch and {branch}'s upstream e.g. (`git merge-base HEAD \"$(git rev-parse --abbrev-ref \"{branch}@{upstream}\")\"`), then run `git diff` against that SHA to see what changes we would merge into the {branch} branch. Provide prioritized, actionable findings.";
|
|
const BASE_BRANCH_PROMPT: &str = "Review the code changes against the base branch '{baseBranch}'. The merge base commit for this comparison is {mergeBaseSha}. Run `git diff {mergeBaseSha}` to inspect the changes relative to {baseBranch}. Provide prioritized, actionable findings.";
|
|
|
|
const COMMIT_PROMPT_WITH_TITLE: &str = "Review the code changes introduced by commit {sha} (\"{title}\"). Provide prioritized, actionable findings.";
|
|
const COMMIT_PROMPT: &str =
|
|
"Review the code changes introduced by commit {sha}. Provide prioritized, actionable findings.";
|
|
|
|
pub fn resolve_review_request(
|
|
request: ReviewRequest,
|
|
cwd: &Path,
|
|
) -> anyhow::Result<ResolvedReviewRequest> {
|
|
let target = request.target;
|
|
let prompt = review_prompt(&target, cwd)?;
|
|
let user_facing_hint = request
|
|
.user_facing_hint
|
|
.unwrap_or_else(|| user_facing_hint(&target));
|
|
|
|
Ok(ResolvedReviewRequest {
|
|
target,
|
|
prompt,
|
|
user_facing_hint,
|
|
})
|
|
}
|
|
|
|
pub fn review_prompt(target: &ReviewTarget, cwd: &Path) -> anyhow::Result<String> {
|
|
match target {
|
|
ReviewTarget::UncommittedChanges => Ok(UNCOMMITTED_PROMPT.to_string()),
|
|
ReviewTarget::BaseBranch { branch } => {
|
|
if let Some(commit) = merge_base_with_head(cwd, branch)? {
|
|
Ok(BASE_BRANCH_PROMPT
|
|
.replace("{baseBranch}", branch)
|
|
.replace("{mergeBaseSha}", &commit))
|
|
} else {
|
|
Ok(BASE_BRANCH_PROMPT_BACKUP.replace("{branch}", branch))
|
|
}
|
|
}
|
|
ReviewTarget::Commit { sha, title } => {
|
|
if let Some(title) = title {
|
|
Ok(COMMIT_PROMPT_WITH_TITLE
|
|
.replace("{sha}", sha)
|
|
.replace("{title}", title))
|
|
} else {
|
|
Ok(COMMIT_PROMPT.replace("{sha}", sha))
|
|
}
|
|
}
|
|
ReviewTarget::Custom { instructions } => {
|
|
let prompt = instructions.trim();
|
|
if prompt.is_empty() {
|
|
anyhow::bail!("Review prompt cannot be empty");
|
|
}
|
|
Ok(prompt.to_string())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn user_facing_hint(target: &ReviewTarget) -> String {
|
|
match target {
|
|
ReviewTarget::UncommittedChanges => "current changes".to_string(),
|
|
ReviewTarget::BaseBranch { branch } => format!("changes against '{branch}'"),
|
|
ReviewTarget::Commit { sha, title } => {
|
|
let short_sha: String = sha.chars().take(7).collect();
|
|
if let Some(title) = title {
|
|
format!("commit {short_sha}: {title}")
|
|
} else {
|
|
format!("commit {short_sha}")
|
|
}
|
|
}
|
|
ReviewTarget::Custom { instructions } => instructions.trim().to_string(),
|
|
}
|
|
}
|
|
|
|
impl From<ResolvedReviewRequest> for ReviewRequest {
|
|
fn from(resolved: ResolvedReviewRequest) -> Self {
|
|
ReviewRequest {
|
|
target: resolved.target,
|
|
user_facing_hint: Some(resolved.user_facing_hint),
|
|
}
|
|
}
|
|
}
|