Skip to content

Commit 15e8900

Browse files
committed
Improve ImportIconCommand
- handle same prefix icons per batchs - improve feedback
1 parent 60fb1e4 commit 15e8900

File tree

2 files changed

+59
-33
lines changed

2 files changed

+59
-33
lines changed

src/Icons/src/Command/ImportIconCommand.php

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Symfony\Component\Console\Input\InputInterface;
1919
use Symfony\Component\Console\Output\OutputInterface;
2020
use Symfony\Component\Console\Style\SymfonyStyle;
21-
use Symfony\UX\Icons\Exception\IconNotFoundException;
2221
use Symfony\UX\Icons\Iconify;
2322
use Symfony\UX\Icons\Registry\LocalSvgIconRegistry;
2423

@@ -50,9 +49,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5049
$io = new SymfonyStyle($input, $output);
5150
$names = $input->getArgument('names');
5251
$result = Command::SUCCESS;
52+
$importedIcons = 0;
5353

5454
$prefixIcons = [];
55-
$importedIcons = 0;
5655
foreach ($names as $name) {
5756
if (!preg_match('#^([\w-]+):([\w-]+)$#', $name, $matches)) {
5857
$io->error(\sprintf('Invalid icon name "%s".', $name));
@@ -61,10 +60,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6160
continue;
6261
}
6362

64-
[$fullName, $prefix, $name] = $matches;
65-
63+
[, $prefix, $name] = $matches;
6664
$prefixIcons[$prefix] ??= [];
67-
$prefixIcons[$prefix][$name] = $fullName;
65+
$prefixIcons[$prefix][$name] = $name;
6866
}
6967

7068
foreach ($prefixIcons as $prefix => $icons) {
@@ -77,43 +75,50 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7775
}
7876

7977
$metadata = $this->iconify->metadataFor($prefix);
80-
$io->writeln([
81-
"\n",
82-
\sprintf(' IconSet: <fg=bright-white;bg=black>%s</> - %s', $metadata['name'], $prefix),
83-
\sprintf(' (Licence: %s)', $metadata['license']['title']),
84-
"\n",
85-
]);
86-
87-
foreach (array_chunk($icons, 25, true) as $iconBatch) {
88-
foreach ($iconBatch as $name => $fullName) {
78+
$io->newLine();
79+
$io->writeln(\sprintf(' Icon set: %s (License: %s)', $metadata['name'], $metadata['license']['title']));
80+
81+
foreach ($this->iconify->chunk($prefix, \array_keys($icons)) as $iconNames) {
82+
83+
$cursor = new Cursor($output);
84+
foreach ($iconNames as $name) {
8985
$io->writeln(\sprintf(' Importing %s:%s ...', $prefix, $name));
9086
}
87+
$cursor->moveUp(count($iconNames));
9188

9289
try {
93-
$batchResults = $this->iconify->fetchIcons($prefix, $names);
94-
} catch (IconNotFoundException $e) {
90+
$batchResults = $this->iconify->fetchIcons($prefix, $iconNames);
91+
} catch (\InvalidArgumentException $e) {
92+
// At this point no exception should be thrown
9593
$io->error($e->getMessage());
96-
$result = Command::FAILURE;
9794

98-
continue;
95+
return COMMAND::FAILURE;
9996
}
10097

101-
$cursor = new Cursor($output);
102-
$cursor->moveUp(count($iconBatch));
98+
foreach ($iconNames as $name) {
99+
$cursor->clearLineAfter();
100+
101+
// If the icon is not found, the value will be null
102+
if (null === $icon = $batchResults[$name] ?? null) {
103+
$io->writeln(\sprintf(" <fg=red;options=bold>✗</> Not Found <fg=bright-white;bg=black>%s:</><fg=bright-red;bg=black>%s</>", $prefix, $name));
104+
105+
continue;
106+
}
103107

104-
foreach ($batchResults as $name => $icon) {
105-
$this->registry->add(\sprintf('%s/%s', $prefix, $name), (string) $icon);
106108
++$importedIcons;
107-
$cursor->clearLine();
109+
$this->registry->add(\sprintf('%s/%s', $prefix, $name), (string) $icon);
108110
$io->writeln(\sprintf(" <fg=bright-green;options=bold>✓</> Imported <fg=bright-white;bg=black>%s:</><fg=bright-magenta;bg=black;options>%s</>", $prefix, $name));
109111
}
110-
111-
$cursor->clearLineAfter();
112112
}
113113
}
114114

115-
if (Command::SUCCESS === $result) {
116-
$io->success(sprintf('Imported %d icons.', $importedIcons));
115+
if ($importedIcons === $totalIcons = count($names)) {
116+
$io->success(sprintf('Imported %d/%d icons.', $importedIcons, $totalIcons));
117+
} elseif ($importedIcons > 0) {
118+
$io->warning(sprintf('Imported %d/%d icons.', $importedIcons, $totalIcons));
119+
} else {
120+
$io->error(sprintf('Imported %d/%d icons.', $importedIcons, $totalIcons));
121+
$result = Command::FAILURE;
117122
}
118123

119124
return $result;

src/Icons/tests/Integration/Command/ImportIconCommandTest.php

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ final class ImportIconCommandTest extends KernelTestCase
2323
use InteractsWithConsole;
2424

2525
private const ICON_DIR = __DIR__.'/../../Fixtures/icons';
26-
private const ICONS = ['uiw/dashboard.svg'];
26+
private const ICONS = ['uiw/dashboard.svg', 'lucide/circle.svg'];
2727

2828
/**
2929
* @before
@@ -45,8 +45,8 @@ public function testCanImportIcon(): void
4545

4646
$this->executeConsoleCommand('ux:icons:import uiw:dashboard')
4747
->assertSuccessful()
48-
->assertOutputContains('Importing uiw:dashboard')
49-
->assertOutputContains("Imported uiw:dashboard (License: MIT). Render with: {{ ux_icon('uiw:dashboard') }}")
48+
->assertOutputContains('Icon set: uiw icons (License: MIT)')
49+
->assertOutputContains("Importing uiw:dashboard")
5050
;
5151

5252
$this->assertFileExists($expectedFile);
@@ -60,13 +60,34 @@ public function testImportInvalidIconName(): void
6060
;
6161
}
6262

63-
public function testImportNonExistentIcon(): void
63+
public function testImportNonExistentIconSet(): void
6464
{
6565
$this->executeConsoleCommand('ux:icons:import something:invalid')
6666
->assertStatusCode(1)
67-
->assertOutputContains('[ERROR] The icon "something:invalid" does not exist on iconify.design.')
67+
->assertOutputContains('[ERROR] Icon set "something" not found.')
68+
;
69+
}
70+
71+
public function testImportNonExistentIcon(): void
72+
{
73+
$this->executeConsoleCommand('ux:icons:import lucide:not-existing-icon')
74+
->assertStatusCode(1)
75+
->assertOutputContains('Not Found lucide:not-existing-icon')
76+
->assertOutputContains('[ERROR] Imported 0/1 icons.')
77+
;
78+
79+
$this->assertFileDoesNotExist(self::ICON_DIR.'/not-existing-icon.svg');
80+
}
81+
82+
public function testImportNonExistentIconWithExistentOne(): void
83+
{
84+
$this->executeConsoleCommand('ux:icons:import lucide:circle lucide:not-existing-icon')
85+
->assertStatusCode(0)
86+
->assertOutputContains('Imported lucide:circle')
87+
->assertOutputContains('Not Found lucide:not-existing-icon')
88+
->assertOutputContains('[WARNING] Imported 1/2 icons.')
6889
;
6990

70-
$this->assertFileDoesNotExist(self::ICON_DIR.'/invalid.svg');
91+
$this->assertFileDoesNotExist(self::ICON_DIR.'/not-existing-icon.svg');
7192
}
7293
}

0 commit comments

Comments
 (0)