#!/usr/bin/env php 'Setup, issue and renew based on a single configuration file.', 'setup' => 'Setup and register account.', 'issue' => 'Issue a new certificate.', 'check' => 'Check if a certificate is still valid long enough.', 'revoke' => 'Revoke a certificate.', 'status' => 'Show status about local certificates.', 'version' => 'Print version information.', 'help' => 'Print this help information.', ]; $binary = getBinary(); $help = implode(PHP_EOL, array_map(function ($command) use ($commands) { $help = " {$command}\n"; $help .= " └─ {$commands[$command]}\n"; return $help; }, array_keys($commands))); $help = <<Usage: bin/acme [command] [--args] Options: -h, --help └─ Print this help information. Available commands: {$help} Get more help by appending --help to specific commands. EOT; $climate = new CLImate; if (!in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) { $climate->error('Please run this script on the command line!'); exit(1); } if (PHP_VERSION_ID < 70400) { $climate->yellow("You're using an older version of PHP which is no longer supported by this client. Have a look at https://php.net/supported-versions.php and upgrade at least to PHP 7.4!"); $climate->br(2); } if (count($argv) === 1 || in_array($argv[1], ['-h', 'help', '--help'], true)) { $climate->out($logo . $help); exit(0); } if (!array_key_exists($argv[1], $commands)) { $climate->error("Unknown command '{$argv[1]}'. Use --help for a list of available commands."); $suggestion = suggestCommand($argv[1], array_keys($commands)); if ($suggestion) { $climate->br()->out(" Did you mean '$suggestion'?"); } $climate->br(); exit(1); } /** @var string|Command $class */ $class = "Kelunik\\AcmeClient\\Commands\\" . ucfirst($argv[1]); $definition = $class::getDefinition(); try { $args = $argv; unset($args[1]); $climate->arguments->add($definition); if (count($argv) === 3 && in_array($argv[2], ['-h', '--help'], true)) { $climate->usage(["{$binary} {$argv[1]}"]); $climate->br(); exit(0); } $climate->arguments->parse(array_values($args)); } catch (Exception $e) { $climate->usage(["{$binary} {$argv[1]}"]); $climate->br(); $climate->error($e->getMessage()); $climate->br(); exit(1); } $injector = new Injector; $injector->share($climate); $injector->share(new AcmeFactory); $injector->share(HttpClientBuilder::buildDefault()); $command = $injector->make($class); $exitCode = 1; Loop::run(function () use ($command, $climate, &$exitCode) { $handler = function ($e) use ($climate) { $error = (string) $e; $lines = explode("\n", $error); $lines = array_filter($lines, function ($line) { return $line !== '' && $line[0] !== '#' && $line !== 'Stack trace:'; }); foreach ($lines as $line) { $climate->error($line)->br(); } exit(1); }; try { $exitCode = yield $command->execute($climate->arguments); if ($exitCode === null) { $exitCode = 0; } } catch (Throwable $e) { $handler($e); } Loop::stop(); }); exit($exitCode);