From b3871f7d31ec6eadb954edfd0f4527c7d1322544 Mon Sep 17 00:00:00 2001 From: Jo Carter Date: Tue, 5 May 2020 16:40:50 +0100 Subject: [PATCH] Add Symfony 4 support, fix Symfony 3/4 deprecation notices and drop support for Symfony 2 (and PHP < 7.3) (#34) * Only use current in-life versions of PHP and Symfony * Fix unit tests * Fix symfony 4 deprecations * Update code to match current standards * Update to PHPUnit 9 * Ensure use static asserts * Downgrade to PHPunit 8 to support php 7.2 * Drop php 7.2 support * Check PHP 7.4 support * Update composer json to reflect version changes * Specify reason for TreeBuilder change * Add Symfony 4 instructions * Ensure test cleans up after itself --- .gitignore | 1 + .travis.yml | 25 ++----- Annotation/Cron.php | 40 +++-------- Command/CommandBase.php | 52 +++++++++----- Command/ReplaceCommand.php | 2 +- DependencyInjection/Configuration.php | 13 +++- .../MyBuilderCronosExtension.php | 2 +- Exporter/AnnotationCronExporter.php | 70 ++++++++----------- Exporter/AnnotationLineConfigurator.php | 10 ++- Exporter/ArrayHeaderConfigurator.php | 10 ++- MyBuilderCronosBundle.php | 4 +- README.md | 60 +++++++++------- Tests/Command/DumpCommandTest.php | 57 ++++++++------- Tests/CronosTestCase.php | 5 +- .../MyBuilderCronosExtensionTest.php | 62 ++++++---------- Tests/DependencyInjection/config/full.yml | 2 +- Tests/Fixtures/Command/TestCommand.php | 2 +- Tests/Fixtures/app/AppKernel.php | 7 +- Tests/bootstrap.php | 4 +- composer.json | 17 ++--- phpunit.xml.dist | 18 ++--- 21 files changed, 223 insertions(+), 240 deletions(-) diff --git a/.gitignore b/.gitignore index 23f63b4..830f85d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ composer.phar bin/ vendor/ /Tests/Fixtures/app/cache/ +var/ diff --git a/.travis.yml b/.travis.yml index 225aaff..dca0dc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,27 +12,14 @@ env: matrix: fast_finish: true include: - - php: 7.1 - env: SYMFONY_VERSION="2.7.*" - - php: 7.1 - env: SYMFONY_VERSION="2.8.*" - - php: 7.1 + - php: 7.3 env: SYMFONY_VERSION="3.4.*" - - php: 7.1 - env: SYMFONY_VERSION="4.0.*" - - php: 7.1 - env: SYMFONY_VERSION="4.1.*" - # Test latest PHP against all symfony versions - - php: 7.2 - env: SYMFONY_VERSION="2.7.*" - - php: 7.2 - env: SYMFONY_VERSION="2.8.*" - - php: 7.2 + - php: 7.3 + env: SYMFONY_VERSION="4.4.*" + - php: 7.4 env: SYMFONY_VERSION="3.4.*" - - php: 7.2 - env: SYMFONY_VERSION="4.0.*" - - php: 7.2 - env: SYMFONY_VERSION="4.1.*" + - php: 7.4 + env: SYMFONY_VERSION="4.4.*" before_install: - composer self-update diff --git a/Annotation/Cron.php b/Annotation/Cron.php index 8921a65..a1df08d 100644 --- a/Annotation/Cron.php +++ b/Annotation/Cron.php @@ -12,44 +12,28 @@ */ class Cron extends Annotation { - /** - * @var string - */ + /** @var string */ public $minute; - /** - * @var string - */ + /** @var string */ public $hour; - /** - * @var string - */ + /** @var string */ public $dayOfMonth; - /** - * @var string - */ + /** @var string */ public $month; - /** - * @var string - */ + /** @var string */ public $dayOfWeek; - /** - * @var string - */ + /** @var string */ public $comment; - /** - * @var string - */ + /** @var string */ public $logFile; - /** - * @var string - */ + /** @var string */ public $errorFile; /** @@ -66,13 +50,9 @@ class Cron extends Annotation */ public $server; - /** - * @var string - */ + /** @var string */ public $params; - /** - * @var string - */ + /** @var string */ public $executor; } diff --git a/Command/CommandBase.php b/Command/CommandBase.php index 302c4dc..c649e6e 100644 --- a/Command/CommandBase.php +++ b/Command/CommandBase.php @@ -4,44 +4,62 @@ use MyBuilder\Bundle\CronosBundle\Exporter\AnnotationCronExporter; use MyBuilder\Cronos\Formatter\Cron; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; -class CommandBase extends ContainerAwareCommand +class CommandBase extends Command implements ContainerAwareInterface { - protected function addServerOption() + use ContainerAwareTrait; + + protected function addServerOption(): void { $this ->addOption('server', null, InputOption::VALUE_REQUIRED, 'Only include cron jobs for the specified server', AnnotationCronExporter::ALL_SERVERS); } - /** - * Configure cron export - * - * @param InputInterface $input - * @param OutputInterface $output - * - * @return Cron - */ - protected function configureCronExport(InputInterface $input, OutputInterface $output) + protected function configureCronExport(InputInterface $input, OutputInterface $output): Cron { - $options = array( + $options = [ 'serverName' => $input->getOption('server'), - 'environment' => $input->getOption('env') - ); + 'environment' => $input->getOption('env'), + ]; $output->writeln(sprintf('Server %s', $options['serverName'])); $cron = $this->exportCron($options); - $output->writeln(sprintf('Found %d lines', $cron->countLines())); + $output->writeln(sprintf('Found %d lines', $cron->countLines())); return $cron; } - private function exportCron($options) + /** @throws \LogicException */ + protected function getContainer(): ContainerInterface + { + if (null === $this->container) { + $application = $this->getApplication(); + + if (null === $application) { + throw new \LogicException('The container cannot be retrieved as the application instance is not yet set.'); + } + + $this->container = $application->getKernel()->getContainer(); + + if (null === $this->container) { + throw new \LogicException('The container cannot be retrieved as the kernel has shut down.'); + } + } + + return $this->container; + } + + private function exportCron($options): Cron { $commands = $this->getApplication()->all(); + /** @var AnnotationCronExporter $exporter */ $exporter = $this->getContainer()->get('mybuilder.cronos_bundle.annotation_cron_exporter'); return $exporter->export($commands, $options); diff --git a/Command/ReplaceCommand.php b/Command/ReplaceCommand.php index dfa3688..96ba9b7 100644 --- a/Command/ReplaceCommand.php +++ b/Command/ReplaceCommand.php @@ -31,7 +31,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->getContainer()->get('mybuilder.cronos_bundle.cron_process_updater')->updateWith($cron, $key); $output->writeln(sprintf('Cron successfully updated with key %s', $key)); } catch (\RuntimeException $e) { - $output->writeln(sprintf('Cron cannot be updated - %s', $e->getMessage())); + $output->writeln(sprintf('Cron cannot be updated - %s', $e->getMessage())); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ca528f4..34234a1 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -7,10 +7,17 @@ class Configuration implements ConfigurationInterface { - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('my_builder_cronos'); + if (method_exists(TreeBuilder::class, 'getRootNode')) { + // Symfony 4 + $treeBuilder = new TreeBuilder('my_builder_cronos'); + $rootNode = $treeBuilder->getRootNode(); + } else { + // Symfony 3 + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('my_builder_cronos'); + } $rootNode ->children() diff --git a/DependencyInjection/MyBuilderCronosExtension.php b/DependencyInjection/MyBuilderCronosExtension.php index 0ea56f9..8b7905a 100644 --- a/DependencyInjection/MyBuilderCronosExtension.php +++ b/DependencyInjection/MyBuilderCronosExtension.php @@ -16,7 +16,7 @@ public function load(array $configs, ContainerBuilder $container) $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.yml'); - $exporterConfig = isset($config['exporter']) ? $config['exporter'] : array(); + $exporterConfig = $config['exporter'] ?? []; $container->setParameter('mybuilder.cronos_bundle.exporter_config', $exporterConfig); } } diff --git a/Exporter/AnnotationCronExporter.php b/Exporter/AnnotationCronExporter.php index 1b5bd5e..dbe4984 100644 --- a/Exporter/AnnotationCronExporter.php +++ b/Exporter/AnnotationCronExporter.php @@ -2,43 +2,39 @@ namespace MyBuilder\Bundle\CronosBundle\Exporter; +use Doctrine\Common\Annotations\Annotation; +use Doctrine\Common\Annotations\Reader; use MyBuilder\Bundle\CronosBundle\Annotation\Cron as CronAnnotation; use MyBuilder\Cronos\Formatter\Cron as CronFormatter; use Symfony\Component\Console\Command\Command; class AnnotationCronExporter { - const ALL_SERVERS = 'all'; + public const ALL_SERVERS = 'all'; + /** @var Reader */ private $annotationsReader; - private $config = array(); - public function __construct($annotationsReader) + /** @var array */ + private $config = []; + + public function __construct(Reader $annotationsReader) { $this->annotationsReader = $annotationsReader; } - /** - * Set the config - * - * @param array $config - */ - public function setConfig(array $config) + public function setConfig(array $config): void { $this->config = $config; } /** * Export the cron for the given commands and server - * - * @param array $commands - * @param array $options - * - * @return CronFormatter */ - public function export(array $commands, array $options) + public function export(array $commands, array $options): CronFormatter { $cron = $this->createCronConfiguration(); + foreach ($commands as $command) { if ($command instanceof Command) { $cron = $this->parseAnnotations($cron, $command, $options); @@ -48,20 +44,16 @@ public function export(array $commands, array $options) return $cron; } - /** - * Create and configure Cron - * - * @return CronFormatter - */ - private function createCronConfiguration() + private function createCronConfiguration(): CronFormatter { $cron = new CronFormatter; $configurator = new ArrayHeaderConfigurator($cron->header()); $configurator->configureFrom($this->config); + return $cron; } - private function parseAnnotations($cron, Command $command, array $options) + private function parseAnnotations(CronFormatter $cron, Command $command, array $options): CronFormatter { foreach ($this->getAnnotations($command) as $annotation) { if ($this->annotationBelongsToServer($annotation, $options['serverName'])) { @@ -72,29 +64,32 @@ private function parseAnnotations($cron, Command $command, array $options) return $cron; } - private function annotationBelongsToServer($annotation, $serverName) + private function annotationBelongsToServer(Annotation $annotation, string $serverName): bool { return - $annotation instanceof CronAnnotation && - ($serverName === self::ALL_SERVERS || $annotation->server === $serverName); + $annotation instanceof CronAnnotation + && ($serverName === self::ALL_SERVERS || $annotation->server === $serverName); } - private function addLine($command, $annotation, array $options, $cron) + private function addLine(Command $command, CronAnnotation $annotation, array $options, CronFormatter $cron): CronFormatter { if ($annotation->comment !== null) { $cron->comment($annotation->comment); } + if ($command->getDescription()) { $cron->comment($command->getDescription()); } + $line = $cron->job($this->buildCommand($command->getName(), $annotation, $options)); - + $configurator = new AnnotationLineConfigurator($line); $configurator->configureFrom($annotation); + return $cron; } - private function getAnnotations(Command $command) + private function getAnnotations(Command $command): array { $reflectedClass = new \ReflectionClass($command); @@ -102,27 +97,22 @@ private function getAnnotations(Command $command) } /** - * build the Command to execute with parameters and environment. - * - * @param string $commandName Name of command to execute - * @param $annotation - * @param array $options - * - * @return string + * Build the Command to execute with parameters and environment. */ - private function buildCommand($commandName, $annotation, array $options) + private function buildCommand(string $commandName, CronAnnotation $annotation, array $options): string { + $executor = ''; + if ($annotation->executor) { $executor = $annotation->executor; - } else if ($this->config['executor']) { + } elseif ($this->config['executor']) { $executor = $this->config['executor']; - } else { - $executor = ''; } $console = isset($this->config['console']) ? ' ' . $this->config['console'] : ''; $environment = isset($options['environment']) ? ' --env=' . $options['environment'] : ''; $params = $annotation->params ? ' ' . $annotation->params : ''; + return $executor . $console . ' ' . $commandName . $params . $environment; } -} \ No newline at end of file +} diff --git a/Exporter/AnnotationLineConfigurator.php b/Exporter/AnnotationLineConfigurator.php index 89f137b..e8a9365 100644 --- a/Exporter/AnnotationLineConfigurator.php +++ b/Exporter/AnnotationLineConfigurator.php @@ -2,16 +2,20 @@ namespace MyBuilder\Bundle\CronosBundle\Exporter; +use MyBuilder\Bundle\CronosBundle\Annotation\Cron as CronAnnotation; +use MyBuilder\Cronos\Formatter\Job; + class AnnotationLineConfigurator { + /** @var Job */ private $line; - public function __construct($line) + public function __construct(Job $line) { $this->line = $line; } - public function configureFrom($annotation) + public function configureFrom(CronAnnotation $annotation): Job { if ($annotation->minute !== null) { $this->line->setMinute($annotation->minute); @@ -40,4 +44,4 @@ public function configureFrom($annotation) return $this->line; } -} \ No newline at end of file +} diff --git a/Exporter/ArrayHeaderConfigurator.php b/Exporter/ArrayHeaderConfigurator.php index 1b9a8d2..480bd87 100644 --- a/Exporter/ArrayHeaderConfigurator.php +++ b/Exporter/ArrayHeaderConfigurator.php @@ -2,22 +2,26 @@ namespace MyBuilder\Bundle\CronosBundle\Exporter; +use MyBuilder\Cronos\Formatter\Header; use Symfony\Component\PropertyAccess\PropertyAccessor; class ArrayHeaderConfigurator { - private $configFields = array('mailto', 'path', 'shell', 'encoding', 'contentType', 'timezone'); + /** @var string[] */ + private $configFields = ['mailto', 'path', 'shell', 'encoding', 'contentType', 'timezone']; + /** @var Header */ private $header; - public function __construct($header) + public function __construct(Header $header) { $this->header = $header; } - public function configureFrom(array $config) + public function configureFrom(array $config): Header { $propertyAccessor = new PropertyAccessor(); + foreach ($this->configFields as $configField) { if (isset($config[$configField])) { $propertyAccessor->setValue($this->header, $configField, $config[$configField]); diff --git a/MyBuilderCronosBundle.php b/MyBuilderCronosBundle.php index 7524922..430d316 100644 --- a/MyBuilderCronosBundle.php +++ b/MyBuilderCronosBundle.php @@ -4,4 +4,6 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; -class MyBuilderCronosBundle extends Bundle {} +class MyBuilderCronosBundle extends Bundle +{ +} diff --git a/README.md b/README.md index 9db9b42..9d0455b 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,12 @@ [![Build Status](https://travis-ci.org/mybuilder/cronos-bundle.svg?branch=master)](https://travis-ci.org/mybuilder/cronos-bundle) -A bundle for Symfony that allows you to use `@Cron` annotations to configure when cron should run your console commands. +A bundle for Symfony 3/4 that allows you to use `@Cron` annotations to configure when cron should run your console commands. Uses the [Cronos](https://github.com/mybuilder/cronos) library to do the actual output and updating. ## Installation -**Note:** If you use Symfony 3 or higher you should replace `app/console` with `bin/console`. - ### Install with composer Run the composer require command: @@ -20,38 +18,49 @@ $ php composer.phar require mybuilder/cronos-bundle ### Enable the bundle -Enable the bundle in the `app/AppKernel.php`: +``` -```php -public function registerBundles() { - $bundles = array( +Enable the bundle in the `app/AppKernel.php` for Symfony 3: + +``` php +public function registerBundles(): array +{ + return [ new MyBuilder\Bundle\CronosBundle\MyBuilderCronosBundle(), - ); + ]; } ``` +Enable the bundle in the `config/bundles.php` for Symfony 4: + +```php +return [ + MyBuilder\Bundle\CronosBundle\MyBuilderCronosBundle::class => ['all' => true], +]; +``` + ### Configure the bundle -You can add the following to your `config.yml` to specify +You can add the following to your `config.yml` (Symfony 3) / `packages/my_builder_cronos.yaml` (Symfony 4) to configure the package. ```yaml my_builder_cronos: exporter: key: unique-key mailto: cron@example.com - path: /bin:/home/gavin/bin + path: /bin:/usr/local/bin executor: php - console: app/console + console: bin/console shell: /bin/bash ``` option | description ---------|----------------------------------------- -key | Unique key that wraps all the cron configured for the current application +key | Unique key that wraps all the cron configured for the current application. mailto | Sets the default email address for all cron output to go to. path | Sets the path for all commands in the crontab it works just like the shell PATH, but it does not inherit from your environment. That means you cannot use ~ or other shell expansions. -executor | Allows you to specify a program that all commands should be passed to such as `/usr/local/bin/php` -console | Allows you to specify the console that all commands should be passed to such as `app/console` +executor | Allows you to specify a program that all commands should be passed to such as `/usr/local/bin/php`. +console | Allows you to specify the console that all commands should be passed to such as `bin/console`. shell | Allows you to specify which shell each program should be run with. ## Usage @@ -62,8 +71,8 @@ The first step is to add the use case for the annotation to the top of the comma use MyBuilder\Bundle\CronosBundle\Annotation\Cron; ``` -Then add to the phpdoc for the command class the '@Cron' annotation which tells cron when you want it to run -This example says it should be run on the web server, every 5 minutes and we don't want to log any output. +Then add to the phpdoc for the command class the '@Cron' annotation which tells cron when you want it to run. +This example says it should be run on the web server, every 5 minutes, and we don't want to log any output. ```php /** @@ -75,13 +84,12 @@ class SendQueuedEmailsCommand extends Command {} ``` ### Specifying when to run + The whole point of cron is being able to specify when a script is run therefore there are a lot of options. -You should read the [general cron info](http://en.wikipedia.org/wiki/Cron) for a general idea of -cron and what you can use in these time fields. +You should read the [general cron info](http://en.wikipedia.org/wiki/Cron) for a general idea of cron and what you can use in these time fields. -**Please note** You CANNOT use `*/` in the annotations, if you want `*/5` just put `/5` and [Cronos](https://github.com/mybuilder/cronos) -will automatically change it to `*/5`. +**Please note** You CANNOT use `*/` in the annotations, if you want `*/5` just put `/5` and [Cronos](https://github.com/mybuilder/cronos) will automatically change it to `*/5`. ### Annotation examples @@ -102,8 +110,7 @@ If everything looks ok you can replace your crontab by running the command below `app/console cronos:replace` -You can also limit which commands are included in the cron file by specifying a server and it will then only show -commands which are specified for that server. +You can also limit which commands are included in the cron file by specifying a server, and it will then only show commands which are specified for that server. ### Exporting the cron @@ -112,17 +119,16 @@ commands which are specified for that server. ### Environment -You can choose which environment you want to run the commands in cron under like this +You can choose which environment you want to run the commands in cron under like this. `app/console cronos:replace --server=web --env=prod` ## Troubleshooting * When a cron line is executed it is executed with the user that owns the crontab, but it will not execute any of the users default shell files so all paths etc need to be specified in the command called from the cron line. -* Your crontab will not be executed if you do not have useable shell in /etc/passwd -* If your jobs don't seem to be running check that the cron deamon is running, also check your username is in /etc/cron.allow and not in /etc/cron.deny. -* Environmental substitutions do not work, you can not use things like $PATH, $HOME, or ~/sbin. - +* Your crontab will not be executed if you do not have usable shell in `/etc/passwd` +* If your jobs don't seem to be running check the cron daemon is running, also check your username is in `/etc/cron.allow` and not in `/etc/cron.deny`. +* Environmental substitutions do not work, you cannot use things like `$PATH`, `$HOME`, or `~/sbin`. --- diff --git a/Tests/Command/DumpCommandTest.php b/Tests/Command/DumpCommandTest.php index ce7e1d4..8fd30e2 100644 --- a/Tests/Command/DumpCommandTest.php +++ b/Tests/Command/DumpCommandTest.php @@ -12,42 +12,47 @@ class DumpCommandTest extends CronosTestCase { - private $application; + /** @var Command */ private $command; - protected function setUp() + protected function setUp(): void { - $kernel = $this->createKernel(); + $kernel = self::createKernel(); $kernel->boot(); - $this->application = new Application($kernel); + $application = new Application($kernel); - $this->application->add(new DumpCommand()); - $this->application->add(new ReplaceCommand()); - $this->application->add(new TestCommand()); + $application->add(new DumpCommand()); + $application->add(new ReplaceCommand()); + $application->add(new TestCommand()); - $this->command = $this->application->find('cronos:dump'); + $this->command = $application->find('cronos:dump'); + } + + protected function tearDown(): void + { + self::ensureKernelShutdown(); } /** * @test * @dataProvider environmentDumps */ - public function dumpShouldBeAsExpected($expectedOutput, array $input) + public function test_dump_should_be_as_expected(string $expectedOutput, array $input): void { - $input = array_merge(array('command' => $this->command->getName()), $input); + $input = array_merge(['command' => $this->command->getName()], $input); $commandTester = new CommandTester($this->command); $commandTester->execute($input); - $this->assertEquals($expectedOutput, trim($commandTester->getDisplay())); + static::assertEquals($expectedOutput, trim($commandTester->getDisplay())); } - public function environmentDumps() + public function environmentDumps(): array { - return array( - array( -'Server all + return [ + [ + 'Server all Found 3 lines We would have put the following in cron PATH=/bin:~/bin @@ -58,23 +63,23 @@ public function environmentDumps() */5 */3 * * * php app/console cronos:test-command --env=test 41 10 1 * * php -d mbstring.func_overload=0 app/console cronos:test-command --env=test', - array( - '--env' => 'test' - ) - ), - array( -'Server web + [ + '--env' => 'test', + ], + ], + [ + 'Server web Found 1 lines We would have put the following in cron PATH=/bin:~/bin MAILTO=test@example.com 27 0 * * 6 php app/console cronos:test-command --env=prod', - array( + [ '--env' => 'prod', - '--server' => 'web' - ) - ) - ); + '--server' => 'web', + ], + ], + ]; } } diff --git a/Tests/CronosTestCase.php b/Tests/CronosTestCase.php index 77e8379..31da64d 100644 --- a/Tests/CronosTestCase.php +++ b/Tests/CronosTestCase.php @@ -4,14 +4,11 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; -/** -* CronosTestCase -*/ class CronosTestCase extends WebTestCase { protected static function getKernelClass() { - require_once __DIR__.'/Fixtures/app/AppKernel.php'; + require_once __DIR__ . '/Fixtures/app/AppKernel.php'; return 'MyBuilder\Bundle\CronosBundle\Tests\Fixtures\app\AppKernel'; } diff --git a/Tests/DependencyInjection/MyBuilderCronosExtensionTest.php b/Tests/DependencyInjection/MyBuilderCronosExtensionTest.php index ff85fc8..79540d5 100644 --- a/Tests/DependencyInjection/MyBuilderCronosExtensionTest.php +++ b/Tests/DependencyInjection/MyBuilderCronosExtensionTest.php @@ -8,82 +8,66 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Yaml\Yaml; -/** -* MyBuilderCronosExtension -*/ class MyBuilderCronosExtensionTest extends TestCase { - /** - * @var MyBuilderCronosExtension - */ + /** @var MyBuilderCronosExtension */ private $loader; - /** - * @var ContainerBuilder - */ + /** @var ContainerBuilder */ private $container; - /** - * Setup the test. - */ - public function setUp() + protected function setUp(): void { $this->container = new ContainerBuilder(); $this->loader = new MyBuilderCronosExtension(); } /** - * @param array $expected - * @param string $file yaml config file to load - * * @dataProvider providerTestConfig */ - public function testConfig(array $expected, $file) + public function test_config(array $expected, string $file): void { $this->loader->load($this->getConfig($file), $this->container); - $this->assertEquals($expected, $this->container->getParameter('mybuilder.cronos_bundle.exporter_config')); + static::assertEquals($expected, $this->container->getParameter('mybuilder.cronos_bundle.exporter_config')); } - public function providerTestConfig() + public function providerTestConfig(): array { - return array( - array( - array( + return [ + [ + [ 'executor' => 'php', 'console' => '%kernel.root_dir%/../bin/console', - ), - 'empty.yml' - ), - array( - array( + ], + 'empty.yml', + ], + [ + [ 'key' => 'test', 'mailto' => 'config-test@example.com', 'path' => '/bin:/usr/local/bin', 'executor' => 'php', - 'console' => 'app/console', - 'shell' => '/bin/bash' - ), - 'full.yml' - ), - ); + 'console' => 'bin/console', + 'shell' => '/bin/bash', + ], + 'full.yml', + ], + ]; } /** * Load the specified yaml config file. - * - * @param string $fileName - * - * @return array */ - private function getConfig($fileName) + private function getConfig(string $fileName): array { $locator = new FileLocator(__DIR__ . '/config'); $file = $locator->locate($fileName, null, true); $config = Yaml::parse(file_get_contents($file)); + if (null === $config) { - return array(); + return []; } return $config; diff --git a/Tests/DependencyInjection/config/full.yml b/Tests/DependencyInjection/config/full.yml index b37736b..685326e 100644 --- a/Tests/DependencyInjection/config/full.yml +++ b/Tests/DependencyInjection/config/full.yml @@ -4,5 +4,5 @@ my_builder_cronos: mailto: config-test@example.com path: /bin:/usr/local/bin executor: php - console: app/console + console: bin/console shell: /bin/bash diff --git a/Tests/Fixtures/Command/TestCommand.php b/Tests/Fixtures/Command/TestCommand.php index b3b19e4..d8c43ff 100644 --- a/Tests/Fixtures/Command/TestCommand.php +++ b/Tests/Fixtures/Command/TestCommand.php @@ -14,7 +14,7 @@ */ class TestCommand extends Command { - protected function configure() + protected function configure() { $this->setName('cronos:test-command'); } diff --git a/Tests/Fixtures/app/AppKernel.php b/Tests/Fixtures/app/AppKernel.php index 29cbff2..8c9756d 100644 --- a/Tests/Fixtures/app/AppKernel.php +++ b/Tests/Fixtures/app/AppKernel.php @@ -2,7 +2,6 @@ namespace MyBuilder\Bundle\CronosBundle\Tests\Fixtures\app; -use Doctrine\Common\Annotations\AnnotationRegistry; use MyBuilder\Bundle\CronosBundle\MyBuilderCronosBundle; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Component\HttpKernel\Kernel; @@ -12,12 +11,10 @@ class AppKernel extends Kernel { public function registerBundles() { - $bundles = array( + return [ new FrameworkBundle(), new MyBuilderCronosBundle(), - ); - - return $bundles; + ]; } public function registerContainerConfiguration(LoaderInterface $loader) diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index d4faffd..c4bf1f1 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -5,8 +5,8 @@ use Doctrine\Common\Annotations\AnnotationRegistry; // Composer -if (file_exists(__DIR__.'/../vendor/autoload.php')) { - $loader = require_once __DIR__.'/../vendor/autoload.php'; +if (file_exists(__DIR__ . '/../vendor/autoload.php')) { + $loader = require __DIR__ . '/../vendor/autoload.php'; AnnotationRegistry::registerLoader('class_exists'); diff --git a/composer.json b/composer.json index b7dc269..acbc849 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "mybuilder/cronos-bundle", - "description": "Symfony bundle which allows you to use @Cron annotations to configure cron to run your console commands.", + "description": "Symfony 3/4 bundle which allows you to use @Cron annotations to configure cron to run your console commands.", "keywords": ["cron", "cronos"], "minimum-stability": "stable", "license": "MIT", @@ -17,17 +17,18 @@ "require": { "mybuilder/cronos": "~2.0", "doctrine/annotations": "1.*", - "symfony/console": "~2.7|~3.0||^4.0", - "symfony/framework-bundle": "~2.7|~3.0||^4.0", - "symfony/yaml": "~2.7|~3.0||^4.0", - "symfony/property-access": "~2.7|~3.0||^4.0", - "php": ">=7.1" + "symfony/console": "~3.0||^4.0", + "symfony/framework-bundle": "~3.0||^4.0", + "symfony/yaml": "3.0||^4.0", + "symfony/property-access": "~3.0||^4.0", + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "~7.0" + "roave/security-advisories": "dev-master", + "phpunit/phpunit": "~9.0" }, "autoload": { - "psr-0": { "MyBuilder\\Bundle\\CronosBundle": "" } + "psr-4": { "MyBuilder\\Bundle\\CronosBundle\\": "" } }, "target-dir": "MyBuilder/Bundle/CronosBundle", "config": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0da3079..5104274 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,15 +2,15 @@ + backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="true" + bootstrap="Tests/bootstrap.php">