#!/usr/bin/env php symlinks to modules//web * - copy: copy module web directories (for environments without symlink support) * * Exit codes: * 0 — sync successful * 1 — error during sync */ declare(strict_types=1); use MintyPHP\App\Module\ModuleRegistry; use MintyPHP\App\Module\ModuleRuntimeAssetPublisher; require_once __DIR__ . '/module-cli-bootstrap.php'; function moduleAssetsSyncRun(): int { $warningsBefore = moduleCliVendorWarningsIgnoredTotal(); moduleCliBootstrapApp(); $exitCode = 0; $runtimeModulesDir = __DIR__ . '/../web/modules'; $lockFile = __DIR__ . '/../storage/runtime/.module-assets-sync.lock'; $mode = (string) getenv('APP_MODULE_ASSET_MODE'); if (trim($mode) === '') { $mode = 'symlink'; } try { $lockDir = dirname($lockFile); if (!is_dir($lockDir) && !mkdir($lockDir, 0775, true) && !is_dir($lockDir)) { throw new RuntimeException("Failed to create lock directory: {$lockDir}"); } $lock = fopen($lockFile, 'c'); if ($lock === false || !flock($lock, LOCK_EX | LOCK_NB)) { fwrite(STDERR, "module-assets-sync: another sync is in progress, skipping.\n"); return 0; } $registry = app(ModuleRegistry::class); $publisher = new ModuleRuntimeAssetPublisher(); $result = $publisher->publish($runtimeModulesDir, $registry->getModules(), $mode); fwrite(STDOUT, sprintf( "module-assets-sync: mode=%s created=%d updated=%d removed=%d unchanged=%d\n", $mode, $result['created'], $result['updated'], $result['removed'], $result['unchanged'] )); } catch (Throwable $exception) { fwrite(STDERR, sprintf("module-assets-sync: FAILED: %s\n", $exception->getMessage())); $exitCode = 1; } finally { if (isset($lock) && is_resource($lock)) { flock($lock, LOCK_UN); fclose($lock); } } $vendorWarningsIgnored = moduleCliVendorWarningsIgnoredSince($warningsBefore); fwrite(STDOUT, sprintf("module-assets-sync: vendor_warnings_ignored=%d\n", $vendorWarningsIgnored)); return $exitCode; } if (PHP_SAPI === 'cli' && realpath((string) ($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { exit(moduleAssetsSyncRun()); }