Lines 100.00% 43 / 43
Methods 100.00% 13 / 13
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 configure 100.00% 4 / 4 100.00% 1 / 1 1
 execute 100.00% 12 / 12 100.00% 1 / 1 4
 reportProbe 100.00% 6 / 6 100.00% 1 / 1 3
 findProbeOption 100.00% 2 / 2 100.00% 1 / 1 2
 [Stewart\Runtime\Console\ControlCommand] resolveControlTarget 100.00% 6 / 6 100.00% 1 / 1 1
 [Stewart\Runtime\Console\ControlCommand] writeCommandResult 100.00% 3 / 3 100.00% 1 / 1 2
 [Stewart\Runtime\Console\ControlCommand] parseTimeoutOption 100.00% 1 / 1 100.00% 1 / 1 1
 [Stewart\Runtime\Console\StewartCommand] findConfigOption 100.00% 1 / 1 100.00% 1 / 1 1
 [Stewart\Runtime\Console\StewartCommand] nonEmptyStringOption 100.00% 2 / 2 100.00% 1 / 1 3
 [Stewart\Runtime\Console\StewartCommand] writeMissingConfigFileNotice 100.00% 2 / 2 100.00% 1 / 1 2
 [Stewart\Runtime\Console\StewartCommand] writeNotice 100.00% 1 / 1 100.00% 1 / 1 2
 [Stewart\Runtime\Console\StewartCommand] readStringArgument 100.00% 2 / 2 100.00% 1 / 1 2
26final class StatusCommand extends ControlCommand
27{
28    public const string NAME = 'status';
29
30    public function __construct(
31        ConfigLoader $config,
32        ControlTargetResolver $targets,
33        private readonly ControlClient $client,
34        private readonly StatusRenderer $renderer,
35        private readonly FrameCodec $codec,
36        private readonly ReadinessCheck $readiness,
37    ) {
38        parent::__construct($config, $targets);
39    }
40
41    protected function configure(): void
42    {
43        parent::configure();
44        $this
45            ->addOption('json', null, InputOption::VALUE_NONE, 'Print the snapshot as the wire JSON instead of tables')
46            ->addOption('probe', null, InputOption::VALUE_REQUIRED, 'liveness or readiness: print one line and exit 0 or 1, for health checks');
47    }
48
49    protected function execute(InputInterface $input, OutputInterface $output): int
50    {
51        try {
52            $probe = $this->findProbeOption($input);
53            $snapshot = $this->client->fetchSnapshot($this->resolveControlTarget($input), $this->parseTimeoutOption($input));
54        } catch (StewartException|StreamException|CancelledException $e) {
55            $output->writeln('<error>' . $e->getMessage() . '</error>');
56
57            return Command::FAILURE;
58        }
59
60        if ($probe !== null) {
61            return $this->reportProbe($output, $probe, $snapshot);
62        }
63
64        if ((bool) $input->getOption('json')) {
65            $output->write($this->codec->encodeFrame(new SnapshotFrame($snapshot)));
66
67            return Command::SUCCESS;
68        }
69
70        $this->renderer->render($output, $snapshot);
71
72        return Command::SUCCESS;
73    }
74
75    private function reportProbe(OutputInterface $output, ProbeKind $probe, RuntimeSnapshot $snapshot): int
76    {
77        if ($probe === ProbeKind::Liveness) {
78            $output->writeln('alive');
79
80            return Command::SUCCESS;
81        }
82
83        $verdict = $this->readiness->assessSnapshot($snapshot);
84        $output->writeln($verdict->describeVerdict());
85
86        return $verdict->isReady() ? Command::SUCCESS : Command::FAILURE;
87    }
88
89    /** @throws ConfigurationException */
90    private function findProbeOption(InputInterface $input): ?ProbeKind
91    {
92        $probe = $this->nonEmptyStringOption($input, 'probe');
93
94        return $probe === null ? null : ProbeKind::parse($probe);
95    }
96}

Inherited from Stewart\Runtime\Console\ControlCommand

39    protected function resolveControlTarget(InputInterface $input): ControlTarget
40    {
41        $path = $this->findConfigOption($input);
42
43        return $this->targets->resolveTarget(
44            $this->nonEmptyStringOption($input, 'address'),
45            $this->nonEmptyStringOption($input, 'token'),
46            fn(): ControlConfig => $this->config->loadConfig($path)->control,
47        );
48    }
50    protected function writeCommandResult(OutputInterface $output, CommandResult $result): void
51    {
52        $output->writeln($result->message);
53
54        if ($result->warning !== null) {
55            $this->writeNotice($output, $result->warning);
56        }
57    }
60    protected function parseTimeoutOption(InputInterface $input): Duration
61    {
62        return Duration::parse($this->nonEmptyStringOption($input, 'timeout') ?? self::DEFAULT_TIMEOUT);
63    }

Inherited from Stewart\Runtime\Console\StewartCommand

20    protected function findConfigOption(InputInterface $input): ?string
21    {
22        return $this->nonEmptyStringOption($input, 'config');
23    }
25    protected function nonEmptyStringOption(InputInterface $input, string $name): ?string
26    {
27        $value = $input->getOption($name);
28
29        return \is_string($value) && $value !== '' ? $value : null;
30    }
32    protected function writeMissingConfigFileNotice(OutputInterface $output, ?string $missingConfigFile): void
33    {
34        if ($missingConfigFile !== null) {
35            $this->writeNotice($output, \sprintf('No config file at %s; using the environment only.', $missingConfigFile));
36        }
37    }
39    protected function writeNotice(OutputInterface $output, string $notice): void
40    {
41        ($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output)->writeln('<comment>' . $notice . '</comment>');
42    }
44    protected function readStringArgument(InputInterface $input, string $name): string
45    {
46        $value = $input->getArgument($name);
47
48        return \is_string($value) ? $value : '';
49    }