⚒️ Forge: Refactor repetitive compare_field calls in diff_config.rs#625
⚒️ Forge: Refactor repetitive compare_field calls in diff_config.rs#625madmax983 wants to merge 1 commit into
Conversation
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Code Review
This pull request refactors src/run/diff_config.rs to reduce boilerplate by introducing local closures (cmp_manifest and cmp_limits) for comparing manifest and limit fields. The reviewer suggests further simplifying the code: first, by replacing the cmp_manifest closure with a macro (cmp_manifest!) to avoid passing mutable vector references on every call; and second, by capturing the mutable vectors directly within the cmp_limits closure since they are used in a single contiguous block.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| let cmp_manifest = |group: &str, | ||
| field: &str, | ||
| compared_fields: &mut Vec<ComparedField>, | ||
| changed_fields: &mut Vec<ChangedField>, | ||
| ignored_fields: &mut Vec<IgnoredField>| { | ||
| let path = format!(".{field}"); | ||
| compare_field( | ||
| group, | ||
| &path, | ||
| &get_field_val(&baseline_manifest, &[group, field]), | ||
| &get_field_val(&candidate_manifest, &[group, field]), | ||
| compared_fields, | ||
| changed_fields, | ||
| ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| }; |
There was a problem hiding this comment.
Instead of a closure that requires passing compared_fields, changed_fields, and ignored_fields as arguments in every single call (due to borrow checker limitations across intermissions), we can define a macro cmp_manifest!. This allows direct access to the variables in the outer scope without passing them, significantly reducing boilerplate.
macro_rules! cmp_manifest {
($group:expr, $field:expr) => {
compare_field(
$group,
&format!(".{}", $field),
&get_field_val(&baseline_manifest, &[$group, $field]),
&get_field_val(&candidate_manifest, &[$group, $field]),
&mut compared_fields,
&mut changed_fields,
&mut ignored_fields,
&ignore_patterns,
);
};
}| cmp_manifest( | ||
| "harness", | ||
| ".name", | ||
| &get_field_val(&baseline_manifest, &["harness", "name"]), | ||
| &get_field_val(&candidate_manifest, &["harness", "name"]), | ||
| "name", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "harness", | ||
| ".version", | ||
| &get_field_val(&baseline_manifest, &["harness", "version"]), | ||
| &get_field_val(&candidate_manifest, &["harness", "version"]), | ||
| "version", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "harness", | ||
| ".git_sha", | ||
| &get_field_val(&baseline_manifest, &["harness", "git_sha"]), | ||
| &get_field_val(&candidate_manifest, &["harness", "git_sha"]), | ||
| "git_sha", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "harness", | ||
| ".git_dirty", | ||
| &get_field_val(&baseline_manifest, &["harness", "git_dirty"]), | ||
| &get_field_val(&candidate_manifest, &["harness", "git_dirty"]), | ||
| "git_dirty", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
|
|
||
| // 2. dataset | ||
| compare_field( | ||
| cmp_manifest( | ||
| "dataset", | ||
| ".path", | ||
| &get_field_val(&baseline_manifest, &["dataset", "path"]), | ||
| &get_field_val(&candidate_manifest, &["dataset", "path"]), | ||
| "path", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "dataset", | ||
| ".sha256", | ||
| &get_field_val(&baseline_manifest, &["dataset", "sha256"]), | ||
| &get_field_val(&candidate_manifest, &["dataset", "sha256"]), | ||
| "sha256", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "dataset", | ||
| ".instance_count", | ||
| &get_field_val(&baseline_manifest, &["dataset", "instance_count"]), | ||
| &get_field_val(&candidate_manifest, &["dataset", "instance_count"]), | ||
| "instance_count", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); |
There was a problem hiding this comment.
Use the newly defined cmp_manifest! macro to simplify the field comparisons for harness and dataset.
cmp_manifest!("harness", "name");
cmp_manifest!("harness", "version");
cmp_manifest!("harness", "git_sha");
cmp_manifest!("harness", "git_dirty");
// 2. dataset
cmp_manifest!("dataset", "path");
cmp_manifest!("dataset", "sha256");
cmp_manifest!("dataset", "instance_count");| cmp_manifest( | ||
| "prompt_template", | ||
| ".source", | ||
| &get_field_val(&baseline_manifest, &["prompt_template", "source"]), | ||
| &get_field_val(&candidate_manifest, &["prompt_template", "source"]), | ||
| "source", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "prompt_template", | ||
| ".path", | ||
| &get_field_val(&baseline_manifest, &["prompt_template", "path"]), | ||
| &get_field_val(&candidate_manifest, &["prompt_template", "path"]), | ||
| "path", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "prompt_template", | ||
| ".sha256", | ||
| &get_field_val(&baseline_manifest, &["prompt_template", "sha256"]), | ||
| &get_field_val(&candidate_manifest, &["prompt_template", "sha256"]), | ||
| "sha256", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
|
|
||
| // 4. model | ||
| compare_field( | ||
| cmp_manifest( | ||
| "model", | ||
| ".name", | ||
| &get_field_val(&baseline_manifest, &["model", "name"]), | ||
| &get_field_val(&candidate_manifest, &["model", "name"]), | ||
| "name", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "model", | ||
| ".backend", | ||
| &get_field_val(&baseline_manifest, &["model", "backend"]), | ||
| &get_field_val(&candidate_manifest, &["model", "backend"]), | ||
| "backend", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "model", | ||
| ".backend_version", | ||
| &get_field_val(&baseline_manifest, &["model", "backend_version"]), | ||
| &get_field_val(&candidate_manifest, &["model", "backend_version"]), | ||
| "backend_version", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| cmp_manifest( | ||
| "model", | ||
| ".base_url", | ||
| &get_field_val(&baseline_manifest, &["model", "base_url"]), | ||
| &get_field_val(&candidate_manifest, &["model", "base_url"]), | ||
| "base_url", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); |
There was a problem hiding this comment.
Use the newly defined cmp_manifest! macro to simplify the field comparisons for prompt_template and model.
cmp_manifest!("prompt_template", "source");
cmp_manifest!("prompt_template", "path");
cmp_manifest!("prompt_template", "sha256");
// 4. model
cmp_manifest!("model", "name");
cmp_manifest!("model", "backend");
cmp_manifest!("model", "backend_version");
cmp_manifest!("model", "base_url");| let cmp_limits = |field: &str, | ||
| compared_fields: &mut Vec<ComparedField>, | ||
| changed_fields: &mut Vec<ChangedField>, | ||
| ignored_fields: &mut Vec<IgnoredField>| { | ||
| let path = format!(".{field}"); | ||
| compare_field( | ||
| "limits", | ||
| &path, | ||
| &get_field_val(&base_limits, &[field]), | ||
| &get_field_val(&cand_limits, &[field]), | ||
| compared_fields, | ||
| changed_fields, | ||
| ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| }; | ||
|
|
||
| cmp_limits( | ||
| "step_limit", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| "limits", | ||
| ".per_task_budget_usd", | ||
| &get_field_val(&base_limits, &["per_task_budget_usd"]), | ||
| &get_field_val(&cand_limits, &["per_task_budget_usd"]), | ||
| cmp_limits( | ||
| "per_task_budget_usd", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| "limits", | ||
| ".task_timeout_secs", | ||
| &get_field_val(&base_limits, &["task_timeout_secs"]), | ||
| &get_field_val(&cand_limits, &["task_timeout_secs"]), | ||
| cmp_limits( | ||
| "task_timeout_secs", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); | ||
| compare_field( | ||
| "limits", | ||
| ".sweep_cost_limit_usd", | ||
| &get_field_val(&base_limits, &["sweep_cost_limit_usd"]), | ||
| &get_field_val(&cand_limits, &["sweep_cost_limit_usd"]), | ||
| cmp_limits( | ||
| "sweep_cost_limit_usd", | ||
| &mut compared_fields, | ||
| &mut changed_fields, | ||
| &mut ignored_fields, | ||
| &ignore_patterns, | ||
| ); |
There was a problem hiding this comment.
Since cmp_limits is defined and used within a single contiguous block with no other intervening borrows of compared_fields, changed_fields, or ignored_fields, we can simplify the closure by capturing these variables mutably from the outer scope. This eliminates the need to pass them as arguments in every call.
let mut cmp_limits = |field: &str| {
let path = format!(".{field}");
compare_field(
"limits",
&path,
&get_field_val(&base_limits, &[field]),
&get_field_val(&cand_limits, &[field]),
&mut compared_fields,
&mut changed_fields,
&mut ignored_fields,
&ignore_patterns,
);
};
cmp_limits("step_limit");
cmp_limits("per_task_budget_usd");
cmp_limits("task_timeout_secs");
cmp_limits("sweep_cost_limit_usd");
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## trunk #625 +/- ##
==========================================
- Coverage 85.40% 85.40% -0.01%
==========================================
Files 116 116
Lines 67035 67021 -14
==========================================
- Hits 57250 57236 -14
Misses 9785 9785 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
compare_fieldwith 8 arguments, duplicating paths and variables across 18 calls.cmp_manifestandcmp_limitsclosures to simplify field comparisons.runmethod readable.PR created automatically by Jules for task 16519351247515352404 started by @madmax983