Files
mokocli/wrappers/gen_wrappers.php
T
Jonathan Miller b73c1eba25
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokoplatform CI / CI Summary (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Universal: PR Check / Branch Policy (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Universal: Build & Release / Promote to RC (pull_request) Has been cancelled
RC Revert / Rename rc/ back to dev/ (pull_request) Has been cancelled
Universal: Security Audit / Dependency Audit (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been cancelled
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been cancelled
Generic: Project CI / Lint & Validate (pull_request) Has been cancelled
Platform: mokoplatform CI / Gate 1: Code Quality (pull_request) Has been cancelled
feat: add manifest_detect.php CLI tool for auto-detecting manifest fields
Scans source files to detect platform, name, version, element_name,
package_type, language, entry_point, description, and license_spdx.
Supports Joomla, Dolibarr, Go, MCP/Node, and generic platforms.

Includes --diff and --update modes for comparing against and pushing
to the Gitea manifest API. Warns on missing core fields.

Also removes deprecated mcp/servers/mokowaas_api (consolidated to
separate repo) and syncs dev branch changes.
2026-06-07 15:37:24 -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: MokoPlatform.Wrappers
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* 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: MokoPlatform.Wrappers
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* 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";