Skip to content

Commit c58da69

Browse files
committed
Puppeteer INSTALLER_BINARY: bootstrap from install_root/npm/node_modules/.bin
Fresh provider copies built by Binary.load() via get_provider_with_overrides start with _INSTALLER_BINARY=None, so super().INSTALLER_BINARY() falls through to searching the env/brew installer providers — none of which know about our hermetic <install_root>/npm/node_modules/.bin layout. The install itself writes puppeteer-browsers there, but subsequent load()s couldn't find it, making _list_installed_browsers() silently return empty and default_abspath_handler return None → Binary.load() raises `BinaryLoadError: ERRORS={}`. Mirror PlaywrightProvider's local_cli fallback: check the hermetic npm bin first, then wrap the result in an EnvProvider.load() and persist it via write_cached_binary so repeat lookups are cheap. https://claude.ai/code/session_01Xt1YPCMzQrrFihDgVEYy4S
1 parent ef93382 commit c58da69

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

abxpkg/binprovider_puppeteer.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,70 @@ def setup_PATH(self, no_cache: bool = False) -> None:
126126
def INSTALLER_BINARY(self, no_cache: bool = False):
127127
from . import DEFAULT_PROVIDER_NAMES, PROVIDER_CLASS_BY_NAME
128128

129+
# Prefer the puppeteer-browsers bootstrapped by an earlier install
130+
# under ``<install_root>/npm/node_modules/.bin``. Without this, a
131+
# fresh provider copy (e.g. the one Binary.load() builds via
132+
# get_provider_with_overrides) can't locate puppeteer-browsers and
133+
# ``_list_installed_browsers()`` silently returns empty.
134+
lib_dir = os.environ.get("ABXPKG_LIB_DIR")
135+
if (
136+
self.install_root is not None
137+
and lib_dir
138+
and str(self.install_root).startswith(lib_dir.rstrip("/") + "/")
139+
):
140+
local_cli = (
141+
Path(lib_dir) / "npm" / "node_modules" / ".bin" / self.INSTALLER_BIN
142+
)
143+
elif self.install_root is not None:
144+
local_cli = (
145+
self.install_root / "npm" / "node_modules" / ".bin" / self.INSTALLER_BIN
146+
)
147+
else:
148+
local_cli = None
149+
150+
if (
151+
local_cli is not None
152+
and local_cli.is_file()
153+
and os.access(local_cli, os.X_OK)
154+
):
155+
if (
156+
not no_cache
157+
and self._INSTALLER_BINARY
158+
and self._INSTALLER_BINARY.loaded_abspath == local_cli
159+
and self._INSTALLER_BINARY.is_valid
160+
):
161+
return self._INSTALLER_BINARY
162+
if not no_cache:
163+
cached = self.load_cached_binary(self.INSTALLER_BIN, local_cli)
164+
if cached and cached.loaded_abspath:
165+
self._INSTALLER_BINARY = cached
166+
return cached
167+
env_provider = EnvProvider(
168+
PATH=str(local_cli.parent),
169+
install_root=None,
170+
bin_dir=None,
171+
)
172+
loaded_local = env_provider.load(
173+
bin_name=self.INSTALLER_BIN,
174+
no_cache=no_cache,
175+
)
176+
if loaded_local and loaded_local.loaded_abspath:
177+
if loaded_local.loaded_version and loaded_local.loaded_sha256:
178+
self.write_cached_binary(
179+
self.INSTALLER_BIN,
180+
loaded_local.loaded_abspath,
181+
loaded_local.loaded_version,
182+
loaded_local.loaded_sha256,
183+
resolved_provider_name=(
184+
loaded_local.loaded_binprovider.name
185+
if loaded_local.loaded_binprovider is not None
186+
else self.name
187+
),
188+
cache_kind="dependency",
189+
)
190+
self._INSTALLER_BINARY = loaded_local
191+
return self._INSTALLER_BINARY
192+
129193
loaded = super().INSTALLER_BINARY(no_cache=no_cache)
130194
raw_provider_names = os.environ.get("ABXPKG_BINPROVIDERS")
131195
selected_provider_names = (

0 commit comments

Comments
 (0)