Skip to content

Commit 896e709

Browse files
author
Denis Brumann
committed
Adds file locking for CopyFromRecipe.
- Allows passing lock to configurators. - Stores copied files in lock. - Ignores locked files on remove.
1 parent 87d511b commit 896e709

21 files changed

+225
-84
lines changed

src/Configurator.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ public function __construct(Composer $composer, IOInterface $io, Options $option
4444
];
4545
}
4646

47-
public function install(Recipe $recipe, array $options = [])
47+
public function install(Recipe $recipe, Lock $lock, array $options = [])
4848
{
4949
$manifest = $recipe->getManifest();
5050
foreach (array_keys($this->configurators) as $key) {
5151
if (isset($manifest[$key])) {
52-
$this->get($key)->configure($recipe, $manifest[$key], $options);
52+
$this->get($key)->configure($recipe, $manifest[$key], $lock, $options);
5353
}
5454
}
5555
}
5656

57-
public function unconfigure(Recipe $recipe)
57+
public function unconfigure(Recipe $recipe, Lock $lock)
5858
{
5959
$manifest = $recipe->getManifest();
6060
foreach (array_keys($this->configurators) as $key) {
6161
if (isset($manifest[$key])) {
62-
$this->get($key)->unconfigure($recipe, $manifest[$key]);
62+
$this->get($key)->unconfigure($recipe, $manifest[$key], $lock);
6363
}
6464
}
6565
}

src/Configurator/AbstractConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Composer\Composer;
1515
use Composer\IO\IOInterface;
16+
use Symfony\Flex\Lock;
1617
use Symfony\Flex\Options;
1718
use Symfony\Flex\Path;
1819
use Symfony\Flex\Recipe;
@@ -35,9 +36,9 @@ public function __construct(Composer $composer, IOInterface $io, Options $option
3536
$this->path = new Path($options->get('root-dir'));
3637
}
3738

38-
abstract public function configure(Recipe $recipe, $config, array $options = []);
39+
abstract public function configure(Recipe $recipe, $config, Lock $lock, array $options = []);
3940

40-
abstract public function unconfigure(Recipe $recipe, $config);
41+
abstract public function unconfigure(Recipe $recipe, $config, Lock $lock);
4142

4243
protected function write($messages)
4344
{

src/Configurator/BundlesConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class BundlesConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $bundles, array $options = [])
22+
public function configure(Recipe $recipe, $bundles, Lock $lock, array $options = [])
2223
{
2324
$this->write('Enabling the package as a Symfony bundle');
2425
$file = $this->getConfFile();
@@ -38,7 +39,7 @@ public function configure(Recipe $recipe, $bundles, array $options = [])
3839
$this->dump($file, $registered);
3940
}
4041

