8000 [Uid] Add Generate and Inspect commands · symfony/symfony@bedc3f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit bedc3f5

Browse files
committed
[Uid] Add Generate and Inspect commands
1 parent d093475 commit bedc3f5

10 files changed

+782
-0
lines changed

src/Symfony/Component/Uid/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* Add commands to generate and inspect Uuid's and Ulid's
8+
49
5.2.0
510
-----
611

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputOption;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Uid\Ulid;
19+
20+
class GenerateUlidCommand extends Command
21+
{
22+
protected static $defaultName = 'ulid:generate';
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
protected function configure(): void
28+
{
29+
$this
30+
->setDefinition([
31+
new InputOption('count', 'c', InputOption::VALUE_REQUIRED, 'The number of ULID to generate.', 1),
32+
])
33+
->setDescription('Generates a ULID')
34+
->setHelp(<<<'EOF'
35+
The <info>%command.name%</info> command generates a ULID.
36+
37+
<info>php %command.full_name%</info>
38+
39+
To generate several ULID:
40+
41+
<info>php %command.full_name% --count=10</info>
42+
EOF
43+
)
44+
;
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
protected function execute(InputInterface $input, OutputInterface $output)
51+
{
52+
$count = (int) $input->getOption('count');
53+
54+
for ($i = 0; $i < $count; ++$i) {
55+
$output->writeln(new Ulid());
56+
}
57+
58+
return 0;
59+
}
60+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Input\InputArgument;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Component\Console\Style\SymfonyStyle;
21+
use Symfony\Component\Uid\Uuid;
22+
23+
class GenerateUuidCommand extends Command
24+
{
25+
protected static $defaultName = 'uuid:generate';
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
protected function configure(): void
31+
{
32+
$this
33+
->setDefinition([
34+
new InputArgument('version', InputArgument::OPTIONAL, 'The UUID version to generate (v1, v3, v4, v5 or v6).', 'v1'),
35+
new InputOption('count', 'c', InputOption::VALUE_REQUIRED, 'The number of UUID to generate.', 1),
36+
new InputOption('namespace', null, InputOption::VALUE_REQUIRED, 'The namespace for version 3 and 5 (a UUID, in any of the supported formats (base 58, base 32 or RFC 4122)).'),
37+
new InputOption('name', null, InputOption::VALUE_REQUIRED, 'The name for version 3 and 5.'),
38+
])
39+
->setDescription('Generates a UUID')
40+
->setHelp(<<<'EOF'
41+
The <info>%command.name%</info> generates a UUID.
42+
43+
<info>php %command.full_name%</info>
44+
45+
To choose the version:
46+
47+
<info>php %command.full_name% v4</info>
48+
49+
For version 3 and 5, you have to provide the namespace and the name:
50+
51+
<info>php %command.full_name% v5 --namespace=c9280a08-4a2b-4105-8e0e-3eef9fd4fb3a --name=foo</info>
52+
53+
To generate several UUID:
54+
55+
<info>php %command.full_name% --count=10</info>
56+
EOF
57+
)
58+
;
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
protected function execute(InputInterface $input, OutputInterface $output)
65+
{
66+
$io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output);
67+
68+
switch ($version = $input->getArgument('version')) {
69+
case 'v1':
70+
case 'v4':
71+
case 'v6':
72+
$create = [Uuid::class, $version];
73+
74+
break;
75+
case 'v3':
76+
case 'v5':
77+
if (null === $namespace = $input->getOption('namespace')) {
78+
$io->error('Providing the UUID namespace is required for this version, use the --namespace option.');
79+
80+
return 2;
81+
}
82+
83+
if (null === $name = $input->getOption('name')) {
84+
$io->error('Providing the UUID name is required for this version, use the --name option.');
85+
86+
return 3;
87+
}
88+
89+
try {
90+
$namespace = Uuid::fromString($namespace);
91+
} catch (\InvalidArgumentException $e) {
92+
$io->error(sprintf('Invalid namespace "%s".', $namespace));
93+
94+
return 4;
95+
}
96+
97+
$create = static function () use ($version, $namespace, $name): Uuid {
98+
return Uuid::$version($namespace, $name);
99+
};
100+
101+
break;
102+
default:
103+
$io->error('Wrong version. Supported versions are v1, v3, v4, v5 and v6.');
104+
105+
return 1;
106+
}
107+
108+
$count = (int) $input->getOption('count');
109+
110+
for ($i = 0; $i < $count; ++$i) {
111+
$io->writeln($create());
112+
}
113+
114+
return 0;
115+
}
116+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Helper\TableSeparator;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Component\Console\Style\SymfonyStyle;
21+
use Symfony\Component\Uid\Ulid;
22+
23+
class InspectUlidCommand extends Command
24+
{
25+
protected static $defaultName = 'ulid:inspect';
26+
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
protected function configure(): void
31+
{
32+
$this
33+
->setDefinition([
34+
new InputArgument('ulid', InputArgument::REQUIRED, 'The ULID to inspect, in any of the supported formats (base 58, base 32 or RFC 4122)'),
35+
])
36+
->setDescription('Inspects a ULID')
37+
->setHelp(<<<'EOF'
38+
The <info>%command.name%</info> display information about a ULID.
39+
40+
<info>php %command.full_name% 01EWAKBCMWQ2C94EXNN60ZBS0Q</info>
41+
<info>php %command.full_name% 1BVdfLn3ERmbjYBLCdaaLW</info>
42+
<info>php %command.full_name% 01771535-b29c-b898-923b-b5a981f5e417</info>
43+
EOF
44+
)
45+
;
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
protected function execute(InputInterface $input, OutputInterface $output)
52+
{
53+
$io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output);
54+
55+
try {
56+
/** @var Ulid $ulid */
57+
$ulid = Ulid::fromString($input->getArgument('ulid'));
58+
} catch (\InvalidArgumentException $e) {
59+
$io->error(sprintf('Invalid ULID "%s".', $input->getArgument('ulid')));
60+
61+
return 1;
62+
}
63+
64+
$io->table(['Label', 'Value'], [
65+
['Canonical (Base 32)', (string) $ulid],
66+
['Base 58', $ulid->toBase58()],
67+
['RFC 4122', $ulid->toRfc4122()],
68+
new TableSeparator(),
69+
['Timestamp', sprintf('%s (%s)', $ulid->getTime(), \DateTimeImmutable::createFromFormat('U.v', sprintf('%.3F', $ulid->getTime()))->format('Y-m-d\TH:i:s.vP'))],
70+
]);
71+
72+
return 0;
73+
}
74+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Helper\TableSeparator;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Component\Console\Style\SymfonyStyle;
21+
use Symfony\Component\Uid\Uuid;
22+
use Symfony\Component\Uid\UuidV1;
23+
use Symfony\Component\Uid\UuidV6;
24+
25+
class InspectUuidCommand extends Command
26+
{
27+
protected static $defaultName = 'uuid:inspect';
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
protected function configure(): void
33+
{
34+
$this
35+
->setDefinition([
36+
new InputArgument('uuid', InputArgument::REQUIRED, 'The UUID to inspect, in any of the supported formats (base 58, base 32 or RFC 4122)'),
37+
])
38+
->setDescription('Inspects a UUID')
39+
->setHelp(<<<'EOF'
40+
The <info>%command.name%</info> display information about a UUID.
41+
42+
<info>php %command.full_name% a7613e0a-5986-11eb-a861-2bf05af69e52</info>
43+
<info>php %command.full_name% MfnmaUvvQ1h8B14vTwt6dX</info>
44+
<info>php %command.full_name% 57C4Z0MPC627NTGR9BY1DFD7JJ</info>
45+
EOF
46+
)
47+
;
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
protected function execute(InputInterface $input, OutputInterface $output)
54+
{
55+
$io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output);
56+
57+
try {
58+
/** @var Uuid $uuid */
59+
$uuid = Uuid::fromString($input->getArgument('uuid'));
60+
} catch (\InvalidArgumentException $e) {
61+
$io->error(sprintf('Invalid UUID "%s".', $input->getArgument('uuid')));
62+
63+
return 1;
64+
}
65+
66+
if (-1 === $version = uuid_type($uuid)) {
67+
$version = 'nil';
68+
} elseif (0 === $version || 2 === $version || 6 < $version) {
69+
$version = 'unknown';
70+
} else {
71+
$version = 'v'.$version;
72+
}
73+
74+
$rows = [
75+
['Version', $version],
76+
['Canonical (RFC 4122)', (string) $uuid],
77+
['Base 58', $uuid->toBase58()],
78+
['Base 32', $uuid->toBase32()],
79+
];
80+
81+
if ($uuid instanceof UuidV1 || $uuid instanceof UuidV6) {
82+
$rows[] = new TableSeparator();
83+
$rows[] = ['Timestamp', sprintf('%s (%s)', $uuid->getTime(), \DateTimeImmutable::createFromFormat('U.v', sprintf('%.3F', $uuid->getTime()))->format('Y-m-d\TH:i:s.vP'))];
84+
}
85+
86+
$io->table(['Label', 'Value'], $rows);
87+
88+
return 0;
89+
}
90+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid\Tests\Command;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Console\Tester\CommandTester;
16+
use Symfony\Component\Uid\Command\GenerateUlidCommand;
17+
use Symfony\Component\Uid\Ulid;
18+
19+
final class GenerateUlidCommandTest extends TestCase
20+
{
21+
public function test()
22+
{
23+
$commandTester = new CommandTester(new GenerateUlidCommand());
24+
25+
$this->assertSame(0, $commandTester->execute([]));
26+
$this->assertTrue(Ulid::isValid(trim($commandTester->getDisplay())));
27+
28+
$this->assertSame(0, $commandTester->execute(['--count' => '10']));
29+
$ulids = explode("\n", trim($commandTester->getDisplay(true)));
30+
$this->assertCount(10, $ulids);
31+
foreach ($ulids as $ulid) {
32+
$this->assertTrue(Ulid::isValid($ulid));
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)
0