From 593c326b819797e8e73906e6fe85ace590536587 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:21:20 -0600 Subject: [PATCH 1/4] feat(http): add start_operations for progress reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement start_operations call in the http backend to improve progress bar display during tool installation. The operation count is calculated dynamically: - 1 for download (always) - +1 if checksum option is set - +1 for extraction (always) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/backend/http.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/http.rs b/src/backend/http.rs index c0ff73f2e0..ac875813aa 100644 --- a/src/backend/http.rs +++ b/src/backend/http.rs @@ -584,6 +584,14 @@ impl Backend for HttpBackend { let platform_key = self.get_platform_key(); tv.lock_platforms.entry(platform_key).or_default().url = Some(url.clone()); + // Determine operation count for progress reporting + let mut op_count = 1; // download + if get_opt(&opts, "checksum").is_some() { + op_count += 1; + } + op_count += 1; // extraction + ctx.pr.start_operations(op_count); + ctx.pr.set_message(format!("download {filename}")); HTTP.download_file(&url, &file_path, Some(ctx.pr.as_ref())) .await?; From 6e79584a7eefcbacb1627c2f93d3cea6de1d1aa3 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:41:09 -0600 Subject: [PATCH 2/4] fix(http): report extraction progress for all file types and cache hits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, extraction operation was counted in op_count but progress was only reported for archive files on cache miss. This caused the progress bar to not complete properly for compressed binaries, raw files, and cached installations. - Add progress reporting to extract_compressed_binary and extract_raw_file - Report extraction as complete instantly on cache hit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/backend/http.rs | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/backend/http.rs b/src/backend/http.rs index ac875813aa..6f2c4d03f0 100644 --- a/src/backend/http.rs +++ b/src/backend/http.rs @@ -287,9 +287,9 @@ impl HttpBackend { let file_info = FileInfo::new(file_path, opts); if file_info.is_compressed_binary { - self.extract_compressed_binary(dest, file_path, &file_info, opts) + self.extract_compressed_binary(dest, file_path, &file_info, opts, pr) } else if file_info.format == file::TarFormat::Raw { - self.extract_raw_file(dest, file_path, &file_info, opts) + self.extract_raw_file(dest, file_path, &file_info, opts, pr) } else { self.extract_archive(dest, file_path, &file_info, opts, pr) } @@ -302,10 +302,19 @@ impl HttpBackend { file_path: &Path, file_info: &FileInfo, opts: &ToolVersionOptions, + pr: Option<&dyn SingleReport>, ) -> Result { let filename = self.dest_filename(file_path, file_info, opts); let dest_file = dest.join(&filename); + // Report extraction progress + if let Some(pr) = pr { + pr.set_message(format!("extract {}", file_info.file_name())); + if let Ok(metadata) = file_path.metadata() { + pr.set_length(metadata.len()); + } + } + match file_info.extension.as_str() { "gz" => file::un_gz(file_path, &dest_file)?, "xz" => file::un_xz(file_path, &dest_file)?, @@ -314,6 +323,13 @@ impl HttpBackend { _ => unreachable!(), } + // Mark extraction complete + if let Some(pr) = pr { + if let Ok(metadata) = file_path.metadata() { + pr.set_position(metadata.len()); + } + } + file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) } @@ -325,11 +341,28 @@ impl HttpBackend { file_path: &Path, file_info: &FileInfo, opts: &ToolVersionOptions, + pr: Option<&dyn SingleReport>, ) -> Result { let filename = self.dest_filename(file_path, file_info, opts); let dest_file = dest.join(&filename); + // Report extraction progress + if let Some(pr) = pr { + pr.set_message(format!("extract {}", file_info.file_name())); + if let Ok(metadata) = file_path.metadata() { + pr.set_length(metadata.len()); + } + } + file::copy(file_path, &dest_file)?; + + // Mark extraction complete + if let Some(pr) = pr { + if let Ok(metadata) = file_path.metadata() { + pr.set_position(metadata.len()); + } + } + file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) } @@ -612,6 +645,9 @@ impl Backend for HttpBackend { // from current options if a previous extraction used different `bin` name) let extraction_type = if self.is_cached(&cache_key) { ctx.pr.set_message("using cached tarball".into()); + // Report extraction operation as complete (instant since we're using cache) + ctx.pr.set_length(1); + ctx.pr.set_position(1); self.extraction_type_from_cache(&cache_key, &file_info) } else { ctx.pr.set_message("extracting to cache".into()); From 0ca070118822a55c9569ff74a50bf67c41d0f5bc Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:50:53 +0000 Subject: [PATCH 3/4] [autofix.ci] apply automated fixes --- src/backend/http.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/backend/http.rs b/src/backend/http.rs index 6f2c4d03f0..06a55ad62f 100644 --- a/src/backend/http.rs +++ b/src/backend/http.rs @@ -324,11 +324,10 @@ impl HttpBackend { } // Mark extraction complete - if let Some(pr) = pr { - if let Ok(metadata) = file_path.metadata() { + if let Some(pr) = pr + && let Ok(metadata) = file_path.metadata() { pr.set_position(metadata.len()); } - } file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) @@ -357,11 +356,10 @@ impl HttpBackend { file::copy(file_path, &dest_file)?; // Mark extraction complete - if let Some(pr) = pr { - if let Ok(metadata) = file_path.metadata() { + if let Some(pr) = pr + && let Ok(metadata) = file_path.metadata() { pr.set_position(metadata.len()); } - } file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) From a1c0ae59e9bf28ab3a87620b47149c376a86d699 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:55:36 -0600 Subject: [PATCH 4/4] fix(http): include lockfile checksum in operation count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The operation count only accounted for download, user-provided checksum, and extraction. However, verify_checksum() also performs hash operations that call set_length() when verifying/generating lockfile checksums. This caused the progress bar to overshoot 100%. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/backend/http.rs | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/backend/http.rs b/src/backend/http.rs index 06a55ad62f..2aed16d488 100644 --- a/src/backend/http.rs +++ b/src/backend/http.rs @@ -325,9 +325,10 @@ impl HttpBackend { // Mark extraction complete if let Some(pr) = pr - && let Ok(metadata) = file_path.metadata() { - pr.set_position(metadata.len()); - } + && let Ok(metadata) = file_path.metadata() + { + pr.set_position(metadata.len()); + } file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) @@ -357,9 +358,10 @@ impl HttpBackend { // Mark extraction complete if let Some(pr) = pr - && let Ok(metadata) = file_path.metadata() { - pr.set_position(metadata.len()); - } + && let Ok(metadata) = file_path.metadata() + { + pr.set_position(metadata.len()); + } file::make_executable(&dest_file)?; Ok(ExtractionType::RawFile { filename }) @@ -613,7 +615,10 @@ impl Backend for HttpBackend { // Record URL in lock platforms let platform_key = self.get_platform_key(); - tv.lock_platforms.entry(platform_key).or_default().url = Some(url.clone()); + tv.lock_platforms + .entry(platform_key.clone()) + .or_default() + .url = Some(url.clone()); // Determine operation count for progress reporting let mut op_count = 1; // download @@ -621,6 +626,19 @@ impl Backend for HttpBackend { op_count += 1; } op_count += 1; // extraction + + // Account for lockfile checksum verification/generation + let settings = Settings::get(); + let lockfile_enabled = settings.lockfile && settings.experimental; + let has_lockfile_checksum = tv + .lock_platforms + .get(&platform_key) + .and_then(|p| p.checksum.as_ref()) + .is_some(); + if lockfile_enabled || has_lockfile_checksum { + op_count += 1; + } + ctx.pr.start_operations(op_count); ctx.pr.set_message(format!("download {filename}"));