41-
public function unconfigure(Recipe $recipe, $bundles)
42+
public function unconfigure(Recipe $recipe, $bundles, Lock $lock)
4243
{
4344
$this->write('Disabling the Symfony bundle');
4445
$file = $this->getConfFile();

src/Configurator/ComposerScriptsConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
use Composer\Factory;
1515
use Composer\Json\JsonFile;
1616
use Composer\Json\JsonManipulator;
17+
use Symfony\Flex\Lock;
1718
use Symfony\Flex\Recipe;
1819

1920
/**
2021
* @author Fabien Potencier <[email protected]>
2122
*/
2223
class ComposerScriptsConfigurator extends AbstractConfigurator
2324
{
24-
public function configure(Recipe $recipe, $scripts, array $options = [])
25+
public function configure(Recipe $recipe, $scripts, Lock $lock, array $options = [])
2526
{
2627
$json = new JsonFile(Factory::getComposerFile());
2728

@@ -35,7 +36,7 @@ public function configure(Recipe $recipe, $scripts, array $options = [])
3536
file_put_contents($json->getPath(), $manipulator->getContents());
3637
}
3738

38-
public function unconfigure(Recipe $recipe, $scripts)
39+
public function unconfigure(Recipe $recipe, $scripts, Lock $lock)
3940
{
4041
$json = new JsonFile(Factory::getComposerFile());
4142

src/Configurator/ContainerConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class ContainerConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $parameters, array $options = [])
22+
public function configure(Recipe $recipe, $parameters, Lock $lock, array $options = [])
2223
{
2324
$this->write('Setting parameters');
2425
$this->addParameters($parameters);
2526
}
2627

27-
public function unconfigure(Recipe $recipe, $parameters)
28+
public function unconfigure(Recipe $recipe, $parameters, Lock $lock)
2829
{
2930
$this->write('Unsetting parameters');
3031
$target = $this->options->get('root-dir').'/'.$this->options->expandTargetDir('%CONFIG_DIR%/services.yaml');

src/Configurator/CopyFromPackageConfigurator.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,45 @@
1212
namespace Symfony\Flex\Configurator;
1313

1414
use LogicException;
15+
use Symfony\Flex\Lock;
1516
use Symfony\Flex\Recipe;
1617

1718
/**
1819
* @author Fabien Potencier <[email protected]>
1920
*/
2021
class CopyFromPackageConfigurator extends AbstractConfigurator
2122
{
22-
public function configure(Recipe $recipe, $config, array $options = [])
23+
public function configure(Recipe $recipe, $config, Lock $lock, array $options = [])
2324
{
2425
$this->write('Setting configuration and copying files');
2526
$packageDir = $this->composer->getInstallationManager()->getInstallPath($recipe->getPackage());
26-
$this->copyFiles($config, $packageDir, $this->options->get('root-dir'), $options['force'] ?? false);
27+
$options = array_merge($this->options->toArray(), $options);
28+
29+
$this->copyFiles($config, $packageDir, $options);
2730
}
2831

29-
public function unconfigure(Recipe $recipe, $config)
32+
public function unconfigure(Recipe $recipe, $config, Lock $lock)
3033
{
3134
$this->write('Removing configuration and files');
3235
$packageDir = $this->composer->getInstallationManager()->getInstallPath($recipe->getPackage());
3336
$this->removeFiles($config, $packageDir, $this->options->get('root-dir'));
3437
}
3538

36-
private function copyFiles(array $manifest, string $from, string $to, bool $overwrite = false)
39+
private function copyFiles(array $manifest, string $from, array $options)
3740
{
41+
$to = $options['root-dir'] ?? '.';
3842
foreach ($manifest as $source => $target) {
3943
$target = $this->options->expandTargetDir($target);
4044
if ('/' === substr($source, -1)) {
41-
$this->copyDir($this->path->concatenate([$from, $source]), $this->path->concatenate([$to, $target]), $overwrite);
45+
$this->copyDir($this->path->concatenate([$from, $source]), $this->path->concatenate([$to, $target]), $options);
4246
} else {
4347
$targetPath = $this->path->concatenate([$to, $target]);
4448
if (!is_dir(\dirname($targetPath))) {
4549
mkdir(\dirname($targetPath), 0777, true);
4650
$this->write(sprintf('Created <fg=green>"%s"</>', $this->path->relativize(\dirname($targetPath))));
4751
}
4852

49-
$this->copyFile($this->path->concatenate([$from, $source]), $targetPath, $overwrite);
53+
$this->copyFile($this->path->concatenate([$from, $source]), $targetPath, $options);
5054
}
5155
}
5256
}
@@ -67,7 +71,7 @@ private function removeFiles(array $manifest, string $from, string $to)
6771
}
6872
}
6973

70-
private function copyDir(string $source, string $target, bool $overwrite)
74+
private function copyDir(string $source, string $target, array $options)
7175
{
7276
if (!is_dir($target)) {
7377
mkdir($target, 0777, true);
@@ -82,13 +86,14 @@ private function copyDir(string $source, string $target, bool $overwrite)
8286
$this->write(sprintf('Created <fg=green>"%s"</>', $this->path->relativize($targetPath)));
8387
}
8488
} elseif (!file_exists($targetPath)) {
85-
$this->copyFile($item, $targetPath, $overwrite);
89+
$this->copyFile($item, $targetPath, $options);
8690
}
8791
}
8892
}
8993

90-
public function copyFile(string $source, string $target, bool $overwrite = false)
94+
public function copyFile(string $source, string $target, array $options)
9195
{
96+
$overwrite = $options['force'] ?? false;
9297
if (!$this->options->shouldWriteFile($target, $overwrite)) {
9398
return;
9499
}

src/Configurator/CopyFromRecipeConfigurator.php

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,91 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class CopyFromRecipeConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $config, array $options = [])
22+
public function configure(Recipe $recipe, $config, Lock $lock, array $options = [])
2223
{
2324
$this->write('Setting configuration and copying files');
24-
$this->copyFiles($config, $recipe->getFiles(), $this->options->get('root-dir'), $options['force'] ?? false);
25+
$options = array_merge($this->options->toArray(), $options);
26+
27+
$lock->add($recipe->getName(), ['files' => $this->copyFiles($config, $recipe->getFiles(), $options)]);
2528
}
2629

27-
public function unconfigure(Recipe $recipe, $config)
30+
public function unconfigure(Recipe $recipe, $config, Lock $lock)
2831
{
2932
$this->write('Removing configuration and files');
30-
$this->removeFiles($config, $recipe->getFiles(), $this->options->get('root-dir'));
33+
$this->removeFiles($config, $this->getRemovableFilesFromRecipeAndLock($recipe, $lock), $this->options->get('root-dir'));
34+
}
35+
36+
private function getRemovableFilesFromRecipeAndLock(Recipe $recipe, Lock $lock): array
37+
{
38+
$lockedFiles = array_unique(
39+
array_reduce(
40+
array_column($lock->all(), 'files'),
41+
function (array $carry, array $package) {
42+
return array_merge($carry, $package);
43+
},
44+
[]
45+
)
46+
);
47+
48+
$removableFiles = $recipe->getFiles();
49+
foreach ($lockedFiles as $file) {
50+
if (isset($removableFiles[$file])) {
51+
unset($removableFiles[$file]);
52+
}
53+
}
54+
55+
return $removableFiles;
3156
}
3257

