Normalize git tails in external short names; surface the name-match suppressions

This commit is contained in:
J. Nick Koston
2026-08-22 17:24:26 -05:00
parent 385e2a92d2
commit 2a1af47cef
3 changed files with 28 additions and 10 deletions
+14 -8
View File
@@ -195,7 +195,6 @@ def _collect_lib_sources(
name: str, name: str,
read_path: Path, read_path: Path,
lib: ArduinoLibrary, lib: ArduinoLibrary,
build: dict,
src_dir: str, src_dir: str,
src_filter: list[str], src_filter: list[str],
) -> None: ) -> None:
@@ -246,7 +245,7 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
name, read_path, lib, lex_build_flags(build.get("flags", []), f"library {name}") name, read_path, lib, lex_build_flags(build.get("flags", []), f"library {name}")
) )
_resolve_include_dirs(name, read_path, lib, build, src_dir, include_flags) _resolve_include_dirs(name, read_path, lib, build, src_dir, include_flags)
_collect_lib_sources(name, read_path, lib, build, src_dir, src_filter) _collect_lib_sources(name, read_path, lib, src_dir, src_filter)
return lib return lib
@@ -306,12 +305,16 @@ def _external_short_name(name: str) -> str:
"owner/Name" and plain names take the last path segment; the "owner/Name" and plain names take the last path segment; the
"Name=<url>" custom-name form takes the declared name (the URL tail is "Name=<url>" custom-name form takes the declared name (the URL tail is
a repository path, not a library name). a repository path, not a library name). Git tails (".git", "#ref") are
stripped like the walk's own URL normalization -- deliberately further
than CORE.add_library's keying, because the comparand here is a manifest
dependency name, never a spec.
""" """
head, sep, tail = name.partition("=") head, sep, tail = name.partition("=")
if sep and "://" in tail: if sep and "://" in tail:
return head return head
return name.rsplit("/", maxsplit=1)[-1] short = name.rsplit("/", maxsplit=1)[-1]
return short.partition("#")[0].removesuffix(".git")
def resolve_libraries( def resolve_libraries(
@@ -470,10 +473,13 @@ def resolve_libraries(
) )
for name in pending_bundled: for name in pending_bundled:
if name in converted_manifest_names: if name in converted_manifest_names:
# Exact manifest-name evidence: the converted library is this # Manifest-name evidence: the converted library is this library,
# library, so the bundled copy would double the archive # so the bundled copy would double the archive. Warn like the
_LOGGER.debug( # external_short_names twin: a coincidental collision would
"Bundled %s suppressed by a converted library's manifest name", # otherwise surface only as link errors
_LOGGER.warning(
"Dependency %s is assumed satisfied by a converted library's "
"manifest name; the bundled copy is not added",
name, name,
) )
continue continue
+7
View File
@@ -923,6 +923,13 @@ def _warn_unsatisfied_versionless(
# A version-less dep's request key is the name itself # A version-less dep's request key is the name itself
continue continue
if dep_name in resolved_manifest_names: if dep_name in resolved_manifest_names:
# Name-only evidence: any resolved component with this manifest
# name counts, not just ones the requester can reach
_LOGGER.debug(
"Version-less dependency %s of %s satisfied by manifest name only",
dep_name,
requester,
)
continue continue
if ( if (
not dep_owner not dep_owner
+7 -2
View File
@@ -984,6 +984,9 @@ def test_transitively_resolved_dependency_does_not_warn(
# An "=" without a URL is a registry name, not the custom-name form # An "=" without a URL is a registry name, not the custom-name form
("FOO=BAR", "FOO=BAR"), ("FOO=BAR", "FOO=BAR"),
("https://github.com/x/Wire", "Wire"), ("https://github.com/x/Wire", "Wire"),
# Git tails are stripped like the walk's URL normalization
("https://github.com/x/Wire.git", "Wire"),
("git+https://github.com/x/Wire.git#v1", "Wire"),
], ],
) )
def test_external_short_name(spec: str, expected: str) -> None: def test_external_short_name(spec: str, expected: str) -> None:
@@ -991,10 +994,11 @@ def test_external_short_name(spec: str, expected: str) -> None:
def test_converted_manifest_name_suppresses_bundled_dependency( def test_converted_manifest_name_suppresses_bundled_dependency(
tmp_path: Path, tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None: ) -> None:
"""A name a converted library's manifest provides is not also added """A name a converted library's manifest provides is not also added
from the framework tree, even when the provider emits later.""" from the framework tree, even when the provider emits later; the
suppression warns like its external_short_names twin."""
framework = _make_framework(tmp_path) framework = _make_framework(tmp_path)
_add_library("ESP32Async/ESPAsyncWebServer", "3.9.6") _add_library("ESP32Async/ESPAsyncWebServer", "3.9.6")
# Requested under a different short name; only the manifest says "Wire" # Requested under a different short name; only the manifest says "Wire"
@@ -1020,6 +1024,7 @@ def test_converted_manifest_name_suppresses_bundled_dependency(
"esp32async__ESPAsyncWebServer", "esp32async__ESPAsyncWebServer",
"someone__WireLib", "someone__WireLib",
] ]
assert "Dependency Wire is assumed satisfied by a converted" in caplog.text
def test_bundled_library_root_headers_pass_the_probe(tmp_path: Path) -> None: def test_bundled_library_root_headers_pass_the_probe(tmp_path: Path) -> None: