Update install hooks to respect XYZ_BINARY env vars

- All install hooks now respect their respective XYZ_BINARY env vars
  (e.g., WGET_BINARY, CHROME_BINARY, YTDLP_BINARY, etc.)
- Support both absolute paths (/usr/bin/wget2) and binary names (wget2)
- Dynamic bin_name used in Dependency JSONL output
- Updated 11 install hooks to follow the new pattern
- Mark checklist items as complete in TODO_hook_architecture.md
This commit is contained in:
Claude
2025-12-27 10:12:45 +00:00
parent 8c846b7d1c
commit e3ba599812
12 changed files with 339 additions and 85 deletions

View File

@@ -1,25 +1,39 @@
#!/usr/bin/env python3
"""
Validation hook for yt-dlp and its dependencies (node, ffmpeg).
Install hook for yt-dlp and its dependencies (node, ffmpeg).
Runs at crawl start to verify yt-dlp and required binaries are available.
Outputs JSONL for InstalledBinary and Machine config updates.
Respects YTDLP_BINARY, NODE_BINARY, FFMPEG_BINARY env vars.
"""
import os
import sys
import json
from pathlib import Path
def get_bin_name(env_var: str, default: str) -> str:
"""Get binary name from env var or use default."""
configured = os.environ.get(env_var, '').strip()
if configured:
if '/' in configured:
return Path(configured).name
return configured
return default
def find_ytdlp() -> dict | None:
"""Find yt-dlp binary."""
"""Find yt-dlp binary, respecting YTDLP_BINARY env var."""
try:
from abx_pkg import Binary, PipProvider, BrewProvider, AptProvider, EnvProvider
binary = Binary(name='yt-dlp', binproviders=[PipProvider(), BrewProvider(), AptProvider(), EnvProvider()])
bin_name = get_bin_name('YTDLP_BINARY', 'yt-dlp')
binary = Binary(name=bin_name, binproviders=[PipProvider(), BrewProvider(), AptProvider(), EnvProvider()])
loaded = binary.load()
if loaded and loaded.abspath:
return {
'name': 'yt-dlp',
'name': bin_name,
'abspath': str(loaded.abspath),
'version': str(loaded.version) if loaded.version else None,
'sha256': loaded.sha256 if hasattr(loaded, 'sha256') else None,
@@ -32,15 +46,16 @@ def find_ytdlp() -> dict | None:
def find_node() -> dict | None:
"""Find node binary."""
"""Find node binary, respecting NODE_BINARY env var."""
try:
from abx_pkg import Binary, AptProvider, BrewProvider, EnvProvider
binary = Binary(name='node', binproviders=[AptProvider(), BrewProvider(), EnvProvider()])
bin_name = get_bin_name('NODE_BINARY', 'node')
binary = Binary(name=bin_name, binproviders=[AptProvider(), BrewProvider(), EnvProvider()])
loaded = binary.load()
if loaded and loaded.abspath:
return {
'name': 'node',
'name': bin_name,
'abspath': str(loaded.abspath),
'version': str(loaded.version) if loaded.version else None,
'sha256': loaded.sha256 if hasattr(loaded, 'sha256') else None,
@@ -53,15 +68,16 @@ def find_node() -> dict | None:
def find_ffmpeg() -> dict | None:
"""Find ffmpeg binary."""
"""Find ffmpeg binary, respecting FFMPEG_BINARY env var."""
try:
from abx_pkg import Binary, AptProvider, BrewProvider, EnvProvider
binary = Binary(name='ffmpeg', binproviders=[AptProvider(), BrewProvider(), EnvProvider()])
bin_name = get_bin_name('FFMPEG_BINARY', 'ffmpeg')
binary = Binary(name=bin_name, binproviders=[AptProvider(), BrewProvider(), EnvProvider()])
loaded = binary.load()
if loaded and loaded.abspath:
return {
'name': 'ffmpeg',
'name': bin_name,
'abspath': str(loaded.abspath),
'version': str(loaded.version) if loaded.version else None,
'sha256': loaded.sha256 if hasattr(loaded, 'sha256') else None,
@@ -85,6 +101,11 @@ def main():
missing_deps = []
# Get configured binary names
ytdlp_bin_name = get_bin_name('YTDLP_BINARY', 'yt-dlp')
node_bin_name = get_bin_name('NODE_BINARY', 'node')
ffmpeg_bin_name = get_bin_name('FFMPEG_BINARY', 'ffmpeg')
# Emit results for yt-dlp
if ytdlp_result and ytdlp_result.get('abspath'):
print(json.dumps({
@@ -113,10 +134,10 @@ def main():
else:
print(json.dumps({
'type': 'Dependency',
'bin_name': 'yt-dlp',
'bin_name': ytdlp_bin_name,
'bin_providers': 'pip,brew,apt,env',
}))
missing_deps.append('yt-dlp')
missing_deps.append(ytdlp_bin_name)
# Emit results for node
if node_result and node_result.get('abspath'):
@@ -147,13 +168,13 @@ def main():
# node is installed as 'nodejs' package on apt
print(json.dumps({
'type': 'Dependency',
'bin_name': 'node',
'bin_name': node_bin_name,
'bin_providers': 'apt,brew,env',
'overrides': {
'apt': {'packages': ['nodejs']}
}
}))
missing_deps.append('node')
missing_deps.append(node_bin_name)
# Emit results for ffmpeg
if ffmpeg_result and ffmpeg_result.get('abspath'):
@@ -183,10 +204,10 @@ def main():
else:
print(json.dumps({
'type': 'Dependency',
'bin_name': 'ffmpeg',
'bin_name': ffmpeg_bin_name,
'bin_providers': 'apt,brew,env',
}))
missing_deps.append('ffmpeg')
missing_deps.append(ffmpeg_bin_name)
if missing_deps:
print(f"Missing dependencies: {', '.join(missing_deps)}", file=sys.stderr)