mirror of
https://github.com/shlinkio/shlink.git
synced 2025-03-14 04:00:57 +03:00
Merge pull request #992 from acelaya-forks/feature/kebab-case-cli
Feature/kebab case cli
This commit is contained in:
commit
56a2253535
14 changed files with 186 additions and 89 deletions
|
@ -13,7 +13,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
|||
* [#986](https://github.com/shlinkio/shlink/issues/986) Updated official docker image to use PHP 8.
|
||||
|
||||
### Deprecated
|
||||
* *Nothing*
|
||||
* [#959](https://github.com/shlinkio/shlink/issues/959) Deprecated all command flags using camelCase format (like `--expirationDate`), adding kebab-case replacements for all of them (like `--expiration-date`).
|
||||
|
||||
All the existing camelCase flags will continue working for now, but will be removed in Shlink 3.0.0
|
||||
|
||||
### Removed
|
||||
* *Nothing*
|
||||
|
|
|
@ -6,11 +6,11 @@ namespace Shlinkio\Shlink\CLI\Command\Api;
|
|||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Shlinkio\Shlink\CLI\ApiKey\RoleResolverInterface;
|
||||
use Shlinkio\Shlink\CLI\Command\BaseCommand;
|
||||
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
||||
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -19,7 +19,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
|||
use function Shlinkio\Shlink\Core\arrayToString;
|
||||
use function sprintf;
|
||||
|
||||
class GenerateKeyCommand extends Command
|
||||
class GenerateKeyCommand extends BaseCommand
|
||||
{
|
||||
public const NAME = 'api-key:generate';
|
||||
|
||||
|
@ -42,9 +42,9 @@ class GenerateKeyCommand extends Command
|
|||
|
||||
<info>%command.full_name%</info>
|
||||
|
||||
You can optionally set its expiration date with <comment>--expirationDate</comment> or <comment>-e</comment>:
|
||||
You can optionally set its expiration date with <comment>--expiration-date</comment> or <comment>-e</comment>:
|
||||
|
||||
<info>%command.full_name% --expirationDate 2020-01-01</info>
|
||||
<info>%command.full_name% --expiration-date 2020-01-01</info>
|
||||
|
||||
You can also set roles to the API key:
|
||||
|
||||
|
@ -56,8 +56,8 @@ class GenerateKeyCommand extends Command
|
|||
$this
|
||||
->setName(self::NAME)
|
||||
->setDescription('Generates a new valid API key.')
|
||||
->addOption(
|
||||
'expirationDate',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'expiration-date',
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The date in which the API key should expire. Use any valid PHP format.',
|
||||
|
@ -79,7 +79,7 @@ class GenerateKeyCommand extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): ?int
|
||||
{
|
||||
$expirationDate = $input->getOption('expirationDate');
|
||||
$expirationDate = $this->getOptionWithDeprecatedFallback($input, 'expiration-date');
|
||||
$apiKey = $this->apiKeyService->create(
|
||||
isset($expirationDate) ? Chronos::parse($expirationDate) : null,
|
||||
...$this->roleResolver->determineRoles($input),
|
||||
|
|
|
@ -4,12 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\CLI\Command\Api;
|
||||
|
||||
use Shlinkio\Shlink\CLI\Command\BaseCommand;
|
||||
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
||||
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
|
||||
use Shlinkio\Shlink\Rest\ApiKey\Role;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -19,7 +19,7 @@ use function Functional\map;
|
|||
use function implode;
|
||||
use function sprintf;
|
||||
|
||||
class ListKeysCommand extends Command
|
||||
class ListKeysCommand extends BaseCommand
|
||||
{
|
||||
private const ERROR_STRING_PATTERN = '<fg=red>%s</>';
|
||||
private const SUCCESS_STRING_PATTERN = '<info>%s</info>';
|
||||
|
@ -40,8 +40,8 @@ class ListKeysCommand extends Command
|
|||
$this
|
||||
->setName(self::NAME)
|
||||
->setDescription('Lists all the available API keys.')
|
||||
->addOption(
|
||||
'enabledOnly',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'enabled-only',
|
||||
'e',
|
||||
InputOption::VALUE_NONE,
|
||||
'Tells if only enabled API keys should be returned.',
|
||||
|
@ -50,7 +50,7 @@ class ListKeysCommand extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): ?int
|
||||
{
|
||||
$enabledOnly = $input->getOption('enabledOnly');
|
||||
$enabledOnly = $this->getOptionWithDeprecatedFallback($input, 'enabled-only');
|
||||
|
||||
$rows = map($this->apiKeyService->listKeys($enabledOnly), function (ApiKey $apiKey) use ($enabledOnly) {
|
||||
$expiration = $apiKey->getExpirationDate();
|
||||
|
|
51
module/CLI/src/Command/BaseCommand.php
Normal file
51
module/CLI/src/Command/BaseCommand.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\CLI\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
use function method_exists;
|
||||
use function Shlinkio\Shlink\Core\kebabCaseToCamelCase;
|
||||
use function sprintf;
|
||||
use function str_contains;
|
||||
|
||||
abstract class BaseCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @param mixed|null $default
|
||||
*/
|
||||
protected function addOptionWithDeprecatedFallback(
|
||||
string $name,
|
||||
?string $shortcut = null,
|
||||
?int $mode = null,
|
||||
string $description = '',
|
||||
$default = null
|
||||
): self {
|
||||
$this->addOption($name, $shortcut, $mode, $description, $default);
|
||||
|
||||
if (str_contains($name, '-')) {
|
||||
$camelCaseName = kebabCaseToCamelCase($name);
|
||||
$this->addOption($camelCaseName, null, $mode, sprintf('[DEPRECATED] Same as "%s".', $name), $default);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|string|string[]|null
|
||||
*/
|
||||
protected function getOptionWithDeprecatedFallback(InputInterface $input, string $name)
|
||||
{
|
||||
$rawInput = method_exists($input, '__toString') ? $input->__toString() : '';
|
||||
$camelCaseName = kebabCaseToCamelCase($name);
|
||||
|
||||
if (str_contains($rawInput, $camelCaseName)) {
|
||||
return $input->getOption($camelCaseName);
|
||||
}
|
||||
|
||||
return $input->getOption($name);
|
||||
}
|
||||
}
|
|
@ -4,13 +4,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
||||
|
||||
use Shlinkio\Shlink\CLI\Command\BaseCommand;
|
||||
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
@ -23,9 +23,9 @@ use function Functional\flatten;
|
|||
use function Functional\unique;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function str_contains;
|
||||
|
||||
class GenerateShortUrlCommand extends Command
|
||||
class GenerateShortUrlCommand extends BaseCommand
|
||||
{
|
||||
public const NAME = 'short-url:generate';
|
||||
|
||||
|
@ -53,34 +53,34 @@ class GenerateShortUrlCommand extends Command
|
|||
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
|
||||
'Tags to apply to the new short URL',
|
||||
)
|
||||
->addOption(
|
||||
'validSince',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'valid-since',
|
||||
's',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The date from which this short URL will be valid. '
|
||||
. 'If someone tries to access it before this date, it will not be found.',
|
||||
)
|
||||
->addOption(
|
||||
'validUntil',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'valid-until',
|
||||
'u',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The date until which this short URL will be valid. '
|
||||
. 'If someone tries to access it after this date, it will not be found.',
|
||||
)
|
||||
->addOption(
|
||||
'customSlug',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'custom-slug',
|
||||
'c',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'If provided, this slug will be used instead of generating a short code',
|
||||
)
|
||||
->addOption(
|
||||
'maxVisits',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'max-visits',
|
||||
'm',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'This will limit the number of visits for this short URL.',
|
||||
)
|
||||
->addOption(
|
||||
'findIfExists',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'find-if-exists',
|
||||
'f',
|
||||
InputOption::VALUE_NONE,
|
||||
'This will force existing matching URL to be returned if found, instead of creating a new one.',
|
||||
|
@ -91,11 +91,11 @@ class GenerateShortUrlCommand extends Command
|
|||
InputOption::VALUE_REQUIRED,
|
||||
'The domain to which this short URL will be attached.',
|
||||
)
|
||||
->addOption(
|
||||
'shortCodeLength',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'short-code-length',
|
||||
'l',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The length for generated short code (it will be ignored if --customSlug was provided).',
|
||||
'The length for generated short code (it will be ignored if --custom-slug was provided).',
|
||||
)
|
||||
->addOption(
|
||||
'validate-url',
|
||||
|
@ -136,18 +136,24 @@ class GenerateShortUrlCommand extends Command
|
|||
|
||||
$explodeWithComma = curry('explode')(',');
|
||||
$tags = unique(flatten(array_map($explodeWithComma, $input->getOption('tags'))));
|
||||
$customSlug = $input->getOption('customSlug');
|
||||
$maxVisits = $input->getOption('maxVisits');
|
||||
$shortCodeLength = $input->getOption('shortCodeLength') ?? $this->defaultShortCodeLength;
|
||||
$customSlug = $this->getOptionWithDeprecatedFallback($input, 'custom-slug');
|
||||
$maxVisits = $this->getOptionWithDeprecatedFallback($input, 'max-visits');
|
||||
$shortCodeLength = $this->getOptionWithDeprecatedFallback(
|
||||
$input,
|
||||
'short-code-length',
|
||||
) ?? $this->defaultShortCodeLength;
|
||||
$doValidateUrl = $this->doValidateUrl($input);
|
||||
|
||||
try {
|
||||
$shortUrl = $this->urlShortener->shorten($longUrl, $tags, ShortUrlMeta::fromRawData([
|
||||
ShortUrlMetaInputFilter::VALID_SINCE => $input->getOption('validSince'),
|
||||
ShortUrlMetaInputFilter::VALID_UNTIL => $input->getOption('validUntil'),
|
||||
ShortUrlMetaInputFilter::VALID_SINCE => $this->getOptionWithDeprecatedFallback($input, 'valid-since'),
|
||||
ShortUrlMetaInputFilter::VALID_UNTIL => $this->getOptionWithDeprecatedFallback($input, 'valid-until'),
|
||||
ShortUrlMetaInputFilter::CUSTOM_SLUG => $customSlug,
|
||||
ShortUrlMetaInputFilter::MAX_VISITS => $maxVisits !== null ? (int) $maxVisits : null,
|
||||
ShortUrlMetaInputFilter::FIND_IF_EXISTS => $input->getOption('findIfExists'),
|
||||
ShortUrlMetaInputFilter::FIND_IF_EXISTS => $this->getOptionWithDeprecatedFallback(
|
||||
$input,
|
||||
'find-if-exists',
|
||||
),
|
||||
ShortUrlMetaInputFilter::DOMAIN => $input->getOption('domain'),
|
||||
ShortUrlMetaInputFilter::SHORT_CODE_LENGTH => $shortCodeLength,
|
||||
ShortUrlMetaInputFilter::VALIDATE_URL => $doValidateUrl,
|
||||
|
@ -168,10 +174,10 @@ class GenerateShortUrlCommand extends Command
|
|||
{
|
||||
$rawInput = method_exists($input, '__toString') ? $input->__toString() : '';
|
||||
|
||||
if (strpos($rawInput, '--no-validate-url') !== false) {
|
||||
if (str_contains($rawInput, '--no-validate-url')) {
|
||||
return false;
|
||||
}
|
||||
if (strpos($rawInput, '--validate-url') !== false) {
|
||||
if (str_contains($rawInput, '--validate-url')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
|||
|
||||
use function Functional\map;
|
||||
use function Functional\select_keys;
|
||||
use function sprintf;
|
||||
|
||||
class GetVisitsCommand extends AbstractWithDateRangeCommand
|
||||
{
|
||||
|
@ -39,18 +40,18 @@ class GetVisitsCommand extends AbstractWithDateRangeCommand
|
|||
$this
|
||||
->setName(self::NAME)
|
||||
->setDescription('Returns the detailed visits information for provided short code')
|
||||
->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get')
|
||||
->addOption('domain', 'd', InputOption::VALUE_REQUIRED, 'The domain for the short code');
|
||||
->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get.')
|
||||
->addOption('domain', 'd', InputOption::VALUE_REQUIRED, 'The domain for the short code.');
|
||||
}
|
||||
|
||||
protected function getStartDateDesc(): string
|
||||
protected function getStartDateDesc(string $optionName): string
|
||||
{
|
||||
return 'Allows to filter visits, returning only those older than start date';
|
||||
return sprintf('Allows to filter visits, returning only those older than "%s".', $optionName);
|
||||
}
|
||||
|
||||
protected function getEndDateDesc(): string
|
||||
protected function getEndDateDesc(string $optionName): string
|
||||
{
|
||||
return 'Allows to filter visits, returning only those newer than end date';
|
||||
return sprintf('Allows to filter visits, returning only those newer than "%s".', $optionName);
|
||||
}
|
||||
|
||||
protected function interact(InputInterface $input, OutputInterface $output): void
|
||||
|
@ -70,8 +71,8 @@ class GetVisitsCommand extends AbstractWithDateRangeCommand
|
|||
protected function execute(InputInterface $input, OutputInterface $output): ?int
|
||||
{
|
||||
$identifier = ShortUrlIdentifier::fromCli($input);
|
||||
$startDate = $this->getDateOption($input, $output, 'startDate');
|
||||
$endDate = $this->getDateOption($input, $output, 'endDate');
|
||||
$startDate = $this->getStartDateOption($input, $output);
|
||||
$endDate = $this->getEndDateOption($input, $output);
|
||||
|
||||
$paginator = $this->visitsTracker->info($identifier, new VisitsParams(new DateRange($startDate, $endDate)));
|
||||
|
||||
|
|
|
@ -60,28 +60,33 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||
'page',
|
||||
'p',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The first page to list (10 items per page unless "--all" is provided)',
|
||||
'The first page to list (10 items per page unless "--all" is provided).',
|
||||
'1',
|
||||
)
|
||||
->addOption(
|
||||
'searchTerm',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'search-term',
|
||||
'st',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'A query used to filter results by searching for it on the longUrl and shortCode fields',
|
||||
'A query used to filter results by searching for it on the longUrl and shortCode fields.',
|
||||
)
|
||||
->addOption(
|
||||
'tags',
|
||||
't',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'A comma-separated list of tags to filter results',
|
||||
'A comma-separated list of tags to filter results.',
|
||||
)
|
||||
->addOption(
|
||||
'orderBy',
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'order-by',
|
||||
'o',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The field from which we want to order by. Pass ASC or DESC separated by a comma',
|
||||
'The field from which we want to order by. Pass ASC or DESC separated by a comma.',
|
||||
)
|
||||
->addOptionWithDeprecatedFallback(
|
||||
'show-tags',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Whether to display the tags or not.',
|
||||
)
|
||||
->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not')
|
||||
->addOption(
|
||||
'all',
|
||||
'a',
|
||||
|
@ -91,14 +96,14 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||
);
|
||||
}
|
||||
|
||||
protected function getStartDateDesc(): string
|
||||
protected function getStartDateDesc(string $optionName): string
|
||||
{
|
||||
return 'Allows to filter short URLs, returning only those created after "startDate"';
|
||||
return sprintf('Allows to filter short URLs, returning only those created after "%s".', $optionName);
|
||||
}
|
||||
|
||||
protected function getEndDateDesc(): string
|
||||
protected function getEndDateDesc(string $optionName): string
|
||||
{
|
||||
return 'Allows to filter short URLs, returning only those created before "endDate"';
|
||||
return sprintf('Allows to filter short URLs, returning only those created before "%s".', $optionName);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): ?int
|
||||
|
@ -106,13 +111,13 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$page = (int) $input->getOption('page');
|
||||
$searchTerm = $input->getOption('searchTerm');
|
||||
$searchTerm = $this->getOptionWithDeprecatedFallback($input, 'search-term');
|
||||
$tags = $input->getOption('tags');
|
||||
$tags = ! empty($tags) ? explode(',', $tags) : [];
|
||||
$showTags = (bool) $input->getOption('showTags');
|
||||
$all = (bool) $input->getOption('all');
|
||||
$startDate = $this->getDateOption($input, $output, 'startDate');
|
||||
$endDate = $this->getDateOption($input, $output, 'endDate');
|
||||
$showTags = $this->getOptionWithDeprecatedFallback($input, 'show-tags');
|
||||
$all = $input->getOption('all');
|
||||
$startDate = $this->getStartDateOption($input, $output);
|
||||
$endDate = $this->getEndDateOption($input, $output);
|
||||
$orderBy = $this->processOrderBy($input);
|
||||
|
||||
$data = [
|
||||
|
@ -178,7 +183,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||
*/
|
||||
private function processOrderBy(InputInterface $input)
|
||||
{
|
||||
$orderBy = $input->getOption('orderBy');
|
||||
$orderBy = $this->getOptionWithDeprecatedFallback($input, 'order-by');
|
||||
if (empty($orderBy)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\CLI\Command\Util;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Shlinkio\Shlink\CLI\Command\BaseCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -13,19 +13,42 @@ use Throwable;
|
|||
|
||||
use function sprintf;
|
||||
|
||||
abstract class AbstractWithDateRangeCommand extends Command
|
||||
abstract class AbstractWithDateRangeCommand extends BaseCommand
|
||||
{
|
||||
private const START_DATE = 'start-date';
|
||||
private const END_DATE = 'end-date';
|
||||
|
||||
final protected function configure(): void
|
||||
{
|
||||
$this->doConfigure();
|
||||
$this
|
||||
->addOption('startDate', 's', InputOption::VALUE_REQUIRED, $this->getStartDateDesc())
|
||||
->addOption('endDate', 'e', InputOption::VALUE_REQUIRED, $this->getEndDateDesc());
|
||||
->addOptionWithDeprecatedFallback(
|
||||
self::START_DATE,
|
||||
's',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
$this->getStartDateDesc(self::START_DATE),
|
||||
)
|
||||
->addOptionWithDeprecatedFallback(
|
||||
self::END_DATE,
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
$this->getEndDateDesc(self::END_DATE),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getDateOption(InputInterface $input, OutputInterface $output, string $key): ?Chronos
|
||||
protected function getStartDateOption(InputInterface $input, OutputInterface $output): ?Chronos
|
||||
{
|
||||
$value = $input->getOption($key);
|
||||
return $this->getDateOption($input, $output, self::START_DATE);
|
||||
}
|
||||
|
||||
protected function getEndDateOption(InputInterface $input, OutputInterface $output): ?Chronos
|
||||
{
|
||||
return $this->getDateOption($input, $output, self::END_DATE);
|
||||
}
|
||||
|
||||
private function getDateOption(InputInterface $input, OutputInterface $output, string $key): ?Chronos
|
||||
{
|
||||
$value = $this->getOptionWithDeprecatedFallback($input, $key);
|
||||
if (empty($value)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -49,6 +72,7 @@ abstract class AbstractWithDateRangeCommand extends Command
|
|||
|
||||
abstract protected function doConfigure(): void;
|
||||
|
||||
abstract protected function getStartDateDesc(): string;
|
||||
abstract protected function getEndDateDesc(): string;
|
||||
abstract protected function getStartDateDesc(string $optionName): string;
|
||||
|
||||
abstract protected function getEndDateDesc(string $optionName): string;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class GenerateKeyCommandTest extends TestCase
|
|||
$this->apiKeyService->create(Argument::type(Chronos::class))->shouldBeCalledOnce()
|
||||
->willReturn(new ApiKey());
|
||||
$this->commandTester->execute([
|
||||
'--expirationDate' => '2016-01-01',
|
||||
'--expiration-date' => '2016-01-01',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class ListKeysCommandTest extends TestCase
|
|||
{
|
||||
$listKeys = $this->apiKeyService->listKeys($enabledOnly)->willReturn($keys);
|
||||
|
||||
$this->commandTester->execute(['--enabledOnly' => $enabledOnly]);
|
||||
$this->commandTester->execute(['--enabled-only' => $enabledOnly]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
|
||||
self::assertEquals($expected, $output);
|
||||
|
|
|
@ -48,7 +48,7 @@ class GenerateShortUrlCommandTest extends TestCase
|
|||
|
||||
$this->commandTester->execute([
|
||||
'longUrl' => 'http://domain.com/foo/bar',
|
||||
'--maxVisits' => '3',
|
||||
'--max-visits' => '3',
|
||||
]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
|
||||
|
@ -78,7 +78,7 @@ class GenerateShortUrlCommandTest extends TestCase
|
|||
NonUniqueSlugException::fromSlug('my-slug'),
|
||||
);
|
||||
|
||||
$this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--customSlug' => 'my-slug']);
|
||||
$this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--custom-slug' => 'my-slug']);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
|
||||
self::assertEquals(ExitCodes::EXIT_FAILURE, $this->commandTester->getStatusCode());
|
||||
|
|
|
@ -71,8 +71,8 @@ class GetVisitsCommandTest extends TestCase
|
|||
|
||||
$this->commandTester->execute([
|
||||
'shortCode' => $shortCode,
|
||||
'--startDate' => $startDate,
|
||||
'--endDate' => $endDate,
|
||||
'--start-date' => $startDate,
|
||||
'--end-date' => $endDate,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -86,13 +86,13 @@ class GetVisitsCommandTest extends TestCase
|
|||
|
||||
$this->commandTester->execute([
|
||||
'shortCode' => $shortCode,
|
||||
'--startDate' => $startDate,
|
||||
'--start-date' => $startDate,
|
||||
]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
|
||||
$info->shouldHaveBeenCalledOnce();
|
||||
self::assertStringContainsString(
|
||||
sprintf('Ignored provided "startDate" since its value "%s" is not a valid date', $startDate),
|
||||
sprintf('Ignored provided "start-date" since its value "%s" is not a valid date', $startDate),
|
||||
$output,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||
->shouldBeCalledOnce();
|
||||
|
||||
$this->commandTester->setInputs(['y']);
|
||||
$this->commandTester->execute(['--showTags' => true]);
|
||||
$this->commandTester->execute(['--show-tags' => true]);
|
||||
$output = $this->commandTester->getDisplay();
|
||||
self::assertStringContainsString('Tags', $output);
|
||||
}
|
||||
|
@ -139,22 +139,22 @@ class ListShortUrlsCommandTest extends TestCase
|
|||
{
|
||||
yield [[], 1, null, []];
|
||||
yield [['--page' => $page = 3], $page, null, []];
|
||||
yield [['--searchTerm' => $searchTerm = 'search this'], 1, $searchTerm, []];
|
||||
yield [['--search-term' => $searchTerm = 'search this'], 1, $searchTerm, []];
|
||||
yield [
|
||||
['--page' => $page = 3, '--searchTerm' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
|
||||
['--page' => $page = 3, '--search-term' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
|
||||
$page,
|
||||
$searchTerm,
|
||||
explode(',', $tags),
|
||||
];
|
||||
yield [
|
||||
['--startDate' => $startDate = '2019-01-01'],
|
||||
['--start-date' => $startDate = '2019-01-01'],
|
||||
1,
|
||||
null,
|
||||
[],
|
||||
$startDate,
|
||||
];
|
||||
yield [
|
||||
['--endDate' => $endDate = '2020-05-23'],
|
||||
['--end-date' => $endDate = '2020-05-23'],
|
||||
1,
|
||||
null,
|
||||
[],
|
||||
|
@ -162,7 +162,7 @@ class ListShortUrlsCommandTest extends TestCase
|
|||
$endDate,
|
||||
];
|
||||
yield [
|
||||
['--startDate' => $startDate = '2019-01-01', '--endDate' => $endDate = '2020-05-23'],
|
||||
['--start-date' => $startDate = '2019-01-01', '--end-date' => $endDate = '2020-05-23'],
|
||||
1,
|
||||
null,
|
||||
[],
|
||||
|
@ -191,9 +191,9 @@ class ListShortUrlsCommandTest extends TestCase
|
|||
public function provideOrderBy(): iterable
|
||||
{
|
||||
yield [[], null];
|
||||
yield [['--orderBy' => 'foo'], 'foo'];
|
||||
yield [['--orderBy' => 'foo,ASC'], ['foo' => 'ASC']];
|
||||
yield [['--orderBy' => 'bar,DESC'], ['bar' => 'DESC']];
|
||||
yield [['--order-by' => 'foo'], 'foo'];
|
||||
yield [['--order-by' => 'foo,ASC'], ['foo' => 'ASC']];
|
||||
yield [['--order-by' => 'bar,DESC'], ['bar' => 'DESC']];
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
|
|
@ -12,9 +12,12 @@ use PUGX\Shortid\Factory as ShortIdFactory;
|
|||
|
||||
use function Functional\reduce_left;
|
||||
use function is_array;
|
||||
use function lcfirst;
|
||||
use function print_r;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function str_replace;
|
||||
use function ucwords;
|
||||
|
||||
const DEFAULT_DELETE_SHORT_URL_THRESHOLD = 15;
|
||||
const DEFAULT_SHORT_CODES_LENGTH = 5;
|
||||
|
@ -97,3 +100,8 @@ function arrayToString(array $array, int $indentSize = 4): string
|
|||
);
|
||||
}, '');
|
||||
}
|
||||
|
||||
function kebabCaseToCamelCase(string $name): string
|
||||
{
|
||||
return lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $name))));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue