Files
cacti/lib/Console/CactiApplication.php
T
Thomas Vincent 1ae479d4f5 feat(cli): add unified command frontend and normalize legacy failures (#7903)
* feat(cli): add unified command frontend and normalize legacy failures

Add the Symfony-backed bin/cacti entry point while preserving legacy argument, terminal, signal, and exit-status behavior. Fold in the focused legacy CLI correctness fixes from #7906 without adding its unused parser abstraction.

Keep path containment and the PHP 8.3 floor out of this review; the latter remains in #7939.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(cli): enforce PHP floor and deny web dispatch

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-09-07 18:36:55 -07:00

74 lines
2.7 KiB
PHP

<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
declare(strict_types = 1);
namespace Cacti\Console;
use Cacti\Console\Command\LegacyScriptCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
final class CactiApplication extends Application {
public function __construct(private readonly string $root) {
parent::__construct('Cacti', $this->readVersion());
foreach (LegacyCommandMap::commands() as $script => $command) {
$this->add(new LegacyScriptCommand($command, $script, $this->root));
}
}
/**
* Dispatch a legacy command before Symfony can claim its flags.
*
* Application::doRun() answers --version/-V itself and rewrites --help/-h
* into the help command, and it reads both straight off the token vector,
* so dropping them from the input definition changes nothing. Forty-five
* scripts under cli/ carry their own --version and --help handling, so a
* legacy command owns its whole flag namespace and Symfony must not read
* any of it.
*/
#[\Override]
public function doRun(InputInterface $input, OutputInterface $output): int {
$name = $this->getCommandName($input);
if ($name !== null && $name !== '') {
try {
$command = $this->find($name);
} catch (\Throwable) {
// Unknown or ambiguous; let Symfony report it as it always has.
$command = null;
}
if ($command instanceof LegacyScriptCommand) {
/* -q belongs to the legacy script too. Symfony has already applied
* it to this output, which would swallow the child's stream while
* the flag is also forwarded to the child. */
$output->setVerbosity(OutputInterface::VERBOSITY_NORMAL);
return $command->run($input, $output);
}
}
return parent::doRun($input, $output);
}
private function readVersion(): string {
$version = @file_get_contents($this->root . '/include/cacti_version');
return $version === false ? 'unknown' : trim($version);
}
}