177 lines
4.1 KiB
PHP
Executable File
177 lines
4.1 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
use Amp\File\BlockingDriver;
|
|
use Amp\Loop;
|
|
use Auryn\Injector;
|
|
use Kelunik\AcmeClient\AcmeFactory;
|
|
use League\CLImate\CLImate;
|
|
use function Amp\File\filesystem;
|
|
|
|
$logo = <<<LOGO
|
|
____ __________ ___ ___
|
|
/ __ `/ ___/ __ `__ \/ _ \
|
|
/ /_/ / /__/ / / / / / __/
|
|
\__,_/\___/_/ /_/ /_/\___/
|
|
|
|
LOGO;
|
|
|
|
if (!file_exists(__DIR__ . '/../vendor/autoload.php')) {
|
|
echo $logo;
|
|
echo <<<HELP
|
|
|
|
You need to install the composer dependencies.
|
|
|
|
composer install --no-dev
|
|
|
|
|
|
HELP;
|
|
exit(-1);
|
|
}
|
|
|
|
if (!function_exists('openssl_pkey_get_private')) {
|
|
echo $logo;
|
|
echo <<<HELP
|
|
|
|
You need to enable OpenSSL in your php.ini
|
|
|
|
|
|
HELP;
|
|
exit(-2);
|
|
}
|
|
|
|
require __DIR__ . '/../vendor/autoload.php';
|
|
|
|
$commands = [
|
|
'auto' => '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 = \Kelunik\AcmeClient\getBinary();
|
|
|
|
$help = implode(PHP_EOL, array_map(function ($command) use ($commands) {
|
|
$help = " <green>{$command}</green>\n";
|
|
$help .= " └─ {$commands[$command]}\n";
|
|
return $help;
|
|
}, array_keys($commands)));
|
|
|
|
$help = <<<EOT
|
|
|
|
<yellow>Usage:</yellow>
|
|
bin/acme [command] [--args]
|
|
|
|
<yellow>Options:</yellow>
|
|
<green>-h, --help</green>
|
|
└─ Print this help information.
|
|
|
|
<yellow>Available commands:</yellow>
|
|
{$help}
|
|
Get more help by appending <yellow>--help</yellow> 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 < 70000) {
|
|
$climate->yellow("You're using an older version of PHP which is no longer supported by this client. Have a look at http://php.net/supported-versions.php and upgrade at least to PHP 7.0!");
|
|
$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 = \Kelunik\AcmeClient\suggestCommand($argv[1], array_keys($commands));
|
|
|
|
if ($suggestion) {
|
|
$climate->br()->out(" Did you mean '$suggestion'?");
|
|
}
|
|
|
|
$climate->br();
|
|
|
|
exit(1);
|
|
}
|
|
|
|
// Use blocking driver for now, as amphp/parallel doesn't work inside PHARs
|
|
filesystem(new BlockingDriver);
|
|
|
|
/** @var \Kelunik\AcmeClient\Commands\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(new Amp\Artax\DefaultClient);
|
|
|
|
$command = $injector->make($class);
|
|
|
|
Loop::run(function () use ($command, $climate) {
|
|
$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) {
|
|
exit(0);
|
|
}
|
|
|
|
exit($exitCode);
|
|
} catch (Throwable $e) {
|
|
$handler($e);
|
|
}
|
|
|
|
Loop::stop();
|
|
});
|