Skip to content

Commit 73038ec

Browse files
committed
iterate
1 parent 50d3079 commit 73038ec

File tree

3 files changed

+42
-49
lines changed

3 files changed

+42
-49
lines changed

src/Toolkit/src/Command/InstallCommand.php

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace Symfony\UX\Toolkit\Command;
1313

14-
use Symfony\Component\Console\Attribute\AsCommand;
1514
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Attribute\AsCommand;
1616
use Symfony\Component\Console\Input\InputArgument;
1717
use Symfony\Component\Console\Input\InputInterface;
1818
use Symfony\Component\Console\Input\InputOption;
@@ -52,7 +52,7 @@ public function __construct(
5252
protected function configure(): void
5353
{
5454
$this
55-
->addArgument('component', InputArgument::OPTIONAL, 'The component name (Ex: Button)')
55+
->addArgument('recipe', InputArgument::OPTIONAL, 'The recipe name (Ex: Button)')
5656
->addOption('kit', 'k', InputOption::VALUE_OPTIONAL, 'The kit name (Ex: "shadcn", or "github.com/user/my-ux-toolkit-kit")')
5757
->addOption(
5858
'destination',
@@ -61,16 +61,16 @@ protected function configure(): void
6161
'The destination directory',
6262
getcwd(),
6363
)
64-
->addOption('force', 'f', InputOption::VALUE_NONE, 'Force the component installation, even if the files already exists')
64+
->addOption('force', 'f', InputOption::VALUE_NONE, 'Force the recipe installation, even if the files already exists')
6565
->setHelp(
6666
<<<EOF
67-
The <info>%command.name%</info> command will install a new UX Component in your project.
67+
The <info>%command.name%</info> command will install a new UX Recipe in your project.
6868
69-
To install a component, use:
69+
To install a recipe, use:
7070
7171
<info>php %command.full_name% Button</info>
7272
73-
To install a component from a specific Kit (either official or external), use the <info>--kit</info> option:
73+
To install a recipe from a specific Kit (either official or external), use the <info>--kit</info> option:
7474
7575
<info>php %command.full_name% Button --kit=shadcn</info>
7676
<info>php %command.full_name% Button --kit=https://github.com/user/my-kit</info>
@@ -89,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8989
$io = new SymfonyStyle($input, $output);
9090

9191
$kitName = $input->getOption('kit');
92-
$componentName = $input->getArgument('component');
92+
$recipeName = $input->getArgument('recipe');
9393

9494
// If the kit name is not explicitly provided, we need to suggest one
9595
if (null === $kitName) {
@@ -99,15 +99,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9999
foreach ($availableKitNames as $availableKitName) {
100100
$kit = $this->registryFactory->getForKit($availableKitName)->getKit($availableKitName);
101101

102-
if (null === $componentName) {
102+
if (null === $recipeName) {
103103
$availableKits[] = $kit;
104-
} elseif (null !== $kit->getRecipe(name: $componentName, type: RecipeType::Component)) {
104+
} elseif (null !== $kit->getRecipe(name: $recipeName)) {
105105
$availableKits[] = $kit;
106106
}
107107
}
108108
// If more than one kit is available, we ask the user which one to use
109109
if (($availableKitsCount = \count($availableKits)) > 1) {
110-
$kitName = $io->choice(null === $componentName ? 'Which kit do you want to use?' : \sprintf('The component "%s" exists in multiple kits. Which one do you want to use?', $componentName), array_map(fn (Kit $kit) => $kit->manifest->name, $availableKits));
110+
$kitName = $io->choice(null === $recipeName ? 'Which kit do you want to use?' : \sprintf('The recipe "%s" exists in multiple kits. Which one do you want to use?', $recipeName), array_map(fn (Kit $kit) => $kit->manifest->name, $availableKits));
111111

112112
foreach ($availableKits as $availableKit) {
113113
if ($availableKit->manifest->name === $kitName) {
@@ -118,9 +118,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
118118
} elseif (1 === $availableKitsCount) {
119119
$kit = $availableKits[0];
120120
} else {
121-
$io->error(null === $componentName
121+
$io->error(null === $recipeName
122122
? 'It seems that no local kits are available and it should not happens. Please open an issue on https://github.com/symfony/ux to report this.'
123-
: \sprintf("The component \"%s\" does not exist in any official kits.\n\nYou can try to run one of the following commands to interactively install components:\n%s\n\nOr you can try one of the community kits https://github.com/search?q=topic:ux-toolkit&type=repositories", $componentName, implode("\n", array_map(fn (string $availableKitName) => \sprintf('$ bin/console %s --kit %s', $this->getName(), $availableKitName), $availableKitNames)))
123+
: \sprintf("The recipe \"%s\" does not exist in any official kits.\n\nYou can try to run one of the following commands to interactively install recipes:\n%s\n\nOr you can try one of the community kits https://github.com/search?q=topic:ux-toolkit&type=repositories", $recipeName, implode("\n", array_map(fn (string $availableKitName) => \sprintf('$ bin/console %s --kit %s', $this->getName(), $availableKitName), $availableKitNames)))
124124
);
125125

126126
return Command::FAILURE;
@@ -130,25 +130,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int
130130
$kit = $registry->getKit($kitName);
131131
}
132132

133-
if (null === $componentName) {
134-
// Ask for the component name if not provided
135-
$componentName = $io->choice('Which component do you want to install?', array_map(fn (Recipe $recipe) => $recipe->manifest->name, $this->getAvailableRecipes($kit)));
136-
$recipe = $kit->getRecipe(name: $componentName, type: RecipeType::Component);
137-
} elseif (null === $recipe = $kit->getRecipe($componentName, type: RecipeType::Component)) {
138-
// Suggest alternatives if component does not exist
139-
$message = \sprintf('The recipe "%s" does not exist.', $componentName);
133+
if (null === $recipeName) {
134+
// Ask for the recipe name if not provided
135+
$recipeName = $io->choice('Which recipe do you want to install?', array_map(fn (Recipe $recipe) => $recipe->manifest->name, $kit->getRecipes()));
136+
$recipe = $kit->getRecipe(name: $recipeName);
137+
} elseif (null === $recipe = $kit->getRecipe($recipeName)) {
138+
// Suggest alternatives if recipe does not exist
139+
$message = \sprintf('The recipe "%s" does not exist.', $recipeName);
140140

141-
$alternativeRecipes = $this->getAlternativeRecipes($kit, $componentName);
142-
$alternativeComponentsCount = \count($alternativeRecipes);
141+
$alternativeRecipes = $this->getAlternativeRecipes($kit, $recipeName);
142+
$alternativeRecipesCount = \count($alternativeRecipes);
143143

144-
if (1 === $alternativeComponentsCount && $input->isInteractive()) {
144+
if (1 === $alternativeRecipesCount && $input->isInteractive()) {
145145
$io->warning($message);
146-
if ($io->confirm(\sprintf('Do you want to install the component "%s" instead?', $alternativeRecipes[0]->manifest->name))) {
146+
if ($io->confirm(\sprintf('Do you want to install the recipe "%s" instead?', $alternativeRecipes[0]->manifest->name))) {
147147
$recipe = $alternativeRecipes[0];
148148
} else {
149149
return Command::FAILURE;
150150
}
151-
} elseif ($alternativeComponentsCount > 0) {
151+
} elseif ($alternativeRecipesCount > 0) {
152152
$io->warning(\sprintf('%s'."\n".'Possible alternatives: "%s"', $message, implode('", "', array_map(fn (Recipe $c) => $c->manifest->name, $alternativeRecipes))));
153153

154154
return Command::FAILURE;
@@ -159,18 +159,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
159159
}
160160
}
161161

162-
$io->writeln(\sprintf('Installing component <info>%s</> from the <info>%s</> kit...', $recipe->manifest->name, $kit->manifest->name));
162+
$io->writeln(\sprintf('Installing recipe <info>%s</> from the <info>%s</> kit...', $recipe->manifest->name, $kit->manifest->name));
163163

164164
$installer = new Installer($this->filesystem, fn (string $question) => $this->io->confirm($question, $input->isInteractive()));
165165
$installationReport = $installer->installRecipe($kit, $recipe, $destinationPath = $input->getOption('destination'), $input->getOption('force'));
166166

167167
if ([] === $installationReport->newFiles) {
168-
$this->io->warning('The component has not been installed.');
168+
$this->io->warning('The recipe has not been installed.');
169169

170170
return Command::SUCCESS;
171171
}
172172

173-
$this->io->success('The component has been installed.');
173+
$this->io->success('The recipe has been installed.');
174174
$this->io->writeln('The following file(s) have been added to your project:');
175175
$this->io->listing(array_map(fn (File $file) => Path::join($destinationPath, $file->sourceRelativePathName), $installationReport->newFiles));
176176

@@ -185,27 +185,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
185185
/**
186186
* @return list<Recipe>
187187
*/
188-
private function getAvailableRecipes(Kit $kit): array
189-
{
190-
$availableComponents = [];
191-
192-
foreach ($kit->getRecipes(type: RecipeType::Component) as $recipe) {
193-
$availableComponents[] = $recipe;
194-
}
195-
196-
return $availableComponents;
197-
}
198-
199-
/**
200-
* @return list<Recipe>
201-
*/
202-
private function getAlternativeRecipes(Kit $kit, string $componentName): array
188+
private function getAlternativeRecipes(Kit $kit, string $recipeName): array
203189
{
204190
$alternative = [];
205191

206-
foreach ($kit->getRecipes(type: RecipeType::Component) as $recipe) {
207-
$lev = levenshtein($componentName, $recipe->manifest->name, 2, 5, 10);
208-
if ($lev <= 8 || str_contains($recipe->manifest->name, $componentName)) {
192+
foreach ($kit->getRecipes() as $recipe) {
193+
$lev = levenshtein($recipeName, $recipe->manifest->name, 2, 5, 10);
194+
if ($lev <= 8 || str_contains($recipe->manifest->name, $recipeName)) {
209195
$alternative[] = $recipe;
210196
}
211197
}

src/Toolkit/src/Dependency/RecipeDependency.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
namespace Symfony\UX\Toolkit\Dependency;
1313

14+
/**
15+
* Represents a dependency on a recipe.
16+
*
17+
* @author Hugo Alliaume <[email protected]>
18+
*
19+
* @internal
20+
*/
1421
class RecipeDependency implements DependencyInterface
1522
{
1623
/**

src/Toolkit/tests/Command/InstallCommandTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ public function testShouldAbleToInstallComponentTableAndItsDependencies()
5353
$testCommand = $this->consoleCommand(\sprintf('ux:install Table --destination="%s"', str_replace('\\', '\\\\', $this->tmpDir)))
5454
->execute()
5555
->assertSuccessful()
56-
->assertOutputContains('Installing component Table from the Shadcn UI kit...')
57-
->assertOutputContains('[OK] The component has been installed.')
56+
->assertOutputContains('Installing recipe Table from the Shadcn UI kit...')
57+
->assertOutputContains('[OK] The recipe has been installed.')
5858
;
5959

6060
// Files should be created
@@ -88,7 +88,7 @@ public function testShouldFailWhenComponentDoesNotExist()
8888
$this->consoleCommand('ux:install Unknown --destination='.$destination)
8989
->execute()
9090
->assertFaulty()
91-
->assertOutputContains('The component "Unknown" does not exist');
91+
->assertOutputContains('The recipe "Unknown" does not exist');
9292
}
9393

9494
public function testShouldWarnWhenComponentFileAlreadyExistsInNonInteractiveMode()
@@ -104,7 +104,7 @@ public function testShouldWarnWhenComponentFileAlreadyExistsInNonInteractiveMode
104104
$this->consoleCommand('ux:install Badge --destination='.$destination)
105105
->execute()
106106
->assertFaulty()
107-
->assertOutputContains('[WARNING] The component has not been installed.')
107+
->assertOutputContains('[WARNING] The recipe has not been installed.')
108108
;
109109
}
110110
}

0 commit comments

Comments
 (0)