4 Commits

Author SHA1 Message Date
Jean-Baptiste Nahan
96910b930a Merge pull request #8 from win32service/master
Create FUNDING.yml
2022-09-29 09:19:50 +02:00
macintoshplus
fb2a92b389 allow dev branche for library 2022-09-08 12:03:57 +02:00
macintoshplus
18a0eea6d5 upgrade code 2022-09-08 10:09:34 +02:00
macintoshplus
ff8392ae16 update dependencies 2022-09-08 09:31:52 +02:00
13 changed files with 185 additions and 109 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
/vendor
/composer.lock
/.php-cs-fixer.cache

53
.php-cs-fixer.dist.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
$finder = PhpCsFixer\Finder::create()
->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;

1
.php-version Normal file
View File

@@ -0,0 +1 @@
8.0

View File

@@ -25,14 +25,15 @@
},
"minimum-stability": "beta",
"require": {
"php": "^7.1.0 <8.0.0",
"win32service/service-library": "^0.1.0",
"symfony/http-kernel": "^4.0||^5.0",
"symfony/console": "^4.0||^5.0",
"symfony/config": "^4.0||^5.0",
"symfony/dependency-injection": "^4.0||^5.0"
"php": "^8.0",
"win32service/service-library": "^1.0||1.x-dev",
"symfony/http-kernel": "^6.0",
"symfony/console": "^6.0",
"symfony/config": "^6.0",
"symfony/dependency-injection": "^6.0",
"symfony/event-dispatcher": "^6.0"
},
"require-dev": {
"atoum/atoum": "^3.3"
"rector/rector": "^0.14.2"
}
}

View File

@@ -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<string, mixed>
*/
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 <info>' . $serviceInfos->serviceId() . '</info> : OK');
} catch (\Exception $e) {
} catch (Exception $e) {
$output->writeln('<error> Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' </error>');
}
}
@@ -110,9 +108,10 @@ class ActionServiceCommand extends Command
if ($nbService === 0) {
$output->writeln('<info>No signal sent</info>');
return;
return self::FAILURE;
}
$output->writeln(sprintf('Signal sent to <info>%d</info> service(s)', $nbService));
return self::SUCCESS;
}
}

View File

@@ -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<string, mixed>
*/
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) {

View File

@@ -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<string, mixed>
*/
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 <info>' . $serviceInfos->serviceId() . '</info>');
} catch (\Exception $e) {
} catch (Exception $e) {
$output->writeln('<error> Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' </error>');
}
}
@@ -127,9 +122,10 @@ class RegisterServiceCommand extends Command
if ($nbService === 0) {
$output->writeln('<info>No service registred</info>');
return;
return self::FAILURE;
}
$output->writeln(sprintf('<info>%d</info> service(s) processed', $nbService));
return self::SUCCESS;
}
}

View File

@@ -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<string, mixed>
*/
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 <info>' . $serviceInfos->serviceId() . '</info>');
} catch (\Exception $e) {
} catch (Exception $e) {
$output->writeln('<error> Error : ' . $serviceInfos->serviceId() . '(' . $e->getCode() . ') ' . $e->getMessage() . ' </error>');
}
}
@@ -75,9 +73,10 @@ class UnregisterServiceCommand extends Command
if ($nbService === 0) {
$output->writeln('<info>No service unregistred</info>');
return;
return self::FAILURE;
}
$output->writeln(sprintf('<info>%d</info> service(s) processed', $nbService));
return self::SUCCESS;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -25,7 +25,6 @@ class RunnerManager
}
/**
* @param string $alias
* @return RunnerServiceInterface|null
*/
public function getRunner(string $alias) {

View File

@@ -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)
{

46
rector.php Normal file
View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\SymfonySetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->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,
]);
};