Files
Jonathan Miller 1d87be7d5e
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
fix: standardize file headers — REPO rename, SPDX case, missing fields
- Update REPO: from MokoStandards-API to moko-platform in 125 files
- Fix wrong org path (mokoconsulting-tech → MokoConsulting) in 10 files
- Fix SPDX-LICENSE-IDENTIFIER case in 2 template files
- Add missing REPO: field to 3 files

Authored-by: Moko Consulting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 17:01:17 -05:00

204 lines
7.4 KiB
PHP

#!/usr/bin/env php
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* 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<string, array{string, string}>
*/
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 <<<PHP
#!/usr/bin/env php
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* 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";