Files
codex/prs/bolinfest/study/PR-1602-study.md
2025-09-02 15:17:45 -07:00

131 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**PR #1602 Review Takeaways**
**DOs**
- **Investigate Before Parsing Changes:** Reproduce the Windows quoting issue, document root cause, and add a regression test before modifying CLI `-c key=value` parsing.
```rust
// Build a TOMLsafe override; quotes + backslashes escaped.
let path = r"C:\logs\sessions\a.jsonl";
let arg = format!("-c experimental_resume={:?}", path);
// -> -c experimental_resume="C:\\logs\\sessions\\a.jsonl"
// Optional normalization approach (test both behaviors):
let arg_norm = format!(r#"-c experimental_resume="{}""#, path.replace('\\', "/"));
```
- **Decide Resume vs New Early (Keep IDs Immutable):** Determine the session to use up front and pass it through; avoid mutating IDs later.
```rust
use uuid::Uuid;
async fn choose_session_id(resume_path: Option<&std::path::Path>) -> std::io::Result<Uuid> {
if let Some(p) = resume_path {
let (_rec, saved) = RolloutRecorder::resume(p).await?;
Ok(saved.session_id)
} else {
Ok(Uuid::new_v4())
}
}
// Later:
let session_id = choose_session_id(config.experimental_resume.as_deref()).await?;
```
- **Propagate I/O Errors From Background Writers:** Have the writer return `io::Result<()>`, store the `JoinHandle`, and surface failures (e.g., in tests or shutdown).
```rust
async fn rollout_writer(
mut file: tokio::fs::File,
mut rx: tokio::sync::mpsc::Receiver<RolloutCmd>,
meta: Option<SessionMeta>,
) -> std::io::Result<()> {
if let Some(m) = meta {
file.write_all(serde_json::to_string(&m)?.as_bytes()).await?;
file.write_all(b"\n").await?;
}
while let Some(cmd) = rx.recv().await {
// ... perform writes with `?`
}
file.flush().await?;
Ok(())
}
// Keep the handle so callers can `await` or inspect errors.
let handle: tokio::task::JoinHandle<std::io::Result<()>> =
tokio::spawn(rollout_writer(file, rx, Some(meta)));
```
- **Use `Command::cargo_bin` In Tests:** Prefer compiled binary execution over `cargo run` for speed and determinism.
```rust
use assert_cmd::cargo::CommandCargoExt;
use std::process::Command;
let mut cmd = Command::cargo_bin("codex-cli").unwrap();
cmd.arg("exec")
.arg("--skip-git-repo-check")
.arg("-c")
.arg(format!("experimental_resume={:?}", path));
cmd.assert().success();
```
- **Add Regression Tests For CLI Overrides:** Cover quoting/escaping on Windows paths and fallback behavior so future changes dont regress.
```rust
#[test]
fn windows_path_is_preserved_in_override() {
let win = r"C:\Users\me\sessions\run.jsonl";
let arg = format!("-c experimental_resume={:?}", win);
assert!(arg.contains(r#""C:\\Users\\me\\sessions\\run.jsonl""#));
}
```
- **Document New Config Clearly:** If adding `experimental_resume`, specify expected format (absolute path, JSONL) and precedence.
```rust
/// Experimental: absolute path to a `.jsonl` rollout to resume.
/// Example: `-c experimental_resume="/home/user/.codex/sessions/2025/07/19/run.jsonl"`
pub experimental_resume: Option<std::path::PathBuf>,
```
**DONTs**
- **Dont Mutate `session_id` MidFlow:** Avoid patterns that change identity after configuration.
```rust
// Bad: mutating the ID later in the loop.
let mut session_id = Uuid::new_v4();
// ...
if let Some(saved) = maybe_resume_id { session_id = saved; }
// Good: compute once, immutably (see DOs).
```
- **Dont Ignore I/O Errors:** Avoid `let _ = ...` in the writer; it hides failures that make rollouts incomplete or corrupt.
```rust
// Bad:
let _ = file.write_all(json.as_bytes()).await;
// Good:
file.write_all(json.as_bytes()).await?;
```
- **Dont Land Parsing Changes Without Tests:** Trimming quotes on parse failure can mask real bugs and create platformspecific surprises.
```rust
// Bad: silently “fixes” input and hides root cause.
let trimmed = value_str.trim().trim_matches(|c| c == '"' || c == '\'');
// Good: reproduce, understand, then fix with a tested approach (see DOs).
```
- **Dont Use `cargo run` In Integration Tests:** Its slower, noisier, and more brittle than invoking the built binary.
```rust
// Bad:
let mut cmd = std::process::Command::new("cargo");
cmd.args(["run", "-p", "codex-cli", "--", "exec"]);
// Good: use Command::cargo_bin (see DOs).
```
- **Dont HandRoll Fragile `-c` Strings:** Avoid manual quoting that breaks on Windows; use `{:?}` or normalize.
```rust
// Bad: breaks when `path` contains backslashes.
let arg = format!("-c experimental_resume=\"{path}\"");
// Good:
let arg = format!("-c experimental_resume={:?}", path);
// or normalize:
let arg = format!(r#"-c experimental_resume="{}""#, path.replace('\\', "/"));
```