Skip to content

Commit 5f92875

Browse files
feature #963 Add --yes flag to recipes:install command to overwrite all files without asking (shyim)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- Add --yes flag to recipes:install command to overwrite all files without asking When I run `recipes:install --reset --force -n` **no files are overwritten**, as the default as been set to false. There is currently also no way to accept that, so I changed it back to `true` Commits ------- 9c70161 Add --yes flag to recipes:install command to overwrite all files without asking
2 parents 52fea95 + 9c70161 commit 5f92875

File tree

8 files changed

+110
-7
lines changed

8 files changed

+110
-7
lines changed

src/Command/InstallRecipesCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ protected function configure()
4646
->addArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Recipes that should be installed.')
4747
->addOption('force', null, InputOption::VALUE_NONE, 'Overwrite existing files when a new version of a recipe is available')
4848
->addOption('reset', null, InputOption::VALUE_NONE, 'Reset all recipes back to their initial state (should be combined with --force)')
49+
->addOption('yes', null, InputOption::VALUE_NONE, "Answer prompt questions with 'yes' for all questions.")
4950
;
5051
}
5152

@@ -135,7 +136,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
135136
}
136137
}
137138

138-
$this->flex->update(new UpdateEvent($force, (bool) $input->getOption('reset')), $operations);
139+
$this->flex->update(new UpdateEvent($force, (bool) $input->getOption('reset'), (bool) $input->getOption('yes')), $operations);
139140

