diff --git a/charmcraft/application/commands/store.py b/charmcraft/application/commands/store.py index 63e8f0728..d1dd0c44d 100644 --- a/charmcraft/application/commands/store.py +++ b/charmcraft/application/commands/store.py @@ -1534,11 +1534,15 @@ def run(self, parsed_args: argparse.Namespace) -> None: for lib in local_libs_data ] ) - except errors.LibraryError: - raise errors.LibraryError( - message=f"Library {parsed_args.library} not found in Charmhub.", - logpath_report=False, - ) + except errors.LibraryError as e: + # If a specific library was requested, use that in the error message + # Otherwise, re-raise the original error which should have details + if parsed_args.library: + raise errors.LibraryError( + message=f"Library {parsed_args.library} not found in Charmhub.", + logpath_report=False, + ) from e + raise # check if something needs to be done analysis = [] @@ -1559,7 +1563,7 @@ def run(self, parsed_args: argparse.Namespace) -> None: break else: raise errors.LibraryError( - message=f"Library {parsed_args.library} not found in Charmhub.", + message=f"Library {lib_data.full_name} not found in Charmhub.", logpath_report=False, ) emit.debug(f"Store tip: {tip}") diff --git a/tests/integration/commands/test_store_commands.py b/tests/integration/commands/test_store_commands.py index 04c9e04fe..42f4cd9bc 100644 --- a/tests/integration/commands/test_store_commands.py +++ b/tests/integration/commands/test_store_commands.py @@ -193,6 +193,38 @@ def test_fetchlib_store_not_found( ) +@pytest.mark.slow +def test_fetchlib_all_library_not_found( + emitter: craft_cli.pytest_plugin.RecordingEmitter, + new_path: pathlib.Path, + config, +) -> None: + """When fetching all libraries, if one is not found, show its name in error message.""" + # Create a library with a fake lib_id that doesn't exist in Charmhub + # Using a lib_id that's clearly fake and won't match any real library + factory.create_lib_filepath( + "nonexistent-charm", + "nonexistent_lib", + api=0, + patch=1, + lib_id="00000000000000000000000000000000", + ) + + args = argparse.Namespace(library=None, format=None) + + with pytest.raises(errors.LibraryError) as exc_info: + FetchLibCommand(config).run(args) + + # The error message should contain the actual library name, not "None" + error_message = exc_info.value.args[0] + assert "charms.nonexistent_charm.v0.nonexistent_lib" in error_message + assert "None" not in error_message + # Verify the full error message format + assert error_message == ( + "Library charms.nonexistent_charm.v0.nonexistent_lib not found in Charmhub." + ) + + @pytest.mark.slow @pytest.mark.parametrize("formatted", [None, "json"]) def test_fetchlib_store_is_old( diff --git a/tests/spread/store/libraries-not-found/task.yaml b/tests/spread/store/libraries-not-found/task.yaml new file mode 100644 index 000000000..11d18058a --- /dev/null +++ b/tests/spread/store/libraries-not-found/task.yaml @@ -0,0 +1,46 @@ +--- +summary: test fetch-lib error message when library not found + +environment: + CHARM_NAME: nonexistent-charm-$(uuidgen | sed -e 's/-//g') + +include: + - tests/ + +prepare: | + tests.pkgs install jq + + # Create a temporary charm directory with a library that has a fake lib_id + mkdir -p charm/lib/charms/nonexistent_charm/v0 + + # Create a library file with metadata that won't exist in Charmhub + cat > charm/lib/charms/nonexistent_charm/v0/fake_lib.py << 'EOF' + # Test library with fake ID + LIBID = "00000000000000000000000000000000" + LIBAPI = 0 + LIBPATCH = 1 + + # Some library code + def test_function(): + pass + EOF + +restore: | + rm -rf charm + +execute: | + cd charm + + # Try to fetch all libraries (without specifying a library name) + # This should fail with error showing library name, not "None" + output=$(charmcraft fetch-lib 2>&1) && exit 1 || true + + # Verify the error message contains the library name + echo "$output" | MATCH "charms.nonexistent_charm.v0.fake_lib" + + # Verify the error message does NOT contain "Library None" + echo "$output" | NOMATCH "Library None" + + # Verify the full error message format + echo "$output" | \ + MATCH "Library charms.nonexistent_charm.v0.fake_lib not found"