From eab56591636e85b2324e397838f382ad7f5f9b71 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 16 Feb 2019 22:15:55 +0100 Subject: [PATCH 1/3] Added status codes returned by CLI commands --- module/CLI/src/Command/Api/DisableKeyCommand.php | 4 +++- module/CLI/src/Command/Api/GenerateKeyCommand.php | 3 ++- module/CLI/src/Command/Api/ListKeysCommand.php | 3 ++- .../CLI/src/Command/Config/GenerateCharsetCommand.php | 3 ++- .../CLI/src/Command/Config/GenerateSecretCommand.php | 3 ++- .../CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php | 10 +++++++--- .../src/Command/ShortUrl/GeneratePreviewCommand.php | 3 ++- .../src/Command/ShortUrl/GenerateShortUrlCommand.php | 7 +++++-- module/CLI/src/Command/ShortUrl/GetVisitsCommand.php | 3 ++- .../CLI/src/Command/ShortUrl/ListShortUrlsCommand.php | 3 ++- module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php | 5 ++++- module/CLI/src/Command/Tag/CreateTagCommand.php | 5 +++-- module/CLI/src/Command/Tag/DeleteTagsCommand.php | 5 +++-- module/CLI/src/Command/Tag/ListTagsCommand.php | 3 ++- module/CLI/src/Command/Tag/RenameTagCommand.php | 4 +++- module/CLI/src/Command/Visit/ProcessVisitsCommand.php | 5 +++-- module/CLI/src/Command/Visit/UpdateDbCommand.php | 4 +++- .../Core/src/Transformer/ShortUrlDataTransformer.php | 3 +-- 18 files changed, 51 insertions(+), 25 deletions(-) diff --git a/module/CLI/src/Command/Api/DisableKeyCommand.php b/module/CLI/src/Command/Api/DisableKeyCommand.php index e8472d4c..e869d985 100644 --- a/module/CLI/src/Command/Api/DisableKeyCommand.php +++ b/module/CLI/src/Command/Api/DisableKeyCommand.php @@ -32,7 +32,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 +40,10 @@ class DisableKeyCommand extends Command try { $this->apiKeyService->disable($apiKey); $io->success(sprintf('API key "%s" properly disabled', $apiKey)); + return 0; } catch (InvalidArgumentException $e) { $io->error(sprintf('API key "%s" does not exist.', $apiKey)); + return -1; } } } diff --git a/module/CLI/src/Command/Api/GenerateKeyCommand.php b/module/CLI/src/Command/Api/GenerateKeyCommand.php index 62aeb657..ae55060a 100644 --- a/module/CLI/src/Command/Api/GenerateKeyCommand.php +++ b/module/CLI/src/Command/Api/GenerateKeyCommand.php @@ -38,11 +38,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 0; } } diff --git a/module/CLI/src/Command/Api/ListKeysCommand.php b/module/CLI/src/Command/Api/ListKeysCommand.php index 42c8fb73..7acdcc03 100644 --- a/module/CLI/src/Command/Api/ListKeysCommand.php +++ b/module/CLI/src/Command/Api/ListKeysCommand.php @@ -44,7 +44,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 +66,7 @@ class ListKeysCommand extends Command ! $enabledOnly ? 'Is enabled' : null, 'Expiration date', ]), $rows); + return 0; } 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..01a95036 100644 --- a/module/CLI/src/Command/Config/GenerateCharsetCommand.php +++ b/module/CLI/src/Command/Config/GenerateCharsetCommand.php @@ -28,9 +28,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 0; } } diff --git a/module/CLI/src/Command/Config/GenerateSecretCommand.php b/module/CLI/src/Command/Config/GenerateSecretCommand.php index 23d559b5..73cc98e1 100644 --- a/module/CLI/src/Command/Config/GenerateSecretCommand.php +++ b/module/CLI/src/Command/Config/GenerateSecretCommand.php @@ -27,9 +27,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 0; } } diff --git a/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php index 2d6d563f..e60fa6d8 100644 --- a/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php @@ -43,7 +43,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 +51,16 @@ class DeleteShortUrlCommand extends Command try { $this->runDelete($io, $shortCode, $ignoreThreshold); + return 0; } catch (Exception\InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); + return -1; } 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 +75,8 @@ class DeleteShortUrlCommand extends Command } else { $io->warning('Short URL was not deleted.'); } + + return $forceDelete ? 0 : 1; } 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..4abaa62b 100644 --- a/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php +++ b/module/CLI/src/Command/ShortUrl/GeneratePreviewCommand.php @@ -39,7 +39,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 +52,7 @@ class GeneratePreviewCommand extends Command } while ($page <= $shortUrls->count()); (new SymfonyStyle($input, $output))->success('Finished processing all URLs'); + return 0; } 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..81c577a5 100644 --- a/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php @@ -102,13 +102,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 -1; } $explodeWithComma = curry('explode')(','); @@ -134,12 +134,15 @@ class GenerateShortUrlCommand extends Command sprintf('Processed long URL: %s', $longUrl), sprintf('Generated short URL: %s', $shortUrl), ]); + return 0; } catch (InvalidUrlException $e) { $io->error(sprintf('Provided URL "%s" is invalid. Try with a different one.', $longUrl)); + return -1; } catch (NonUniqueSlugException $e) { $io->error( sprintf('Provided slug "%s" is already in use by another URL. Try with a different one.', $customSlug) ); + return -1; } } diff --git a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php index 7c2989db..d4aedf52 100644 --- a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php +++ b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php @@ -68,7 +68,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 +83,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 0; } 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..6a0884a8 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -74,7 +74,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 +95,7 @@ class ListShortUrlsCommand extends Command $io->newLine(); $io->success('Short URLs properly listed'); + return 0; } private function renderPage( diff --git a/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php b/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php index ca921ff4..4fd0b1fb 100644 --- a/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php @@ -50,7 +50,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 +58,13 @@ class ResolveUrlCommand extends Command try { $url = $this->urlShortener->shortCodeToUrl($shortCode); $output->writeln(sprintf('Long URL: %s', $url->getLongUrl())); + return 0; } catch (InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" has an invalid format.', $shortCode)); + return -1; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); + return -1; } } } diff --git a/module/CLI/src/Command/Tag/CreateTagCommand.php b/module/CLI/src/Command/Tag/CreateTagCommand.php index b15746a5..57323d69 100644 --- a/module/CLI/src/Command/Tag/CreateTagCommand.php +++ b/module/CLI/src/Command/Tag/CreateTagCommand.php @@ -36,17 +36,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 1; } $this->tagService->createTags($tagNames); $io->success('Tags properly created'); + return 0; } } diff --git a/module/CLI/src/Command/Tag/DeleteTagsCommand.php b/module/CLI/src/Command/Tag/DeleteTagsCommand.php index caac09bc..327c21e3 100644 --- a/module/CLI/src/Command/Tag/DeleteTagsCommand.php +++ b/module/CLI/src/Command/Tag/DeleteTagsCommand.php @@ -36,17 +36,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 1; } $this->tagService->deleteTags($tagNames); $io->success('Tags properly deleted'); + return 0; } } diff --git a/module/CLI/src/Command/Tag/ListTagsCommand.php b/module/CLI/src/Command/Tag/ListTagsCommand.php index 4d2e05bb..0866445c 100644 --- a/module/CLI/src/Command/Tag/ListTagsCommand.php +++ b/module/CLI/src/Command/Tag/ListTagsCommand.php @@ -31,9 +31,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 0; } private function getTagsRows(): array diff --git a/module/CLI/src/Command/Tag/RenameTagCommand.php b/module/CLI/src/Command/Tag/RenameTagCommand.php index d942cd98..69cf0a07 100644 --- a/module/CLI/src/Command/Tag/RenameTagCommand.php +++ b/module/CLI/src/Command/Tag/RenameTagCommand.php @@ -34,7 +34,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 +43,10 @@ class RenameTagCommand extends Command try { $this->tagService->renameTag($oldName, $newName); $io->success('Tag properly renamed.'); + return 0; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('A tag with name "%s" was not found', $oldName)); + return -1; } } } diff --git a/module/CLI/src/Command/Visit/ProcessVisitsCommand.php b/module/CLI/src/Command/Visit/ProcessVisitsCommand.php index cc1e2687..7c51c020 100644 --- a/module/CLI/src/Command/Visit/ProcessVisitsCommand.php +++ b/module/CLI/src/Command/Visit/ProcessVisitsCommand.php @@ -48,7 +48,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 +56,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 1; } try { @@ -70,6 +70,7 @@ class ProcessVisitsCommand extends Command $io->success('Finished processing all IPs'); } finally { $lock->release(); + return 0; } } diff --git a/module/CLI/src/Command/Visit/UpdateDbCommand.php b/module/CLI/src/Command/Visit/UpdateDbCommand.php index 87eb6022..b4554e66 100644 --- a/module/CLI/src/Command/Visit/UpdateDbCommand.php +++ b/module/CLI/src/Command/Visit/UpdateDbCommand.php @@ -35,7 +35,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 +51,7 @@ class UpdateDbCommand extends Command $io->writeln(''); $io->success('GeoLite2 database properly updated'); + return 0; } catch (RuntimeException $e) { $progressBar->finish(); $io->writeln(''); @@ -59,6 +60,7 @@ class UpdateDbCommand extends Command if ($io->isVerbose()) { $this->getApplication()->renderException($e, $output); } + return -1; } } } diff --git a/module/Core/src/Transformer/ShortUrlDataTransformer.php b/module/Core/src/Transformer/ShortUrlDataTransformer.php index 363e533a..91d64ea7 100644 --- a/module/Core/src/Transformer/ShortUrlDataTransformer.php +++ b/module/Core/src/Transformer/ShortUrlDataTransformer.php @@ -25,7 +25,6 @@ class ShortUrlDataTransformer implements DataTransformerInterface */ public function transform($value): array { - $dateCreated = $value->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'), From 580050cb7d624838fd6eddaec22739110d4dbfc7 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Feb 2019 10:06:27 +0100 Subject: [PATCH 2/3] Updated to phpstan 0.11 --- composer.json | 2 +- module/CLI/src/Command/Api/DisableKeyCommand.php | 5 +++-- module/CLI/src/Command/Api/GenerateKeyCommand.php | 3 ++- module/CLI/src/Command/Api/ListKeysCommand.php | 3 ++- .../CLI/src/Command/Config/GenerateCharsetCommand.php | 3 ++- .../CLI/src/Command/Config/GenerateSecretCommand.php | 3 ++- .../src/Command/ShortUrl/DeleteShortUrlCommand.php | 7 ++++--- .../src/Command/ShortUrl/GeneratePreviewCommand.php | 3 ++- .../src/Command/ShortUrl/GenerateShortUrlCommand.php | 9 +++++---- module/CLI/src/Command/ShortUrl/GetVisitsCommand.php | 3 ++- .../CLI/src/Command/ShortUrl/ListShortUrlsCommand.php | 3 ++- module/CLI/src/Command/ShortUrl/ResolveUrlCommand.php | 7 ++++--- module/CLI/src/Command/Tag/CreateTagCommand.php | 5 +++-- module/CLI/src/Command/Tag/DeleteTagsCommand.php | 5 +++-- module/CLI/src/Command/Tag/ListTagsCommand.php | 3 ++- module/CLI/src/Command/Tag/RenameTagCommand.php | 5 +++-- module/CLI/src/Command/Visit/ProcessVisitsCommand.php | 5 +++-- module/CLI/src/Command/Visit/UpdateDbCommand.php | 5 +++-- module/CLI/src/Util/ExitCodes.php | 11 +++++++++++ 19 files changed, 59 insertions(+), 31 deletions(-) create mode 100644 module/CLI/src/Util/ExitCodes.php 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 e869d985..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; @@ -40,10 +41,10 @@ class DisableKeyCommand extends Command try { $this->apiKeyService->disable($apiKey); $io->success(sprintf('API key "%s" properly disabled', $apiKey)); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (InvalidArgumentException $e) { $io->error(sprintf('API key "%s" does not exist.', $apiKey)); - return -1; + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Api/GenerateKeyCommand.php b/module/CLI/src/Command/Api/GenerateKeyCommand.php index ae55060a..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; @@ -44,6 +45,6 @@ class GenerateKeyCommand extends Command $apiKey = $this->apiKeyService->create(isset($expirationDate) ? Chronos::parse($expirationDate) : null); (new SymfonyStyle($input, $output))->success(sprintf('Generated API key: "%s"', $apiKey)); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Api/ListKeysCommand.php b/module/CLI/src/Command/Api/ListKeysCommand.php index 7acdcc03..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; @@ -66,7 +67,7 @@ class ListKeysCommand extends Command ! $enabledOnly ? 'Is enabled' : null, 'Expiration date', ]), $rows); - return 0; + 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 01a95036..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; @@ -32,6 +33,6 @@ class GenerateCharsetCommand extends Command { $charSet = str_shuffle(UrlShortenerOptions::DEFAULT_CHARS); (new SymfonyStyle($input, $output))->success(sprintf('Character set: "%s"', $charSet)); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Config/GenerateSecretCommand.php b/module/CLI/src/Command/Config/GenerateSecretCommand.php index 73cc98e1..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; @@ -31,6 +32,6 @@ class GenerateSecretCommand extends Command { $secret = $this->generateRandomString(32); (new SymfonyStyle($input, $output))->success(sprintf('Secret key: "%s"', $secret)); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/DeleteShortUrlCommand.php index e60fa6d8..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; @@ -51,10 +52,10 @@ class DeleteShortUrlCommand extends Command try { $this->runDelete($io, $shortCode, $ignoreThreshold); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (Exception\InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); - return -1; + return ExitCodes::EXIT_FAILURE; } catch (Exception\DeleteShortUrlException $e) { return $this->retry($io, $shortCode, $e); } @@ -76,7 +77,7 @@ class DeleteShortUrlCommand extends Command $io->warning('Short URL was not deleted.'); } - return $forceDelete ? 0 : 1; + 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 4abaa62b..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; @@ -52,7 +53,7 @@ class GeneratePreviewCommand extends Command } while ($page <= $shortUrls->count()); (new SymfonyStyle($input, $output))->success('Finished processing all URLs'); - return 0; + 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 81c577a5..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; @@ -108,7 +109,7 @@ class GenerateShortUrlCommand extends Command $longUrl = $input->getArgument('longUrl'); if (empty($longUrl)) { $io->error('A URL was not provided!'); - return -1; + return ExitCodes::EXIT_FAILURE; } $explodeWithComma = curry('explode')(','); @@ -134,15 +135,15 @@ class GenerateShortUrlCommand extends Command sprintf('Processed long URL: %s', $longUrl), sprintf('Generated short URL: %s', $shortUrl), ]); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (InvalidUrlException $e) { $io->error(sprintf('Provided URL "%s" is invalid. Try with a different one.', $longUrl)); - return -1; + 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 -1; + return ExitCodes::EXIT_FAILURE; } } diff --git a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php index d4aedf52..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; @@ -83,7 +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 0; + 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 6a0884a8..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; @@ -95,7 +96,7 @@ class ListShortUrlsCommand extends Command $io->newLine(); $io->success('Short URLs properly listed'); - return 0; + 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 4fd0b1fb..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; @@ -58,13 +59,13 @@ class ResolveUrlCommand extends Command try { $url = $this->urlShortener->shortCodeToUrl($shortCode); $output->writeln(sprintf('Long URL: %s', $url->getLongUrl())); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (InvalidShortCodeException $e) { $io->error(sprintf('Provided short code "%s" has an invalid format.', $shortCode)); - return -1; + return ExitCodes::EXIT_FAILURE; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('Provided short code "%s" could not be found.', $shortCode)); - return -1; + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Tag/CreateTagCommand.php b/module/CLI/src/Command/Tag/CreateTagCommand.php index 57323d69..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; @@ -43,11 +44,11 @@ class CreateTagCommand extends Command if (empty($tagNames)) { $io->warning('You have to provide at least one tag name'); - return 1; + return ExitCodes::EXIT_WARNING; } $this->tagService->createTags($tagNames); $io->success('Tags properly created'); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Tag/DeleteTagsCommand.php b/module/CLI/src/Command/Tag/DeleteTagsCommand.php index 327c21e3..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; @@ -43,11 +44,11 @@ class DeleteTagsCommand extends Command if (empty($tagNames)) { $io->warning('You have to provide at least one tag name'); - return 1; + return ExitCodes::EXIT_WARNING; } $this->tagService->deleteTags($tagNames); $io->success('Tags properly deleted'); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Tag/ListTagsCommand.php b/module/CLI/src/Command/Tag/ListTagsCommand.php index 0866445c..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; @@ -34,7 +35,7 @@ class ListTagsCommand extends Command protected function execute(InputInterface $input, OutputInterface $output): ?int { ShlinkTable::fromOutput($output)->render(['Name'], $this->getTagsRows()); - return 0; + 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 69cf0a07..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; @@ -43,10 +44,10 @@ class RenameTagCommand extends Command try { $this->tagService->renameTag($oldName, $newName); $io->success('Tag properly renamed.'); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (EntityDoesNotExistException $e) { $io->error(sprintf('A tag with name "%s" was not found', $oldName)); - return -1; + return ExitCodes::EXIT_FAILURE; } } } diff --git a/module/CLI/src/Command/Visit/ProcessVisitsCommand.php b/module/CLI/src/Command/Visit/ProcessVisitsCommand.php index 7c51c020..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; @@ -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 1; + return ExitCodes::EXIT_WARNING; } try { @@ -70,7 +71,7 @@ class ProcessVisitsCommand extends Command $io->success('Finished processing all IPs'); } finally { $lock->release(); - return 0; + return ExitCodes::EXIT_SUCCESS; } } diff --git a/module/CLI/src/Command/Visit/UpdateDbCommand.php b/module/CLI/src/Command/Visit/UpdateDbCommand.php index b4554e66..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; @@ -51,7 +52,7 @@ class UpdateDbCommand extends Command $io->writeln(''); $io->success('GeoLite2 database properly updated'); - return 0; + return ExitCodes::EXIT_SUCCESS; } catch (RuntimeException $e) { $progressBar->finish(); $io->writeln(''); @@ -60,7 +61,7 @@ class UpdateDbCommand extends Command if ($io->isVerbose()) { $this->getApplication()->renderException($e, $output); } - return -1; + 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 @@ + Date: Sun, 17 Feb 2019 10:12:13 +0100 Subject: [PATCH 3/3] Increased scrutinizer timeout while waiting for code coverage, from 5 min to 10 min --- .scrutinizer.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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