Files
moko-platform/cli/completion.php
T
Jonathan Miller b3d9ee8255
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 36s
refactor(cli): migrate 64 legacy scripts to CliFramework (#235)
Wrap all CLI tools in cli/, automation/, maintenance/, deploy/, and
release/ in classes extending CliFramework. Replaces manual $argv
parsing with configure()/addArgument(), moves logic into run(): int,
and converts fwrite(STDERR,...) to $this->log(). Two CLIApp subclasses
(generate_dolibarr_version_txt, generate_joomla_update_xml) converted
to extend CliFramework directly.

Every script now gets free --help, --verbose, --quiet, --dry-run,
--json, --no-color, banners, coloured logging, and progress bars.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-31 11:39:10 -05:00

169 lines
4.7 KiB
PHP

#!/usr/bin/env php
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: moko-platform.CLI
* INGROUP: moko-platform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
* PATH: /cli/completion.php
* BRIEF: Generate bash/zsh tab completion scripts for bin/moko
*/
declare(strict_types=1);
require_once __DIR__ . '/../lib/Enterprise/CliFramework.php';
use MokoEnterprise\CliFramework;
class CompletionCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Generate bash/zsh tab completion scripts for bin/moko');
$this->addArgument('--shell', 'Shell type: bash or zsh', 'bash');
}
protected function run(): int
{
$shell = $this->getArgument('--shell');
// Also accept positional-style: check raw argv for bash/zsh
global $argv;
foreach ($argv as $arg) {
if (in_array($arg, ['bash', 'zsh'], true)) {
$shell = $arg;
break;
}
}
// Extract command names from bin/moko COMMAND_MAP using regex (no eval).
$mokoFile = dirname(__DIR__) . '/bin/moko';
$content = file_get_contents($mokoFile);
// Isolate the COMMAND_MAP block, then extract keys.
if (!preg_match('/const COMMAND_MAP\s*=\s*\[(.+?)\];/s', $content, $block)) {
$this->log('ERROR', 'Could not find COMMAND_MAP in bin/moko');
return 1;
}
// Match 'command-name' => 'path' entries within the block.
if (!preg_match_all("/'([a-z][a-z0-9:_-]*)'\s*=>/m", $block[1], $matches)) {
$this->log('ERROR', 'Could not parse command names from COMMAND_MAP');
return 1;
}
$commandNames = array_unique($matches[1]);
sort($commandNames);
// Common flags supported by CliFramework.
$commonFlags = ['--help', '--verbose', '--quiet', '--dry-run', '--json', '--no-color', '--path'];
if ($shell === 'zsh') {
$this->generateZsh($commandNames, $commonFlags);
} else {
$this->generateBash($commandNames, $commonFlags);
}
return 0;
}
// -- Generators --
private function generateBash(array $commands, array $flags): void
{
$cmdList = implode(' ', $commands);
$flagList = implode(' ', $flags);
echo <<<BASH
# moko bash completion — generated by: php bin/moko completion bash
_moko_complete() {
local cur prev commands flags
COMPREPLY=()
cur="\${COMP_WORDS[COMP_CWORD]}"
prev="\${COMP_WORDS[COMP_CWORD-1]}"
commands="{$cmdList}"
flags="{$flagList}"
# Complete commands (first argument after 'moko')
if [[ \$COMP_CWORD -eq 1 ]] || [[ \$COMP_CWORD -eq 2 && "\${COMP_WORDS[1]}" == "php" ]]; then
COMPREPLY=( \$(compgen -W "\$commands list help" -- "\$cur") )
return 0
fi
# Complete flags
if [[ "\$cur" == -* ]]; then
COMPREPLY=( \$(compgen -W "\$flags" -- "\$cur") )
return 0
fi
# Complete --path with directories
if [[ "\$prev" == "--path" ]]; then
COMPREPLY=( \$(compgen -d -- "\$cur") )
return 0
fi
}
# Register for both direct and php invocation
complete -F _moko_complete moko
complete -F _moko_complete ./bin/moko
complete -F _moko_complete bin/moko
BASH;
}
private function generateZsh(array $commands, array $flags): void
{
$cmdLines = '';
foreach ($commands as $cmd) {
$cmdLines .= " '{$cmd}'\n";
}
$flagLines = '';
foreach ($flags as $flag) {
$desc = match ($flag) {
'--help' => 'Show help for the command',
'--verbose' => 'Show detailed output',
'--quiet' => 'Suppress non-error output',
'--dry-run' => 'Preview changes without writing',
'--json' => 'Machine-readable JSON output',
'--no-color' => 'Disable ANSI colour output',
'--path' => 'Repository root path',
default => $flag,
};
$flagLines .= " '{$flag}[{$desc}]'\n";
}
echo <<<ZSH
#compdef moko bin/moko
# moko zsh completion — generated by: php bin/moko completion zsh
_moko() {
local -a commands flags
commands=(
{$cmdLines} 'list'
'help'
)
flags=(
{$flagLines} )
if (( CURRENT == 2 )); then
_describe 'command' commands
else
_arguments '*:flags:_values "flag" \${flags[@]}'
fi
}
compdef _moko moko
compdef _moko bin/moko
ZSH;
}
}
$app = new CompletionCli();
exit($app->execute());