From 1786d27c062dd60b9f8c54175e4c736b7a91eaf1 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Thu, 7 May 2026 08:17:45 -0500 Subject: [PATCH] Address PR review: fix extractfile fallback and add OSError handling - Fix tar.gz extractfile() None fallback in extension_update: nested-directory search now runs whenever manifest_data is still None, not only on KeyError - Add OSError handling around write_bytes in preset --from URL path - Add OSError handling around write_bytes in extension --from URL path --- src/specify_cli/__init__.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index ce29f48ae..572e6c254 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -2650,8 +2650,12 @@ def preset_add( suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip" archive_path = Path(tmpdir) / f"preset{suffix}" - archive_path.write_bytes(archive_data) - manifest = manager.install_from_zip(archive_path, speckit_version, priority) + try: + archive_path.write_bytes(archive_data) + manifest = manager.install_from_zip(archive_path, speckit_version, priority) + except OSError as e: + console.print(f"[red]Error:[/red] Failed to save or install archive: {e}") + raise typer.Exit(1) console.print(f"[green]✓[/green] Preset '{manifest.name}' v{manifest.version} installed (priority {priority})") @@ -3672,6 +3676,9 @@ def extension_add( except urllib.error.URLError as e: console.print(f"[red]Error:[/red] Failed to download from {from_url}: {e}") raise typer.Exit(1) + except OSError as e: + console.print(f"[red]Error:[/red] Failed to save or install archive: {e}") + raise typer.Exit(1) finally: # Clean up the downloaded archive if archive_path is not None and archive_path.exists(): @@ -4347,7 +4354,10 @@ def extension_update( with f: manifest_data = yaml.safe_load(f.read()) or {} except KeyError: - # Look for extension.yml in a single top-level subdirectory + pass + # Fall back to nested-directory search if root-level + # was missing (KeyError) or not a regular file (None). + if manifest_data is None: 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])