33-
private function copyFiles(array $manifest, array $files, string $to, bool $overwrite = false)
58+
private function copyFiles(array $manifest, array $files, array $options): array
3459
{
60+
$copiedFiles = [];
61+
$to = $options['root-dir'] ?? '.';
62+
3563
foreach ($manifest as $source => $target) {
3664
$target = $this->options->expandTargetDir($target);
3765
if ('/' === substr($source, -1)) {
38-
$this->copyDir($source, $this->path->concatenate([$to, $target]), $files, $overwrite);
66+
$copiedFiles = array_merge(
67+
$copiedFiles,
68+
$this->copyDir($source, $this->path->concatenate([$to, $target]), $files, $options)
69+
);
3970
} else {
40-
$this->copyFile($this->path->concatenate([$to, $target]), $files[$source]['contents'], $files[$source]['executable'], $overwrite);
71+
$copiedFiles[] = $this->copyFile($this->path->concatenate([$to, $target]), $files[$source]['contents'], $files[$source]['executable'], $options);
4172
}
4273
}
74+
75+
return $copiedFiles;
4376
}
4477

45-
private function copyDir(string $source, string $target, array $files, bool $overwrite = false)
78+
private function copyDir(string $source, string $target, array $files, array $options): array
4679
{
80+
$copiedFiles = [];
4781
foreach ($files as $file => $data) {
4882
if (0 === strpos($file, $source)) {
4983
$file = $this->path->concatenate([$target, substr($file, \strlen($source))]);
50-
$this->copyFile($file, $data['contents'], $data['executable'], $overwrite);
84+
$copiedFiles[] = $this->copyFile($file, $data['contents'], $data['executable'], $options);
5185
}
5286
}
87+
88+
return $copiedFiles;
5389
}
5490

55-
private function copyFile(string $to, string $contents, bool $executable, bool $overwrite = false)
91+
private function copyFile(string $to, string $contents, bool $executable, array $options): string
5692
{
93+
$overwrite = $options['force'] ?? false;
94+
$basePath = $options['root-dir'] ?? '.';
95+
$copiedFile = str_replace($basePath.\DIRECTORY_SEPARATOR, '', $to);
96+
5797
if (!$this->options->shouldWriteFile($to, $overwrite)) {
58-
return;
98+
return $copiedFile;
5999
}
60100

61101
if (!is_dir(\dirname($to))) {
@@ -68,6 +108,8 @@ private function copyFile(string $to, string $contents, bool $executable, bool $
68108
}
69109

70110
$this->write(sprintf('Created <fg=green>"%s"</>', $this->path->relativize($to)));
111+
112+
return $copiedFile;
71113
}
72114

73115
private function removeFiles(array $manifest, array $files, string $to)

src/Configurator/EnvConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class EnvConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $vars, array $options = [])
22+
public function configure(Recipe $recipe, $vars, Lock $lock, array $options = [])
2223
{
2324
$this->write('Added environment variable defaults');
2425

@@ -28,7 +29,7 @@ public function configure(Recipe $recipe, $vars, array $options = [])
2829
}
2930
}
3031

31-
public function unconfigure(Recipe $recipe, $vars)
32+
public function unconfigure(Recipe $recipe, $vars, Lock $lock)
3233
{
3334
$this->unconfigureEnvFiles($recipe, $vars);
3435
$this->unconfigurePhpUnit($recipe, $vars);

src/Configurator/GitignoreConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class GitignoreConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $vars, array $options = [])
22+
public function configure(Recipe $recipe, $vars, Lock $lock, array $options = [])
2223
{
2324
$this->write('Added entries to .gitignore');
2425

@@ -39,7 +40,7 @@ public function configure(Recipe $recipe, $vars, array $options = [])
3940
}
4041
}
4142

42-
public function unconfigure(Recipe $recipe, $vars)
43+
public function unconfigure(Recipe $recipe, $vars, Lock $lock)
4344
{
4445
$file = $this->options->get('root-dir').'/.gitignore';
4546
if (!file_exists($file)) {

src/Configurator/MakefileConfigurator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Flex\Configurator;
1313

14+
use Symfony\Flex\Lock;
1415
use Symfony\Flex\Recipe;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
1819
*/
1920
class MakefileConfigurator extends AbstractConfigurator
2021
{
21-
public function configure(Recipe $recipe, $definitions, array $options = [])
22+
public function configure(Recipe $recipe, $definitions, Lock $lock, array $options = [])
2223
{
2324
$this->write('Added Makefile entries');
2425

@@ -53,7 +54,7 @@ public function configure(Recipe $recipe, $definitions, array $options = [])
5354
}
5455
}
5556

56-
public function unconfigure(Recipe $recipe, $vars)
57+
public function unconfigure(Recipe $recipe, $vars, Lock $lock)
5758
{
5859
if (!file_exists($makefile = $this->options->get('root-dir').'/Makefile')) {
5960
return;

0 commit comments

Comments
 (0)