diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 99d313e12..843c60db3 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -2643,6 +2643,11 @@ def preset_add( console.print(f"[red]Error:[/red] Failed to download: {e}") raise typer.Exit(1) + 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.") + raise typer.Exit(1) + suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip" archive_path = Path(tmpdir) / f"preset{suffix}" archive_path.write_bytes(archive_data) @@ -3652,6 +3657,11 @@ def extension_add( archive_fmt = _detect_archive_format(from_url, content_type) archive_data = response.read() + 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.") + raise typer.Exit(1) + suffix = ".tar.gz" if archive_fmt == "tar.gz" else ".zip" archive_path = download_dir / f"{extension}-url-download{suffix}" archive_path.write_bytes(archive_data) @@ -4936,7 +4946,7 @@ def _extract_workflow_yml(archive_path: Path, archive_fmt: str) -> bytes: if f is not None: return f.read() except KeyError: - pass + pass # Root-level workflow.yml not found; fall through to subdirectory search below. # Look in a single top-level subdirectory. candidates = [ m for m in tf.getmembers() @@ -5099,7 +5109,7 @@ def workflow_add( _validate_and_install_local(source_path, str(source_path)) return elif source_path.is_file() and ( - source.endswith(".tar.gz") or source.endswith(".tgz") or source.endswith(".zip") + source.lower().endswith(".tar.gz") or source.lower().endswith(".tgz") or source.lower().endswith(".zip") ): # Local archive file containing workflow.yml from .extensions import _detect_archive_format diff --git a/src/specify_cli/extensions.py b/src/specify_cli/extensions.py index f28c02e9b..27e78925d 100644 --- a/src/specify_cli/extensions.py +++ b/src/specify_cli/extensions.py @@ -2151,6 +2151,11 @@ class ExtensionCatalog: raise ExtensionError(f"Failed to save extension archive: {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." + ) if archive_fmt == "tar.gz": archive_filename = f"{extension_id}-{version}.tar.gz" else: diff --git a/src/specify_cli/presets.py b/src/specify_cli/presets.py index 0d597423e..f8cd3bbba 100644 --- a/src/specify_cli/presets.py +++ b/src/specify_cli/presets.py @@ -2331,6 +2331,11 @@ class PresetCatalog: raise PresetError(f"Failed to save preset archive: {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." + ) if archive_fmt == "tar.gz": archive_filename = f"{pack_id}-{version}.tar.gz" else: