Use annotations and autoconfiguration

Use the `AsCommand` annotation to automatically register commands as
services and automatically add them to `./bin/console` instead of adding
them manually.
This commit is contained in:
Oliver Davies 2024-02-26 20:40:58 +00:00
parent bfc9a89842
commit 4ebfd9333a
17 changed files with 78 additions and 81 deletions

36
autoload_runtime.template Normal file
View file

@ -0,0 +1,36 @@
<?php
// autoload_runtime.php @generated by Symfony Runtime
if (true === (require_once __DIR__.'/autoload.php') || empty($_SERVER['SCRIPT_FILENAME'])) {
return;
}
$pharPath = Phar::running();
if (strlen($pharPath) == 0) {
$scriptFileName = $_SERVER['SCRIPT_FILENAME'];
} else {
$scriptFileName = $_SERVER['APP_SCRIPT_FILENAME'] ?? $_SERVER['SCRIPT_FILENAME'] ?? null;
}
$app = require $scriptFileName;
if (!is_object($app)) {
throw new TypeError(sprintf('Invalid return value: callable object expected, "%s" returned from "%s".', get_debug_type($app), $_SERVER['SCRIPT_FILENAME']));
}
$runtime = $_SERVER['APP_RUNTIME'] ?? $_ENV['APP_RUNTIME'] ?? %runtime_class%;
$runtime = new $runtime(($_SERVER['APP_RUNTIME_OPTIONS'] ?? $_ENV['APP_RUNTIME_OPTIONS'] ?? []) + %runtime_options%);
[$app, $args] = $runtime
->getResolver($app)
->resolve();
$app = $app(...$args);
exit(
$runtime
->getRunner($app)
->run()
);

View file

@ -1,13 +1,17 @@
{ {
"main": "bin/console",
"output": "dist/versa", "output": "dist/versa",
"files": [
"versa"
],
"directories": [ "directories": [
"config",
"src", "src",
"vendor" "vendor"
], ],
"files": [
".env.local.php",
"autoload_runtime.template"
],
"check-requirements": true, "check-requirements": true,
"exclude-composer-files": false, "exclude-composer-files": false,
"force-autodiscovery": true,
"compression": "GZ" "compression": "GZ"
} }

View file