140141
if ($force) {
141142
$output = [

src/Configurator/CopyFromPackageConfigurator.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ public function copyFile(string $source, string $target, array $options)
124124
return;
125125
}
126126

127-
$overwrite = $options['force'] ?? false;
128-
if (!$this->options->shouldWriteFile($target, $overwrite)) {
127+
if (!$this->options->shouldWriteFile($target, $options['force'] ?? false, $options['assumeYesForPrompts'] ?? false)) {
129128
return;
130129
}
131130

src/Configurator/CopyFromRecipeConfigurator.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,10 @@ private function copyDir(string $source, string $target, array $files, array $op
127127

128128
private function copyFile(string $to, string $contents, bool $executable, array $options): string
129129
{
130-
$overwrite = $options['force'] ?? false;
131130
$basePath = $options['root-dir'] ?? '.';
132131
$copiedFile = $this->getLocalFilePath($basePath, $to);
133132

134-
if (!$this->options->shouldWriteFile($to, $overwrite)) {
133+
if (!$this->options->shouldWriteFile($to, $options['force'] ?? false, $options['assumeYesForPrompts'] ?? false)) {
135134
return $copiedFile;
136135
}
137136

src/Event/UpdateEvent.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ class UpdateEvent extends Event
1818
{
1919
private $force;
2020
private $reset;
21+
private $assumeYesForPrompts;
2122

22-
public function __construct(bool $force, bool $reset)
23+
public function __construct(bool $force, bool $reset, bool $assumeYesForPrompts)
2324
{
2425
$this->name = ScriptEvents::POST_UPDATE_CMD;
2526
$this->force = $force;
2627
$this->reset = $reset;
28+
$this->assumeYesForPrompts = $assumeYesForPrompts;
2729
}
2830

2931
public function force(): bool
@@ -35,4 +37,9 @@ public function reset(): bool
3537
{
3638
return $this->reset;
3739
}
40+
41+
public function assumeYesForPrompts(): bool
42+
{
43+
return $this->assumeYesForPrompts;
44+
}
3845
}

src/Flex.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ function ($value) {
447447
$this->io->writeError(\sprintf(' - Configuring %s', $this->formatOrigin($recipe)));
448448
$this->configurator->install($recipe, $this->lock, [
449449
'force' => $event instanceof UpdateEvent && $event->force(),
450+
'assumeYesForPrompts' => $event instanceof UpdateEvent && $event->assumeYesForPrompts(),
450451
]);
451452
$manifest = $recipe->getManifest();
452453
if (isset($manifest['post-install-output'])) {
@@ -471,6 +472,7 @@ function ($value) {
471472
foreach ($postInstallRecipes as $recipe) {
472473
$this->configurator->postInstall($recipe, $this->lock, [
473474
'force' => $event instanceof UpdateEvent && $event->force(),
475+
'assumeYesForPrompts' => $event instanceof UpdateEvent && $event->assumeYesForPrompts(),
474476
]);
475477
}
476478
}

src/Options.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function expandTargetDir(string $target): string
6262
return file_exists($rootDir.'/'.$otherPhpunitDistFile) ? $otherPhpunitDistFile : $result;
6363
}
6464

65-
public function shouldWriteFile(string $file, bool $overwrite): bool
65+
public function shouldWriteFile(string $file, bool $overwrite, bool $skipQuestion): bool
6666
{
6767
if (isset($this->writtenFiles[$file])) {
6868
return false;
@@ -81,6 +81,10 @@ public function shouldWriteFile(string $file, bool $overwrite): bool
8181
return true;
8282
}
8383

84+
if ($skipQuestion) {
85+
return true;
86+
}
87+
8488
exec('git status --short --ignored --untracked-files=all -- '.ProcessExecutor::escape($file).' 2>&1', $output, $status);
8589

8690
if (0 !== $status) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Flex\Tests\Command;
13+
14+
use Composer\Console\Application;
15+
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Console\Tester\CommandTester;
17+
use Symfony\Flex\Command\InstallRecipesCommand;
18+
use Symfony\Flex\Event\UpdateEvent;
19+
use Symfony\Flex\Flex;
20+
21+
class InstallRecipesCommandTest extends TestCase
22+
{
23+
public function testCommandFlagsPassedDown()
24+
{
25+
$flex = $this->createMock(Flex::class);
26+
$flex->method('update')->willReturnCallback(function (UpdateEvent $event) {
27+
$this->assertTrue($event->reset());
28+
$this->assertTrue($event->assumeYesForPrompts());
29+
});
30+
31+
$command = new InstallRecipesCommand($flex, __DIR__);
32+
$application = new Application();
33+
$application->add($command);
34+
$command = $application->find('symfony:recipes:install');
35+
36+
$tester = new CommandTester($command);
37+
$tester->execute([
38+
'--reset' => true,
39+
'--yes' => true,
40+
]);
41+
}
42+
}

tests/OptionsTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Flex\Tests;
13+
14+
use Composer\IO\IOInterface;
15+
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Process\Process;
17+
use Symfony\Flex\Options;
18+
19+
class OptionsTest extends TestCase
20+
{
21+
public function testShouldWrite()
22+
{
23+
@mkdir(FLEX_TEST_DIR);
24+
(new Process(['git', 'init'], FLEX_TEST_DIR))->mustRun();
25+
(new Process(['git', 'config', 'user.name', 'Unit test'], FLEX_TEST_DIR))->mustRun();
26+
(new Process(['git', 'config', 'user.email', ''], FLEX_TEST_DIR))->mustRun();
27+
28+
$filePath = FLEX_TEST_DIR.'/a.txt';
29+
file_put_contents($filePath, 'a');
30+
(new Process(['git', 'add', '-A'], FLEX_TEST_DIR))->mustRun();
31+
(new Process(['git', 'commit', '-m', 'setup of original files'], FLEX_TEST_DIR))->mustRun();
32+
33+
file_put_contents($filePath, 'b');
34+
35+
$this->assertTrue((new Options([], null))->shouldWriteFile('non-existing-file.txt', false, false));
36+
$this->assertFalse((new Options([], null))->shouldWriteFile($filePath, false, false));
37+
38+
// We don't have an IO, so we don't write the file
39+
$this->assertFalse((new Options([], null))->shouldWriteFile($filePath, true, false));
40+
41+
// We have an IO, and it allowed to write the file
42+
$io = $this->createMock(IOInterface::class);
43+
$io->expects($this->once())->method('askConfirmation')->willReturn(true);
44+
$this->assertTrue((new Options([], $io))->shouldWriteFile($filePath, true, false));
45+
46+
// We skip all questions, so we're able to write
47+
$this->assertTrue((new Options([], null))->shouldWriteFile($filePath, true, true));
48+
}
49+
}

0 commit comments

Comments
 (0)