diff --git a/.gitignore b/.gitignore index de4a392..e080be8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /vendor /composer.lock + +/.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..942cecb --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,53 @@ +in('lib') + ->in('tests') + ->files()->name('*.php'); + +$config = new PhpCsFixer\Config(); +$config->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + '@PSR12' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'declare_strict_types' => true, + 'constant_case' => true, + 'combine_consecutive_unsets' => true, + 'native_function_invocation' => [ + 'include' => [ + '@compiler_optimized', + ], + ], + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'continue', + 'extra', + 'return', + 'throw', + 'use', + 'parenthesis_brace_block', + 'square_brace_block', + 'curly_brace_block', + ], + ], + 'ordered_class_elements' => true, + 'ordered_imports' => true, + 'yoda_style' => [ + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, + 'always_move_variable' => false, + ], +]) + ->setRiskyAllowed(true) + ->setFinder( + $finder + ); + +return $config; diff --git a/composer.json b/composer.json index 9320773..5f6b9eb 100644 --- a/composer.json +++ b/composer.json @@ -26,13 +26,14 @@ "minimum-stability": "beta", "require": { "php": "^8.0", - "win32service/service-library": "^0.1.0", + "win32service/service-library": "^1.0", "symfony/http-kernel": "^6.0", "symfony/console": "^6.0", "symfony/config": "^6.0", - "symfony/dependency-injection": "^6.0" + "symfony/dependency-injection": "^6.0", + "symfony/event-dispatcher": "^6.0" }, "require-dev": { - "atoum/atoum": "^3.3" + "rector/rector": "^0.14.2" } } diff --git a/lib/Command/ActionServiceCommand.php b/lib/Command/ActionServiceCommand.php index 7668826..8ad494c 100644 --- a/lib/Command/ActionServiceCommand.php +++ b/lib/Command/ActionServiceCommand.php @@ -6,6 +6,9 @@ namespace Win32ServiceBundle\Command; +use Exception; +use InvalidArgumentException; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -13,18 +16,17 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Win32Service\Model\ServiceIdentifier; use Win32Service\Service\ServiceStateManager; +use const atoum\atoum\phar\name; +#[AsCommand(name: 'win32service:action')] class ActionServiceCommand extends Command { - // the name of the command (the part after "bin/console") - protected static $defaultName = 'win32service:action'; - const ALL_SERVICE = 'All'; /** - * @var array + * @var array */ - private $config; + private array $config = []; protected function configure() { @@ -34,19 +36,15 @@ class ActionServiceCommand extends Command $this->addOption('custom-action', 'c', InputOption::VALUE_REQUIRED, 'The custom control send to the service.', null); } - /** - * @param array $config - * - */ public function defineBundleConfig(array $config) { $this->config = $config; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->config === null) { - throw new \Exception('The configuration of win32Service is not defined into command'); + if ($this->config === []) { + throw new Exception('The configuration of win32Service is not defined into command'); } $serviceToAction = $input->getOption('service-name'); @@ -55,11 +53,11 @@ class ActionServiceCommand extends Command $actions = ['start', 'stop', 'pause', 'continue', 'custom']; if (!in_array($action, $actions)) { - throw new \InvalidArgumentException('The value of action argument is invalid. Valid values : '.implode(', ', $actions)); + throw new InvalidArgumentException('The value of action argument is invalid. Valid values : '.implode(', ', $actions)); } if ($action === 'custom' && ($customAction < 128 || $customAction > 255)) { - throw new \InvalidArgumentException("The custom control value must be between 128 and 255"); + throw new InvalidArgumentException("The custom control value must be between 128 and 255"); } $services = $this->config['services']; @@ -102,7 +100,7 @@ class ActionServiceCommand extends Command break; } $output->writeln('Sending control to ' . $serviceInfos->serviceId() . ' : OK'); - } catch (\Exception $e) { + } catch (Exception $e) { $output->writeln(' Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' '); } } @@ -110,9 +108,10 @@ class ActionServiceCommand extends Command if ($nbService === 0) { $output->writeln('No signal sent'); - return; + return self::FAILURE; } $output->writeln(sprintf('Signal sent to %d service(s)', $nbService)); + return self::SUCCESS; } } diff --git a/lib/Command/ExecuteServiceCommand.php b/lib/Command/ExecuteServiceCommand.php index c83ca75..b0812e3 100644 --- a/lib/Command/ExecuteServiceCommand.php +++ b/lib/Command/ExecuteServiceCommand.php @@ -6,6 +6,8 @@ namespace Win32ServiceBundle\Command; +use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -16,26 +18,19 @@ use Win32Service\Model\ServiceIdentifier; use Win32Service\Model\RunnerServiceInterface; use Win32ServiceBundle\Logger\ThreadNumberEvent; use Win32ServiceBundle\Service\RunnerManager; +use const atoum\atoum\phar\name; +#[AsCommand(name: 'win32service:run')] class ExecuteServiceCommand extends Command { - // the name of the command (the part after "bin/console") - protected static $defaultName = 'win32service:run'; - /** - * @var array + * @var array */ - private $config; + private array $config = []; - /** - * @var RunnerManager - */ - private $service; + private ?RunnerManager $service = null; - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; + private ?EventDispatcherInterface $eventDispatcher = null; protected function configure() { @@ -45,10 +40,6 @@ class ExecuteServiceCommand extends Command $this->addOption('max-run', 'r', InputOption::VALUE_REQUIRED, 'Set the max run'); } - /** - * @param array $config - * - */ public function defineBundleConfig(array $config) { $this->config = $config; @@ -58,20 +49,17 @@ class ExecuteServiceCommand extends Command $this->service = $service; } - /** - * @param EventDispatcherInterface $eventDispatcher - */ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->config === null) { - throw new \Exception('The configuration of win32Service is not defined into command'); + if ($this->config === []) { + throw new Exception('The configuration of win32Service is not defined into command'); } if ($this->service === null) { - throw new \Exception('The service runner manager is not defined into command'); + throw new Exception('The service runner manager is not defined into command'); } $serviceName = $input->getArgument('service-name'); @@ -80,7 +68,7 @@ class ExecuteServiceCommand extends Command $infos=$this->getServiceInformation($serviceName, $threadNumber); if ($infos === null) { - throw new \Exception(sprintf('The information for service %s is not found', $serviceName)); + throw new Exception(sprintf('The information for service %s is not found', $serviceName)); } if ($maxRun === null) { @@ -89,12 +77,12 @@ class ExecuteServiceCommand extends Command $runner = $this->service->getRunner($infos['service_id']); if ($runner === null) { - throw new \Exception(sprintf('The runner for service "%1$s" is not found. Call method \'add\' on the RunnerManager with the runner instance and the alias "%1$s".', $infos['service_id'])); + throw new Exception(sprintf('The runner for service "%1$s" is not found. Call method \'add\' on the RunnerManager with the runner instance and the alias "%1$s".', $infos['service_id'])); } if ($this->eventDispatcher !== null) { $event = new ThreadNumberEvent($threadNumber); - $this->eventDispatcher->dispatch(ThreadNumberEvent::NAME, $event); + $this->eventDispatcher->dispatch($event,ThreadNumberEvent::NAME); } $runner->setServiceId(ServiceIdentifier::identify($serviceName, $infos['machine'])); @@ -103,6 +91,7 @@ class ExecuteServiceCommand extends Command $runner->doRun(intval($maxRun), $threadNumber); + return self::SUCCESS; } private function getServiceInformation(string $serviceToRun, $threadNumber) { diff --git a/lib/Command/RegisterServiceCommand.php b/lib/Command/RegisterServiceCommand.php index ffe8e37..948484c 100644 --- a/lib/Command/RegisterServiceCommand.php +++ b/lib/Command/RegisterServiceCommand.php @@ -6,6 +6,8 @@ namespace Win32ServiceBundle\Command; +use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -14,49 +16,42 @@ use Win32Service\Model\ServiceIdentifier; use Win32Service\Model\ServiceInformations; use Win32Service\Service\ServiceAdminManager; +#[AsCommand(name: 'win32service:register')] class RegisterServiceCommand extends Command { - // the name of the command (the part after "bin/console") - protected static $defaultName = 'win32service:register'; - const ALL_SERVICE = 'All'; /** - * @var array + * @var array */ - private $config; + private array $config = []; - /** - * @var string - */ - private $projectRoot; + private ?string $projectRoot = null; protected function configure() { $this->setDescription("Register all service into Windows Service Manager"); - $this->addOption('service-name', 's', InputOption::VALUE_REQUIRED, 'Register the service with service_id. The value must be equal to the configuration.', self::ALL_SERVICE); + $this->addOption('service-name', 's', InputOption::VALUE_REQUIRED, + 'Register the service with service_id. The value must be equal to the configuration.', self::ALL_SERVICE); } - /** - * @param array $config - * - */ - public function defineBundleConfig(array $config) { + public function defineBundleConfig(array $config) + { $this->config = $config; } /** - * @param string $projectRoot * @required */ - public function defineProjectRoot(string $projectRoot) { + public function defineProjectRoot(string $projectRoot) + { $this->projectRoot = $projectRoot; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->config === null) { - throw new \Exception('The configuration of win32Service is not defined into command'); + if ($this->config === []) { + throw new Exception('The configuration of win32Service is not defined into command'); } $serviceToRegister = $input->getOption('service-name'); @@ -83,7 +78,7 @@ class RegisterServiceCommand extends Command if ($path === null) { $path = realpath($_SERVER['PHP_SELF']); //$path = sprintf('%s\\bin\\console', $this->projectRoot); - $args = sprintf('%s %s %d', ExecuteServiceCommand::getDefaultName(),$serviceThreadId, $i ); + $args = sprintf('%s %s %d', ExecuteServiceCommand::getDefaultName(), $serviceThreadId, $i); } $serviceInfos = new ServiceInformations( @@ -96,7 +91,7 @@ class RegisterServiceCommand extends Command $serviceInfos->defineIfStartIsDelayed($service['delayed_start']); - $recovery=$service['recovery']; + $recovery = $service['recovery']; $serviceInfos->defineRecoverySettings( $recovery['delay'], $recovery['enable'], @@ -112,14 +107,14 @@ class RegisterServiceCommand extends Command $serviceInfos->defineUserService($service['user']['account'], $service['user']['password']); } - if (count($service['dependencies']) >0) { + if (count($service['dependencies']) > 0) { $serviceInfos->defineDependencies($service['dependencies']); } try { $adminService->registerService($serviceInfos); $output->writeln('Registration success for ' . $serviceInfos->serviceId() . ''); - } catch (\Exception $e) { + } catch (Exception $e) { $output->writeln(' Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' '); } } @@ -127,9 +122,10 @@ class RegisterServiceCommand extends Command if ($nbService === 0) { $output->writeln('No service registred'); - return; + return self::FAILURE; } $output->writeln(sprintf('%d service(s) processed', $nbService)); + return self::SUCCESS; } } diff --git a/lib/Command/UnregisterServiceCommand.php b/lib/Command/UnregisterServiceCommand.php index 444b115..dbabd85 100644 --- a/lib/Command/UnregisterServiceCommand.php +++ b/lib/Command/UnregisterServiceCommand.php @@ -6,6 +6,8 @@ namespace Win32ServiceBundle\Command; +use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -13,37 +15,33 @@ use Symfony\Component\Console\Output\OutputInterface; use Win32Service\Model\ServiceIdentifier; use Win32Service\Service\ServiceAdminManager; +#[AsCommand(name: 'win32service:unregister')] class UnregisterServiceCommand extends Command { - // the name of the command (the part after "bin/console") - protected static $defaultName = 'win32service:unregister'; - const ALL_SERVICE = 'All'; /** - * @var array + * @var array */ - private $config; + private array $config = []; protected function configure() { $this->setDescription("Unregister all service into Windows Service Manager"); - $this->addOption('service-name', 's', InputOption::VALUE_REQUIRED, 'Register the service with service_id. The value must be equal to the configuration.', self::ALL_SERVICE); + $this->addOption('service-name', 's', InputOption::VALUE_REQUIRED, + 'Register the service with service_id. The value must be equal to the configuration.', self::ALL_SERVICE); } - /** - * @param array $config - * - */ - public function defineBundleConfig(array $config) { + public function defineBundleConfig(array $config) + { $this->config = $config; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->config === null) { - throw new \Exception('The configuration of win32Service is not defined into command'); + if ($this->config === []) { + throw new Exception('The configuration of win32Service is not defined into command'); } $serviceToRegister = $input->getOption('service-name'); @@ -67,7 +65,7 @@ class UnregisterServiceCommand extends Command try { $adminService->unregisterService($serviceInfos); $output->writeln('Unregistration success for ' . $serviceInfos->serviceId() . ''); - } catch (\Exception $e) { + } catch (Exception $e) { $output->writeln(' Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' '); } } @@ -75,9 +73,10 @@ class UnregisterServiceCommand extends Command if ($nbService === 0) { $output->writeln('No service unregistred'); - return; + return self::FAILURE; } $output->writeln(sprintf('%d service(s) processed', $nbService)); + return self::SUCCESS; } } diff --git a/lib/Logger/ThreadNumberEvent.php b/lib/Logger/ThreadNumberEvent.php index 4510963..856fbab 100644 --- a/lib/Logger/ThreadNumberEvent.php +++ b/lib/Logger/ThreadNumberEvent.php @@ -6,26 +6,16 @@ namespace Win32ServiceBundle\Logger; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class ThreadNumberEvent extends Event { public const NAME = 'win32service.thread_number'; - private $threadNumber; - - /** - * ThreadNumberEvent constructor. - * @param int $threadNumber - */ - public function __construct(int $threadNumber) + public function __construct(private int $threadNumber) { - $this->threadNumber = $threadNumber; } - /** - * @return int - */ public function getThreadNumber(): int { return $this->threadNumber; diff --git a/lib/Logger/ThreadNumberProcessor.php b/lib/Logger/ThreadNumberProcessor.php index 3ffa4d3..854814e 100644 --- a/lib/Logger/ThreadNumberProcessor.php +++ b/lib/Logger/ThreadNumberProcessor.php @@ -7,13 +7,13 @@ namespace Win32ServiceBundle\Logger; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; class ThreadNumberProcessor { - private $threadNumber; + private ?int $threadNumber = null; - public function setThreadNumber(Event $evt) { + public function setThreadNumber(Event $evt): void { if (!$evt instanceof ThreadNumberEvent) { return; } @@ -21,7 +21,7 @@ class ThreadNumberProcessor } - public function __invoke(array $record) + public function __invoke(array $record): array { $record['extra']['threadNumber'] = $this->threadNumber; return $record; diff --git a/lib/Service/RunnerManager.php b/lib/Service/RunnerManager.php index 838f1db..797cccf 100644 --- a/lib/Service/RunnerManager.php +++ b/lib/Service/RunnerManager.php @@ -25,7 +25,6 @@ class RunnerManager } /** - * @param string $alias * @return RunnerServiceInterface|null */ public function getRunner(string $alias) { diff --git a/lib/Win32ServiceBundle.php b/lib/Win32ServiceBundle.php index b547993..94d64f0 100644 --- a/lib/Win32ServiceBundle.php +++ b/lib/Win32ServiceBundle.php @@ -6,10 +6,11 @@ namespace Win32ServiceBundle; +use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; use Win32ServiceBundle\DependencyInjection\TagRunnerCompilerPass; -class Win32ServiceBundle extends \Symfony\Component\HttpKernel\Bundle\Bundle +class Win32ServiceBundle extends Bundle { public function build(ContainerBuilder $container) { diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..0b30c26 --- /dev/null +++ b/rector.php @@ -0,0 +1,46 @@ +phpVersion(phpVersion: PhpVersion::PHP_80); + $rectorConfig->importNames(); + $rectorConfig->importShortClasses(); + $rectorConfig->parallel(); +// $rectorConfig->symfonyContainerPhp(filePath: __DIR__ . 'var/cache/dev/App_KernelDevDebugContainer.php'); + + $rectorConfig->autoloadPaths(autoloadPaths: [ + __DIR__ . '/vendor/autoload.php', + ]); + + $rectorConfig->paths(paths: [ + __DIR__ . '/lib', + ]); + + $rectorConfig->skip(criteria: [ + __DIR__ . '/vendor', + ]); + + $rectorConfig->sets(sets: [ +// SetList::CODE_QUALITY, +// SetList::CODING_STYLE, +// SetList::DEAD_CODE, +// SetList::EARLY_RETURN, + SetList::PHP_80, +// SetList::PSR_4, +// SetList::PRIVATIZATION, +// SetList::TYPE_DECLARATION, +// SetList::TYPE_DECLARATION_STRICT, +// SymfonySetList::SYMFONY_STRICT, +// SymfonySetList::SYMFONY_44, +// SymfonySetList::SYMFONY_CODE_QUALITY, +// SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, +#SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES, + ]); + +};