Skip to content

Commit 38e43fa

Browse files
romtsnclaude
andcommitted
ref(code-mappings): Address review feedback on batching
- Use div_ceil and lazy chunks iteration instead of collecting into Vec - Implement FromIterator for MergedResponse to separate merging from request logic - Avoid allocating Vec in print_error_table, iterate filter directly - Use AtomicU8 instead of AtomicU16 in test Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent c29479d commit 38e43fa

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed

src/commands/code_mappings/upload.rs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -77,35 +77,31 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
7777
)?;
7878

7979
let mapping_count = mappings.len();
80-
let batches: Vec<&[BulkCodeMapping]> = mappings.chunks(BATCH_SIZE).collect();
81-
let total_batches = batches.len();
80+
let total_batches = mapping_count.div_ceil(BATCH_SIZE);
8281

8382
println!("Uploading {mapping_count} code mapping(s)...");
8483

8584
let api = Api::current();
8685
let authenticated = api.authenticated()?;
8786

88-
let mut merged = MergedResponse::default();
89-
90-
for (i, batch) in batches.iter().enumerate() {
91-
if total_batches > 1 {
92-
println!("Sending batch {}/{total_batches}...", i + 1);
93-
}
94-
let request = BulkCodeMappingsRequest {
95-
project: &project,
96-
repository: &repo_name,
97-
default_branch: &default_branch,
98-
mappings: batch,
99-
};
100-
match authenticated.bulk_upload_code_mappings(&org, &request) {
101-
Ok(response) => merged.add(response),
102-
Err(err) => {
103-
merged
104-
.batch_errors
105-
.push(format!("Batch {}/{total_batches} failed: {err}", i + 1));
87+
let merged: MergedResponse = mappings
88+
.chunks(BATCH_SIZE)
89+
.enumerate()
90+
.map(|(i, batch)| {
91+
if total_batches > 1 {
92+
println!("Sending batch {}/{total_batches}...", i + 1);
10693
}
107-
}
108-
}
94+
let request = BulkCodeMappingsRequest {
95+
project: &project,
96+
repository: &repo_name,
97+
default_branch: &default_branch,
98+
mappings: batch,
99+
};
100+
authenticated
101+
.bulk_upload_code_mappings(&org, &request)
102+
.map_err(|err| format!("Batch {}/{total_batches} failed: {err}", i + 1))
103+
})
104+
.collect();
109105

110106
// Display error details (successful mappings are summarized in counts only).
111107
print_error_table(&merged.mappings);
@@ -222,9 +218,7 @@ fn infer_default_branch(git_repo: Option<&git2::Repository>, remote_name: Option
222218
}
223219

224220
fn print_error_table(mappings: &[BulkCodeMappingResult]) {
225-
let error_mappings: Vec<_> = mappings.iter().filter(|r| r.status == "error").collect();
226-
227-
if error_mappings.is_empty() {
221+
if !mappings.iter().any(|r| r.status == "error") {
228222
return;
229223
}
230224

@@ -235,7 +229,7 @@ fn print_error_table(mappings: &[BulkCodeMappingResult]) {
235229
.add("Source Root")
236230
.add("Detail");
237231

238-
for result in &error_mappings {
232+
for result in mappings.iter().filter(|r| r.status == "error") {
239233
let detail = result.detail.as_deref().unwrap_or("unknown error");
240234
table
241235
.add_row()
@@ -257,12 +251,24 @@ struct MergedResponse {
257251
batch_errors: Vec<String>,
258252
}
259253

260-
impl MergedResponse {
261-
fn add(&mut self, response: BulkCodeMappingsResponse) {
262-
self.created += response.created;
263-
self.updated += response.updated;
264-
self.errors += response.errors;
265-
self.mappings.extend(response.mappings);
254+
impl FromIterator<Result<BulkCodeMappingsResponse, String>> for MergedResponse {
255+
fn from_iter<I>(iter: I) -> Self
256+
where
257+
I: IntoIterator<Item = Result<BulkCodeMappingsResponse, String>>,
258+
{
259+
let mut merged = Self::default();
260+
for result in iter {
261+
match result {
262+
Ok(response) => {
263+
merged.created += response.created;
264+
merged.updated += response.updated;
265+
merged.errors += response.errors;
266+
merged.mappings.extend(response.mappings);
267+
}
268+
Err(err) => merged.batch_errors.push(err),
269+
}
270+
}
271+
merged
266272
}
267273
}
268274

tests/integration/code_mappings/upload.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::atomic::{AtomicU16, Ordering};
1+
use std::sync::atomic::{AtomicU8, Ordering};
22

33
use crate::integration::{AssertCommand, MockEndpointBuilder, TestManager};
44

@@ -49,7 +49,7 @@ fn command_code_mappings_upload_batches() {
4949
let fixture = tempfile::NamedTempFile::new().expect("failed to create temp file");
5050
serde_json::to_writer(&fixture, &mappings).expect("failed to write fixture");
5151

52-
let call_count = AtomicU16::new(0);
52+
let call_count = AtomicU8::new(0);
5353

5454
TestManager::new()
5555
.mock_endpoint(

0 commit comments

Comments
 (0)