diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 620ece4f..3fa0e966 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,5 +1,6 @@ tools: - external_code_coverage: true + external_code_coverage: + timeout: 600 checks: php: code_rating: true diff --git a/composer.json b/composer.json index ad597380..ed431a24 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "doctrine/data-fixtures": "^1.3", "filp/whoops": "^2.0", "infection/infection": "^0.12.2", - "phpstan/phpstan": "^0.10.8", + "phpstan/phpstan": "^0.11.2", "phpunit/phpcov": "^6.0@dev || ^5.0", "phpunit/phpunit": "^8.0 || ^7.5", "roave/security-advisories": "dev-master", diff --git a/module/CLI/src/Command/Api/DisableKeyCommand.php b/module/CLI/src/Command/Api/DisableKeyCommand.php index e8472d4c..4d945c48 100644 --- a/module/CLI/src/Command/Api/DisableKeyCommand.php +++ b/module/CLI/src/Command/Api/DisableKeyCommand.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Api; use InvalidArgumentException; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -32,7 +33,7 @@ class DisableKeyCommand extends Command ->addArgument('apiKey', InputArgument::REQUIRED, 'The API key to disable'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $apiKey = $input->getArgument('apiKey'); $io = new SymfonyStyle($input, $output); @@ -40,8 +41,10 @@ class DisableKeyCommand extends Command try { $this->apiKeyService->disable($apiKey); $io->success(sprintf('API key "%s" properly disabled', $apiKey)); + return ExitCodes::EXIT_SUCCESS; } catch (InvalidArgumentException $e) { $io->error(sprintf('API key "%s" does not exist.', $apiKey)); + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Api/GenerateKeyCommand.php b/module/CLI/src/Command/Api/GenerateKeyCommand.php index 62aeb657..bba8ace6 100644 --- a/module/CLI/src/Command/Api/GenerateKeyCommand.php +++ b/module/CLI/src/Command/Api/GenerateKeyCommand.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Api; use Cake\Chronos\Chronos; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -38,11 +39,12 @@ class GenerateKeyCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $expirationDate = $input->getOption('expirationDate'); $apiKey = $this->apiKeyService->create(isset($expirationDate) ? Chronos::parse($expirationDate) : null); (new SymfonyStyle($input, $output))->success(sprintf('Generated API key: "%s"', $apiKey)); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Api/ListKeysCommand.php b/module/CLI/src/Command/Api/ListKeysCommand.php index 42c8fb73..710c22c8 100644 --- a/module/CLI/src/Command/Api/ListKeysCommand.php +++ b/module/CLI/src/Command/Api/ListKeysCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Api; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Console\ShlinkTable; use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; @@ -44,7 +45,7 @@ class ListKeysCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $enabledOnly = $input->getOption('enabledOnly'); @@ -66,6 +67,7 @@ class ListKeysCommand extends Command ! $enabledOnly ? 'Is enabled' : null, 'Expiration date', ]), $rows); + return ExitCodes::EXIT_SUCCESS; } private function determineMessagePattern(ApiKey $apiKey): string diff --git a/module/CLI/src/Command/Config/GenerateCharsetCommand.php b/module/CLI/src/Command/Config/GenerateCharsetCommand.php index c7f174cb..0fab6336 100644 --- a/module/CLI/src/Command/Config/GenerateCharsetCommand.php +++ b/module/CLI/src/Command/Config/GenerateCharsetCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Config; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -28,9 +29,10 @@ class GenerateCharsetCommand extends Command ->setHelp('This command is deprecated. Better leave shlink generate the charset.'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $charSet = str_shuffle(UrlShortenerOptions::DEFAULT_CHARS); (new SymfonyStyle($input, $output))->success(sprintf('Character set: "%s"', $charSet)); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Config/GenerateSecretCommand.php b/module/CLI/src/Command/Config/GenerateSecretCommand.php index 23d559b5..8a194bd7 100644 --- a/module/CLI/src/Command/Config/GenerateSecretCommand.php +++ b/module/CLI/src/Command/Config/GenerateSecretCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Config; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Util\StringUtilsTrait; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -27,9 +28,10 @@ class GenerateSecretCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $secret = $this->generateRandomString(32); (new SymfonyStyle($input, $output))->success(sprintf('Secret key: "%s"', $secret)); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php index 2d6d563f..0bc2a5fb 100644 --- a/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Exception; use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface; use Symfony\Component\Console\Command\Command; @@ -43,7 +44,7 @@ class DeleteShortUrlCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $shortCode = $input->getArgument('shortCode'); @@ -51,14 +52,16 @@ class DeleteShortUrlCommand extends Command try { $this->runDelete($io, $shortCode, $ignoreThreshold); + return ExitCodes::EXIT_SUCCESS; } catch (Exception\InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); + return ExitCodes::EXIT_FAILURE; } catch (Exception\DeleteShortUrlException $e) { - $this->retry($io, $shortCode, $e); + return $this->retry($io, $shortCode, $e); } } - private function retry(SymfonyStyle $io, string $shortCode, Exception\DeleteShortUrlException $e): void + private function retry(SymfonyStyle $io, string $shortCode, Exception\DeleteShortUrlException $e): int { $warningMsg = sprintf( 'It was not possible to delete the short URL with short code "%s" because it has more than %s visits.', @@ -73,6 +76,8 @@ class DeleteShortUrlCommand extends Command } else { $io->warning('Short URL was not deleted.'); } + + return $forceDelete ? ExitCodes::EXIT_SUCCESS : ExitCodes::EXIT_WARNING; } private function runDelete(SymfonyStyle $io, string $shortCode, bool $ignoreThreshold): void diff --git a/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php b/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php index 8d600010..0a769553 100644 --- a/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php +++ b/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Exception\PreviewGenerationException; use Shlinkio\Shlink\Common\Service\PreviewGeneratorInterface; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; @@ -39,7 +40,7 @@ class GeneratePreviewCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $page = 1; do { @@ -52,6 +53,7 @@ class GeneratePreviewCommand extends Command } while ($page <= $shortUrls->count()); (new SymfonyStyle($input, $output))->success('Finished processing all URLs'); + return ExitCodes::EXIT_SUCCESS; } private function processUrl($url, OutputInterface $output): void diff --git a/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php index fcb4d305..192c7049 100644 --- a/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; use Cake\Chronos\Chronos; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Exception\InvalidUrlException; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; use Shlinkio\Shlink\Core\Model\ShortUrlMeta; @@ -102,13 +103,13 @@ class GenerateShortUrlCommand extends Command } } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $longUrl = $input->getArgument('longUrl'); if (empty($longUrl)) { $io->error('A URL was not provided!'); - return; + return ExitCodes::EXIT_FAILURE; } $explodeWithComma = curry('explode')(','); @@ -134,12 +135,15 @@ class GenerateShortUrlCommand extends Command sprintf('Processed long URL: %s', $longUrl), sprintf('Generated short URL: %s', $shortUrl), ]); + return ExitCodes::EXIT_SUCCESS; } catch (InvalidUrlException $e) { $io->error(sprintf('Provided URL "%s" is invalid. Try with a different one.', $longUrl)); + return ExitCodes::EXIT_FAILURE; } catch (NonUniqueSlugException $e) { $io->error( sprintf('Provided slug "%s" is already in use by another URL. Try with a different one.', $customSlug) ); + return ExitCodes::EXIT_FAILURE; } } diff --git a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php index 7c2989db..85258c16 100644 --- a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php +++ b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; use Cake\Chronos\Chronos; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Console\ShlinkTable; use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Core\Entity\Visit; @@ -68,7 +69,7 @@ class GetVisitsCommand extends Command } } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $shortCode = $input->getArgument('shortCode'); $startDate = $this->getDateOption($input, 'startDate'); @@ -83,6 +84,7 @@ class GetVisitsCommand extends Command return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']); }, $visits); ShlinkTable::fromOutput($output)->render(['Referer', 'Date', 'User agent', 'Country'], $rows); + return ExitCodes::EXIT_SUCCESS; } private function getDateOption(InputInterface $input, $key) diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php index a5e83c85..47afc208 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Console\ShlinkTable; use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter; use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait; @@ -74,7 +75,7 @@ class ListShortUrlsCommand extends Command ->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $page = (int) $input->getOption('page'); @@ -95,6 +96,7 @@ class ListShortUrlsCommand extends Command $io->newLine(); $io->success('Short URLs properly listed'); + return ExitCodes::EXIT_SUCCESS; } private function renderPage( diff --git a/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php b/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php index ca921ff4..e2d72d44 100644 --- a/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException; use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException; use Shlinkio\Shlink\Core\Service\UrlShortenerInterface; @@ -50,7 +51,7 @@ class ResolveUrlCommand extends Command } } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $shortCode = $input->getArgument('shortCode'); @@ -58,10 +59,13 @@ class ResolveUrlCommand extends Command try { $url = $this->urlShortener->shortCodeToUrl($shortCode); $output->writeln(sprintf('Long URL: %s', $url->getLongUrl())); + return ExitCodes::EXIT_SUCCESS; } catch (InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" has an invalid format.', $shortCode)); + return ExitCodes::EXIT_FAILURE; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Tag/CreateTagCommand.php b/module/CLI/src/Command/Tag/CreateTagCommand.php index b15746a5..371337d7 100644 --- a/module/CLI/src/Command/Tag/CreateTagCommand.php +++ b/module/CLI/src/Command/Tag/CreateTagCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Tag; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Service\Tag\TagServiceInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -36,17 +37,18 @@ class CreateTagCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $tagNames = $input->getOption('name'); if (empty($tagNames)) { $io->warning('You have to provide at least one tag name'); - return; + return ExitCodes::EXIT_WARNING; } $this->tagService->createTags($tagNames); $io->success('Tags properly created'); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Tag/DeleteTagsCommand.php b/module/CLI/src/Command/Tag/DeleteTagsCommand.php index caac09bc..02f542fd 100644 --- a/module/CLI/src/Command/Tag/DeleteTagsCommand.php +++ b/module/CLI/src/Command/Tag/DeleteTagsCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Tag; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Service\Tag\TagServiceInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -36,17 +37,18 @@ class DeleteTagsCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $tagNames = $input->getOption('name'); if (empty($tagNames)) { $io->warning('You have to provide at least one tag name'); - return; + return ExitCodes::EXIT_WARNING; } $this->tagService->deleteTags($tagNames); $io->success('Tags properly deleted'); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Tag/ListTagsCommand.php b/module/CLI/src/Command/Tag/ListTagsCommand.php index 4d2e05bb..02a7a831 100644 --- a/module/CLI/src/Command/Tag/ListTagsCommand.php +++ b/module/CLI/src/Command/Tag/ListTagsCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Tag; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Console\ShlinkTable; use Shlinkio\Shlink\Core\Entity\Tag; use Shlinkio\Shlink\Core\Service\Tag\TagServiceInterface; @@ -31,9 +32,10 @@ class ListTagsCommand extends Command ->setDescription('Lists existing tags.'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { ShlinkTable::fromOutput($output)->render(['Name'], $this->getTagsRows()); + return ExitCodes::EXIT_SUCCESS; } private function getTagsRows(): array diff --git a/module/CLI/src/Command/Tag/RenameTagCommand.php b/module/CLI/src/Command/Tag/RenameTagCommand.php index d942cd98..2875761d 100644 --- a/module/CLI/src/Command/Tag/RenameTagCommand.php +++ b/module/CLI/src/Command/Tag/RenameTagCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Tag; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException; use Shlinkio\Shlink\Core\Service\Tag\TagServiceInterface; use Symfony\Component\Console\Command\Command; @@ -34,7 +35,7 @@ class RenameTagCommand extends Command ->addArgument('newName', InputArgument::REQUIRED, 'New name of the tag.'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $oldName = $input->getArgument('oldName'); @@ -43,8 +44,10 @@ class RenameTagCommand extends Command try { $this->tagService->renameTag($oldName, $newName); $io->success('Tag properly renamed.'); + return ExitCodes::EXIT_SUCCESS; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('A tag with name "%s" was not found', $oldName)); + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Visit/ProcessVisitsCommand.php b/module/CLI/src/Command/Visit/ProcessVisitsCommand.php index cc1e2687..848a540c 100644 --- a/module/CLI/src/Command/Visit/ProcessVisitsCommand.php +++ b/module/CLI/src/Command/Visit/ProcessVisitsCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Visit; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Exception\WrongIpException; use Shlinkio\Shlink\Common\IpGeolocation\IpLocationResolverInterface; use Shlinkio\Shlink\Common\Util\IpAddress; @@ -48,7 +49,7 @@ class ProcessVisitsCommand extends Command ->setDescription('Processes visits where location is not set yet'); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $this->output = $output; $io = new SymfonyStyle($input, $output); @@ -56,7 +57,7 @@ class ProcessVisitsCommand extends Command $lock = $this->locker->createLock(self::NAME); if (! $lock->acquire()) { $io->warning(sprintf('There is already an instance of the "%s" command in execution', self::NAME)); - return; + return ExitCodes::EXIT_WARNING; } try { @@ -70,6 +71,7 @@ class ProcessVisitsCommand extends Command $io->success('Finished processing all IPs'); } finally { $lock->release(); + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Visit/UpdateDbCommand.php b/module/CLI/src/Command/Visit/UpdateDbCommand.php index 87eb6022..35389260 100644 --- a/module/CLI/src/Command/Visit/UpdateDbCommand.php +++ b/module/CLI/src/Command/Visit/UpdateDbCommand.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Visit; +use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\Common\Exception\RuntimeException; use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface; use Symfony\Component\Console\Command\Command; @@ -35,7 +36,7 @@ class UpdateDbCommand extends Command ); } - protected function execute(InputInterface $input, OutputInterface $output): void + protected function execute(InputInterface $input, OutputInterface $output): ?int { $io = new SymfonyStyle($input, $output); $progressBar = new ProgressBar($output); @@ -51,6 +52,7 @@ class UpdateDbCommand extends Command $io->writeln(''); $io->success('GeoLite2 database properly updated'); + return ExitCodes::EXIT_SUCCESS; } catch (RuntimeException $e) { $progressBar->finish(); $io->writeln(''); @@ -59,6 +61,7 @@ class UpdateDbCommand extends Command if ($io->isVerbose()) { $this->getApplication()->renderException($e, $output); } + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Util/ExitCodes.php b/module/CLI/src/Util/ExitCodes.php new file mode 100644 index 00000000..f62e14fc --- /dev/null +++ b/module/CLI/src/Util/ExitCodes.php @@ -0,0 +1,11 @@ +getDateCreated(); $longUrl = $value->getLongUrl(); $shortCode = $value->getShortCode(); @@ -33,7 +32,7 @@ class ShortUrlDataTransformer implements DataTransformerInterface 'shortCode' => $shortCode, 'shortUrl' => $this->buildShortUrl($this->domainConfig, $shortCode), 'longUrl' => $longUrl, - 'dateCreated' => $dateCreated !== null ? $dateCreated->toAtomString() : null, + 'dateCreated' => $value->getDateCreated()->toAtomString(), 'visitsCount' => $value->getVisitsCount(), 'tags' => invoke($value->getTags(), '__toString'),