#!/usr/bin/env php * * This file is part of a Moko Consulting project. * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: MokoStandards.Wrappers * INGROUP: MokoStandards * REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform * PATH: /wrappers/gen_wrappers.php * BRIEF: Generate PHP CLI wrapper scripts for every PHP script in the repo */ declare(strict_types=1); /** * Canonical map: wrapper_name => [script_path, category] * * @var array */ const SCRIPTS = [ // validate 'auto_detect_platform' => ['validate/auto_detect_platform.php', 'validate'], 'check_changelog' => ['validate/check_changelog.php', 'validate'], 'check_dolibarr_module' => ['validate/check_dolibarr_module.php', 'validate'], 'check_enterprise_readiness' => ['validate/check_enterprise_readiness.php', 'validate'], 'check_joomla_manifest' => ['validate/check_joomla_manifest.php', 'validate'], 'check_language_structure' => ['validate/check_language_structure.php', 'validate'], 'check_license_headers' => ['validate/check_license_headers.php', 'validate'], 'check_no_secrets' => ['validate/check_no_secrets.php', 'validate'], 'check_paths' => ['validate/check_paths.php', 'validate'], 'check_php_syntax' => ['validate/check_php_syntax.php', 'validate'], 'check_repo_health' => ['validate/check_repo_health.php', 'validate'], 'check_structure' => ['validate/check_structure.php', 'validate'], 'check_tabs' => ['validate/check_tabs.php', 'validate'], 'check_version_consistency' => ['validate/check_version_consistency.php', 'validate'], 'check_xml_wellformed' => ['validate/check_xml_wellformed.php', 'validate'], 'scan_drift' => ['validate/scan_drift.php', 'validate'], // automation 'bulk_sync' => ['automation/bulk_sync.php', 'automation'], // deploy 'deploy_sftp' => ['deploy/deploy-sftp.php', 'deploy'], // fix 'fix_line_endings' => ['fix/fix_line_endings.php', 'fix'], 'fix_permissions' => ['fix/fix_permissions.php', 'fix'], 'fix_tabs' => ['fix/fix_tabs.php', 'fix'], 'fix_trailing_spaces' => ['fix/fix_trailing_spaces.php', 'fix'], // maintenance 'pin_action_shas' => ['maintenance/pin_action_shas.php', 'maintenance'], 'setup_labels' => ['maintenance/setup_labels.php', 'maintenance'], 'sync_dolibarr_readmes' => ['maintenance/sync_dolibarr_readmes.php', 'maintenance'], 'update_sha_hashes' => ['maintenance/update_sha_hashes.php', 'maintenance'], 'update_version_from_readme' => ['maintenance/update_version_from_readme.php', 'maintenance'], // plugin 'plugin_health_check' => ['plugin_health_check.php', 'plugin'], 'plugin_list' => ['plugin_list.php', 'plugin'], 'plugin_metrics' => ['plugin_metrics.php', 'plugin'], 'plugin_readiness' => ['plugin_readiness.php', 'plugin'], 'plugin_validate' => ['plugin_validate.php', 'plugin'], ]; /** * Render a single PHP wrapper file. * * @param string $name Wrapper / script name (snake_case) * @param string $scriptPath Script path relative to repo root * @param string $category Log sub-directory category * @return string Complete PHP file content */ function renderWrapper(string $name, string $scriptPath, string $category): string { return << * * This file is part of a Moko Consulting project. * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: MokoStandards.Wrappers * INGROUP: MokoStandards * REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform * PATH: /wrappers/{$name}.php * BRIEF: PHP wrapper for {$scriptPath} */ declare(strict_types=1); const SCRIPT_NAME = '{$name}'; const SCRIPT_PATH = '{$scriptPath}'; const SCRIPT_CATEGORY = '{$category}'; /** * Walk up from \$startDir until a .git directory is found, or return getcwd(). */ function findRepoRoot(string \$startDir): string { \$dir = \$startDir; for (\$i = 0; \$i < 12; \$i++) { if (is_dir(\$dir . '/.git')) { return \$dir; } \$parent = dirname(\$dir); if (\$parent === \$dir) { break; } \$dir = \$parent; } return (string) getcwd(); } \$repoRoot = findRepoRoot(__DIR__); \$fullPath = \$repoRoot . '/' . SCRIPT_PATH; if (!file_exists(\$fullPath)) { fwrite(STDERR, '[ERROR] Script not found: ' . \$fullPath . PHP_EOL); exit(1); } \$logDir = \$repoRoot . '/logs/' . SCRIPT_CATEGORY; @mkdir(\$logDir, 0755, true); \$logFile = \$logDir . '/' . SCRIPT_NAME . '_' . date('Ymd_His') . '.log'; \$args = array_map('escapeshellarg', array_slice(\$argv, 1)); \$cmd = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg(\$fullPath); if (\$args !== []) { \$cmd .= ' ' . implode(' ', \$args); } fwrite(STDOUT, '[INFO] Running ' . SCRIPT_NAME . '...' . PHP_EOL); fwrite(STDOUT, '[INFO] Log: ' . \$logFile . PHP_EOL); \$descriptors = [0 => STDIN, 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; \$process = proc_open(\$cmd, \$descriptors, \$pipes); if (!\is_resource(\$process)) { fwrite(STDERR, '[ERROR] Failed to start ' . SCRIPT_NAME . PHP_EOL); exit(1); } \$log = fopen(\$logFile, 'w'); stream_set_blocking(\$pipes[1], false); stream_set_blocking(\$pipes[2], false); while (true) { \$read = [\$pipes[1], \$pipes[2]]; \$write = []; \$except = []; if (stream_select(\$read, \$write, \$except, 0, 200000) === false) { break; } foreach (\$read as \$stream) { \$chunk = fread(\$stream, 8192); if (\$chunk === false || \$chunk === '') { continue; } \$out = (\$stream === \$pipes[1]) ? STDOUT : STDERR; fwrite(\$out, \$chunk); fwrite(\$log, \$chunk); } if (feof(\$pipes[1]) && feof(\$pipes[2])) { break; } } fclose(\$pipes[1]); fclose(\$pipes[2]); fclose(\$log); \$exitCode = proc_close(\$process); if (\$exitCode === 0) { fwrite(STDOUT, '[OK] ' . SCRIPT_NAME . ' completed successfully' . PHP_EOL); } else { fwrite(STDERR, '[ERROR] ' . SCRIPT_NAME . ' failed (exit ' . \$exitCode . ') — see ' . \$logFile . PHP_EOL); } exit(\$exitCode); PHP; } // ── Main ───────────────────────────────────────────────────────────────────── $outDir = __DIR__; $count = 0; foreach (SCRIPTS as $name => [$scriptPath, $category]) { $content = renderWrapper($name, $scriptPath, $category); // Heredoc indentation: strip leading tab from each line $content = preg_replace('/^\t/m', '', $content) ?? $content; $filePath = $outDir . DIRECTORY_SEPARATOR . $name . '.php'; file_put_contents($filePath, $content); echo " {$name}.php\n"; $count++; } echo "\nGenerated {$count} PHP wrappers in {$outDir}\n";