@ -47,13 +47,9 @@
}, },
"scripts": { "scripts": {
"auto-scripts": { "auto-scripts": {
"cache:clear": "symfony-cmd", "cache:clear": "symfony-cmd"
"assets:install %PUBLIC_DIR%": "symfony-cmd"
}, },
"post-install-cmd": [ "post-autoload-dump": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts" "@auto-scripts"
] ]
}, },
@ -61,6 +57,9 @@
"symfony/symfony": "*" "symfony/symfony": "*"
}, },
"extra": { "extra": {
"runtime": {
"autoload_template": "autoload_runtime.template"
},
"symfony": { "symfony": {
"allow-contrib": false, "allow-contrib": false,
"require": "7.0.*" "require": "7.0.*"

View file

@ -1,10 +0,0 @@
framework:
router:
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
#default_uri: http://localhost
when@prod:
framework:
router:
strict_requirements: null

View file

@ -1,5 +0,0 @@
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute

View file

@ -1,4 +0,0 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

View file

@ -1,3 +0,0 @@
<?php
require __DIR__."/versa";

View file

@ -3,5 +3,9 @@ _default:
build: build:
# TODO: create a Nix derivation and add it to the Nix store instead of copying the phar to my Home directory. # TODO: create a Nix derivation and add it to the Nix store instead of copying the phar to my Home directory.
composer dump-env prod
./bin/console cache:clear
./bin/console cache:warmup
./vendor/bin/box compile ./vendor/bin/box compile
rm .env.local.php
cp dist/versa ~/versa cp dist/versa ~/versa

View file

@ -1,9 +0,0 @@
<?php
use App\Kernel;
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

View file

@ -8,8 +8,6 @@ use Symfony\Component\Filesystem\Filesystem;
abstract class AbstractCommand extends Command abstract class AbstractCommand extends Command
{ {
protected static string $description;
public function __construct( public function __construct(
protected Filesystem $filesystem, protected Filesystem $filesystem,
?string $name = null, ?string $name = null,
@ -19,8 +17,6 @@ abstract class AbstractCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->setDescription(static::$description);
$this->addOption( $this->addOption(
name: 'args', name: 'args',
shortcut: 'a', shortcut: 'a',

View file

@ -7,14 +7,19 @@ use App\Enum\ProjectLanguage;
use App\Enum\ProjectType; use App\Enum\ProjectType;
use App\Process\Process; use App\Process\Process;
use RuntimeException; use RuntimeException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
#[AsCommand(
description: 'Install the project\'s dependencies',
name: 'build',
)]
final class BuildCommand extends AbstractCommand final class BuildCommand extends AbstractCommand
{ {
public static string $description = 'Build the project'; public static string $description = '';
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {

View file

@ -8,15 +8,17 @@ use App\Enum\PackageManager;
use App\Enum\ProjectLanguage; use App\Enum\ProjectLanguage;
use App\Process\Process; use App\Process\Process;
use RuntimeException; use RuntimeException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
#[AsCommand(
description: 'Install the project\'s dependencies',
name: 'install',
)]
final class InstallCommand extends AbstractCommand final class InstallCommand extends AbstractCommand
{ {
public static string $description = 'Install the project\'s dependencies';
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
$args = $input->getOption('args'); $args = $input->getOption('args');
@ -27,8 +29,6 @@ final class InstallCommand extends AbstractCommand
workingDir: $workingDir, workingDir: $workingDir,
))->getLanguage(); ))->getLanguage();
$filesystem = new Filesystem();
// TODO: Composer in Docker Compose? // TODO: Composer in Docker Compose?
$process = Process::create( $process = Process::create(
args: explode(separator: ' ', string: strval($args)), args: explode(separator: ' ', string: strval($args)),

View file

@ -7,15 +7,18 @@ use App\Action\DetermineProjectLanguage;
use App\Enum\PackageManager; use App\Enum\PackageManager;
use App\Enum\ProjectLanguage; use App\Enum\ProjectLanguage;
use App\Process\Process; use App\Process\Process;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(
description: 'Install a new package',
name: 'package-install',
)]
final class PackageInstallCommand extends AbstractCommand final class PackageInstallCommand extends AbstractCommand
{ {
public static string $description = 'Install a new package';
public function configure(): void public function configure(): void
{ {
parent::configure(); parent::configure();

View file

@ -6,15 +6,18 @@ use App\Action\DetermineProjectLanguage;
use App\Enum\ProjectLanguage; use App\Enum\ProjectLanguage;
use App\Enum\ProjectType; use App\Enum\ProjectType;
use App\Process\Process; use App\Process\Process;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
#[AsCommand(
description: 'Run the project',
name: 'run',
)]
final class RunCommand extends AbstractCommand final class RunCommand extends AbstractCommand
{ {
public static string $description = 'Run the project';
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
$projectType = null; $projectType = null;

View file

@ -3,14 +3,17 @@
namespace App\Console\Command; namespace App\Console\Command;
use App\Process\Process; use App\Process\Process;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(
description: 'Run the project\'s tests',
name: 'test',
)]
final class TestCommand extends AbstractCommand final class TestCommand extends AbstractCommand
{ {
public static string $description = 'Run the project\'s tests';
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
$args = $input->getOption('args'); $args = $input->getOption('args');

View file

25
versa
View file

@ -1,25 +0,0 @@
#!/usr/bin/env php
<?php
require __DIR__.'/vendor/autoload.php';
use App\Console\Command\BuildCommand;
use App\Console\Command\InstallCommand;
use App\Console\Command\PackageInstallCommand;
use App\Console\Command\RunCommand;
use App\Console\Command\TestCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Filesystem\Filesystem;
$application = new Application();
$filesystem = new Filesystem();
$application->addCommands([
new BuildCommand(filesystem: $filesystem, name: 'build'),
new InstallCommand(filesystem: $filesystem, name: 'install'),
new PackageInstallCommand(filesystem: $filesystem, name: 'package-install'),
new RunCommand(filesystem: $filesystem, name: 'run'),
new TestCommand(filesystem: $filesystem, name: 'test'),
]);
$application->run();