From d00509e77077f1adb7f6ba808e458d161674b133 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 19:22:38 +0000 Subject: [PATCH] Fix IOError messages, close tf.extractfile() handles, mention .tgz in error messages Agent-Logs-Url: https://github.com/github/spec-kit/sessions/891dfd6f-0f75-4522-bcd2-8a6fffb2d5f7 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> --- src/specify_cli/__init__.py | 16 ++++++++++------ src/specify_cli/extensions.py | 4 ++-- src/specify_cli/presets.py | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 843c60db3..b540ebd1a 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -2645,7 +2645,7 @@ def preset_add( if not archive_fmt: console.print("[red]Error:[/red] Could not determine archive format from URL or Content-Type.") - console.print("Ensure the URL points to a .zip or .tar.gz file.") + console.print("Ensure the URL points to a .zip or .tar.gz/.tgz file.") raise typer.Exit(1) suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip" @@ -3659,7 +3659,7 @@ def extension_add( if not archive_fmt: console.print("[red]Error:[/red] Could not determine archive format from URL or Content-Type.") - console.print("Ensure the URL points to a .zip or .tar.gz file.") + console.print("Ensure the URL points to a .zip or .tar.gz/.tgz file.") raise typer.Exit(1) suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip" @@ -4343,14 +4343,16 @@ def extension_update( m = tf.getmember("extension.yml") f = tf.extractfile(m) if f is not None: - manifest_data = yaml.safe_load(f.read()) or {} + with f: + manifest_data = yaml.safe_load(f.read()) or {} except KeyError: # Look for extension.yml in a single top-level subdirectory members = [m for m in tf.getmembers() if m.name.endswith("/extension.yml") and m.name.count("/") == 1] if len(members) == 1: f = tf.extractfile(members[0]) if f is not None: - manifest_data = yaml.safe_load(f.read()) or {} + with f: + manifest_data = yaml.safe_load(f.read()) or {} else: with zipfile.ZipFile(zip_path, "r") as zf: namelist = zf.namelist() @@ -4944,7 +4946,8 @@ def _extract_workflow_yml(archive_path: Path, archive_fmt: str) -> bytes: try: f = tf.extractfile(tf.getmember("workflow.yml")) if f is not None: - return f.read() + with f: + return f.read() except KeyError: pass # Root-level workflow.yml not found; fall through to subdirectory search below. # Look in a single top-level subdirectory. @@ -4955,7 +4958,8 @@ def _extract_workflow_yml(archive_path: Path, archive_fmt: str) -> bytes: if len(candidates) == 1: f = tf.extractfile(candidates[0]) if f is not None: - return f.read() + with f: + return f.read() else: with zipfile.ZipFile(archive_path, "r") as zf: namelist = zf.namelist() diff --git a/src/specify_cli/extensions.py b/src/specify_cli/extensions.py index 27e78925d..6946a1a09 100644 --- a/src/specify_cli/extensions.py +++ b/src/specify_cli/extensions.py @@ -2148,13 +2148,13 @@ class ExtensionCatalog: except urllib.error.URLError as e: raise ExtensionError(f"Failed to download extension from {download_url}: {e}") except IOError as e: - raise ExtensionError(f"Failed to save extension archive: {e}") + raise ExtensionError(f"Failed to read extension archive from {download_url}: {e}") # Choose file extension based on detected format. if not archive_fmt: raise ExtensionError( f"Could not determine archive format for {download_url}. " - "Ensure the URL points to a .zip or .tar.gz file." + "Ensure the URL points to a .zip or .tar.gz/.tgz file." ) if archive_fmt == "tar.gz": archive_filename = f"{extension_id}-{version}.tar.gz" diff --git a/src/specify_cli/presets.py b/src/specify_cli/presets.py index f8cd3bbba..e270bb504 100644 --- a/src/specify_cli/presets.py +++ b/src/specify_cli/presets.py @@ -2328,13 +2328,13 @@ class PresetCatalog: f"Failed to download preset from {download_url}: {e}" ) except IOError as e: - raise PresetError(f"Failed to save preset archive: {e}") + raise PresetError(f"Failed to read preset archive from {download_url}: {e}") # Choose file extension based on detected format. if not archive_fmt: raise PresetError( f"Could not determine archive format for {download_url}. " - "Ensure the URL points to a .zip or .tar.gz file." + "Ensure the URL points to a .zip or .tar.gz/.tgz file." ) if archive_fmt == "tar.gz": archive_filename = f"{pack_id}-{version}.tar.gz"