Skip to content

Commit 034e7bc

Browse files
committed
added support for unpacking Composer packages
1 parent c3980f5 commit 034e7bc

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

src/Command/RequireCommand.php

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,23 @@
1212
namespace Symfony\Flex\Command;
1313

1414
use Composer\Command\RequireCommand as BaseRequireCommand;
15+
use Composer\DependencyResolver\Pool;
16+
use Composer\Factory;
17+
use Composer\Json\JsonFile;
18+
use Composer\Json\JsonManipulator;
19+
use Composer\Package\Link;
20+
use Composer\Package\Package;
21+
use Composer\Package\Version\VersionParser;
1522
use Symfony\Component\Console\Input\InputInterface;
23+
use Symfony\Component\Console\Input\InputOption;
1624
use Symfony\Component\Console\Output\OutputInterface;
1725
use Symfony\Flex\PackageResolver;
1826

1927
class RequireCommand extends BaseRequireCommand
2028
{
2129
private $resolver;
30+
private $composer;
31+
private $manipulator;
2232

2333
public function __construct(PackageResolver $resolver)
2434
{
@@ -27,14 +37,81 @@ public function __construct(PackageResolver $resolver)
2737
parent::__construct();
2838
}
2939

40+
protected function configure()
41+
{
42+
parent::configure();
43+
$this->addOption('unpack', null, InputOption::VALUE_NONE, 'Unpack Symfony packs in composer.json.');
44+
}
45+
3046
protected function execute(InputInterface $input, OutputInterface $output)
3147
{
32-
$input->setArgument('packages', $this->resolver->resolve($input->getArgument('packages'), true));
48+
$packages = $this->resolver->resolve($input->getArgument('packages'), true);
49+
$packages = $this->unpack($packages, $input->getOption('unpack'), $input->getOption('sort-packages'), $input->getOption('dev'));
50+
if (!$packages) {
51+
// we need at least one package for the command to work properly
52+
$packages = ['symfony/flex'];
53+
}
54+
55+
$input->setArgument('packages', $packages);
3356

3457
if ($input->hasOption('no-suggest')) {
3558
$input->setOption('no-suggest', true);
3659
}
3760

3861
return parent::execute($input, $output);
3962
}
63+
64+
private function unpack(array $packages, bool $unpack, bool $sortPackages, bool $dev): array
65+
{
66+
$versionParser = new VersionParser();
67+
$this->composer = $this->getComposer();
68+
$json = new JsonFile(Factory::getComposerFile());
69+
$this->manipulator = new JsonManipulator(file_get_contents($json->getPath()));
70+
$sortPackages = $sortPackages || $this->composer->getConfig()->get('sort-packages');
71+
$pkgs = [];
72+
73+
foreach ($versionParser->parseNameVersionPairs($packages) as $package) {
74+
if (!$this->addDep($package['name'], $package['version'] ?? '*', $unpack, $sortPackages, $dev)) {
75+
$pkgs[] = $package['name'].(isset($package['version']) ? ':'.$package['version'] : '');
76+
}
77+
}
78+
79+
file_put_contents($json->getPath(), $this->manipulator->getContents());
80+
81+
return $pkgs;
82+
}
83+
84+
private function addDep(string $name, string $version, bool $unpack, bool $sortPackages, bool $dev)
85+
{
86+
$pkg = $this->composer->getRepositoryManager()->findPackage($name, $version ?? '*');
87+
if ('symfony-profile' !== $pkg->getType() && ($pkg->getType() !== 'symfony-pack' || !$unpack)) {
88+
return false;
89+
}
90+
if (0 === count($pkg->getRequires()) + count($pkg->getDevRequires())) {
91+
// don't unpack empty packs, they are markers we need to keep
92+
return false;
93+
}
94+
95+
foreach ($pkg->getRequires() as $link) {
96+
if ('php' === $link->getTarget()) {
97+
continue;
98+
}
99+
if (!$this->addDep($link->getTarget(), '*', true, $sortPackages, $dev)) {
100+
if (!$this->manipulator->addLink($dev ? 'require-dev' : 'require', $link->getTarget(), $link->getPrettyConstraint(), $sortPackages)) {
101+
throw new \RuntimeException(sprintf('Unable to unpack package "%s".', $link->getTarget()));
102+
}
103+
}
104+
}
105+
if ('symfony-profile' === $pkg->getType()) {
106+
foreach ($pkg->getDevRequires() as $link) {
107+
if (!$this->addDep($link->getTarget(), '*', true, $sortPackages, true)) {
108+
if (!$this->manipulator->addLink('require-dev', $link->getTarget(), $link->getPrettyConstraint(), $sortPackages)) {
109+
throw new \RuntimeException(sprintf('Unable to unpack package "%s".', $link->getTarget()));
110+
}
111+
}
112+
}
113+
}
114+
115+
return true;
116+
}
40117
}

0 commit comments

Comments
 (0)