feat(P2.1h): no-manifest + scan-all-retry resolve from the content-addressed cache, not the global volume
The last paths that read the shared global /root/Arduino/libraries: a compile
with NO manifest (libraries=null — any from-scratch/anon sketch; the manifest is
never auto-derived from #includes) and the incomplete-manifest scan-all retry
(which re-enters compile unscoped). Both fell through to the global dir,
bypassing the cache entirely (a cached lib still failed when global was gone).
Now, when no scope is materialized, point the library search at the cache: the
cache root is itself a valid Arduino libraries dir (each <name@ver-sha> child is
a library), exposed via env (pro overlay sets them):
- arduino-cli: ARDUINO_DIRECTORIES_USER = VELXIO_FALLBACK_SKETCHBOOK (whose
libraries/ -> cache root) when scope_dir is None.
- ESP-IDF: _find_arduino_libraries_dir() prefers VELXIO_FALLBACK_LIBRARIES_DIR.
Unset (OSS self-host) -> legacy global, unchanged.
Also strip a trailing @version from manifest names (_bare_lib_names): norm_name
fused 'ArduinoJson@6.21.5' -> 'arduinojson6215' (cache miss -> global scan-all);
the per-board boards_json manifest is the path that still carries @version.
This commit is contained in:
parent
7674b7b15e
commit
3fe1766dc8
|
|
@ -216,6 +216,13 @@ def _resolve_files(request: CompileRequest) -> list[dict[str, str]]:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _bare_lib_names(names) -> set[str] | None:
|
||||||
|
"""Strip a trailing @version (or @wokwi:hash) from each manifest name and
|
||||||
|
drop empties. None if nothing remains. See _resolve_compile_scope (P2.1h)."""
|
||||||
|
out = {n.split("@", 1)[0].strip() for n in names if n and n.split("@", 1)[0].strip()}
|
||||||
|
return out or None
|
||||||
|
|
||||||
|
|
||||||
async def _resolve_compile_scope(
|
async def _resolve_compile_scope(
|
||||||
request: CompileRequest, requester_id: str | None
|
request: CompileRequest, requester_id: str | None
|
||||||
) -> tuple[set[str] | None, str | None]:
|
) -> tuple[set[str] | None, str | None]:
|
||||||
|
|
@ -248,13 +255,19 @@ async def _resolve_compile_scope(
|
||||||
# owner-bytes gate; P2.2-sec).
|
# owner-bytes gate; P2.2-sec).
|
||||||
gated_owner = await resolve_compile_owner(request.project_id, requester_id)
|
gated_owner = await resolve_compile_owner(request.project_id, requester_id)
|
||||||
|
|
||||||
|
# P2.1h: strip a trailing @version from each manifest name. norm_name fuses
|
||||||
|
# the version digits into the name otherwise ("ArduinoJson@6.21.5" ->
|
||||||
|
# "arduinojson6215"), which misses the cache entry ("arduinojson") and forces
|
||||||
|
# a global-dir scan-all. The per-board manifest (boards_json[].libraries,
|
||||||
|
# which the client sends in request.libraries) is the path that still carries
|
||||||
|
# @version. We don't version-pin today, so the bare name is what resolves.
|
||||||
allowed_libraries: set[str] | None = None
|
allowed_libraries: set[str] | None = None
|
||||||
if request.libraries:
|
if request.libraries:
|
||||||
allowed_libraries = set(request.libraries)
|
allowed_libraries = _bare_lib_names(request.libraries)
|
||||||
elif gated_owner is not None:
|
elif gated_owner is not None:
|
||||||
project_libs = await get_project_libraries(request.project_id)
|
project_libs = await get_project_libraries(request.project_id)
|
||||||
if project_libs:
|
if project_libs:
|
||||||
allowed_libraries = set(project_libs)
|
allowed_libraries = _bare_lib_names(project_libs)
|
||||||
|
|
||||||
owner_id = gated_owner if gated_owner is not None else requester_id
|
owner_id = gated_owner if gated_owner is not None else requester_id
|
||||||
return allowed_libraries, owner_id
|
return allowed_libraries, owner_id
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,17 @@ class ArduinoCLIService:
|
||||||
compile_env = dict(os.environ)
|
compile_env = dict(os.environ)
|
||||||
if scope_dir is not None:
|
if scope_dir is not None:
|
||||||
compile_env["ARDUINO_DIRECTORIES_USER"] = str(scope_dir.parent)
|
compile_env["ARDUINO_DIRECTORIES_USER"] = str(scope_dir.parent)
|
||||||
|
else:
|
||||||
|
# P2.1h: NO manifest -> point the default sketchbook at the
|
||||||
|
# content-addressed cache (VELXIO_FALLBACK_SKETCHBOOK, whose
|
||||||
|
# libraries/ is the cache root) instead of the shared global
|
||||||
|
# volume, so a from-scratch / no-manifest compile (and the
|
||||||
|
# scan-all retry, which re-enters here unscoped) resolves user
|
||||||
|
# libraries from the cache. Unset (OSS self-host) -> arduino-
|
||||||
|
# cli's default sketchbook (legacy global volume).
|
||||||
|
_fb = os.environ.get("VELXIO_FALLBACK_SKETCHBOOK")
|
||||||
|
if _fb:
|
||||||
|
compile_env["ARDUINO_DIRECTORIES_USER"] = _fb
|
||||||
|
|
||||||
# Run compilation using subprocess.run in a thread (Windows compatible)
|
# Run compilation using subprocess.run in a thread (Windows compatible)
|
||||||
# ESP32 lcgamboa emulator requires DIO flash mode and
|
# ESP32 lcgamboa emulator requires DIO flash mode and
|
||||||
|
|
|
||||||
|
|
@ -562,8 +562,19 @@ class ESPIDFCompiler:
|
||||||
return '\n'.join(lines) + '\n'
|
return '\n'.join(lines) + '\n'
|
||||||
|
|
||||||
def _find_arduino_libraries_dir(self) -> Path | None:
|
def _find_arduino_libraries_dir(self) -> Path | None:
|
||||||
"""Find the Arduino global user-libraries directory (installed via arduino-cli)."""
|
"""Find the Arduino global user-libraries directory (installed via arduino-cli).
|
||||||
candidates = [
|
|
||||||
|
P2.1h: when the pro overlay sets VELXIO_FALLBACK_LIBRARIES_DIR (the
|
||||||
|
content-addressed cache root, itself a valid libraries dir whose children
|
||||||
|
are library folders), prefer it — so the no-manifest scan + the scan-all
|
||||||
|
retry resolve from the cache instead of the shared global volume, letting
|
||||||
|
the global volume be retired. Unset (OSS self-host) -> legacy global.
|
||||||
|
"""
|
||||||
|
candidates: list[Path] = []
|
||||||
|
_fb = os.environ.get('VELXIO_FALLBACK_LIBRARIES_DIR')
|
||||||
|
if _fb:
|
||||||
|
candidates.append(Path(_fb))
|
||||||
|
candidates += [
|
||||||
Path.home() / 'Arduino' / 'libraries',
|
Path.home() / 'Arduino' / 'libraries',
|
||||||
Path.home() / 'Documents' / 'Arduino' / 'libraries',
|
Path.home() / 'Documents' / 'Arduino' / 'libraries',
|
||||||
Path('/root/Arduino/libraries'), # Docker / CI as root
|
Path('/root/Arduino/libraries'), # Docker / CI as root
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue