Skip to content

Commit d3a5f3e

Browse files
[10.x] Add commonly reusable Composer related commands from 1st party packages (#48096)
* Add commonly reusable Composer related commands from 1st party packages. Signed-off-by: Mior Muhammad Zaki <[email protected]> * formatting --------- Signed-off-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent 85ad68c commit d3a5f3e

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/Illuminate/Support/Composer.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace Illuminate\Support;
44

5+
use Closure;
56
use Illuminate\Filesystem\Filesystem;
7+
use RuntimeException;
8+
use Symfony\Component\Console\Output\OutputInterface;
69
use Symfony\Component\Process\PhpExecutableFinder;
710
use Symfony\Component\Process\Process;
811

@@ -35,6 +38,97 @@ public function __construct(Filesystem $files, $workingPath = null)
3538
$this->workingPath = $workingPath;
3639
}
3740

41+
/**
42+
* Install the given Composer packages into the application.
43+
*
44+
* @param array<int, string> $packages
45+
* @param bool $dev
46+
* @param \Closure|\Symfony\Component\Console\Output\OutputInterface|null $output
47+
* @return bool
48+
*/
49+
protected function requirePackages(array $packages, bool $dev = false, Closure|OutputInterface $output = null)
50+
{
51+
$composer = $this->findComposer();
52+
53+
$command = explode(' ', $composer);
54+
55+
array_push($command, 'require');
56+
57+
$command = array_merge(
58+
$command,
59+
$packages,
60+
$dev ? ['--dev'] : [],
61+
);
62+
63+
return 0 === (new Process($command, cwd: $this->workingPath, env: ['COMPOSER_MEMORY_LIMIT' => '-1']))
64+
->setTimeout(null)
65+
->run(
66+
$output instanceof OutputInterface
67+
? function ($type, $line) use ($output) {
68+
$output->write(' '.$line);
69+
} : $output
70+
);
71+
}
72+
73+
/**
74+
* Remove the given Composer packages from the application.
75+
*
76+
* @param array<int, string> $packages
77+
* @param bool $dev
78+
* @param \Closure|\Symfony\Component\Console\Output\OutputInterface|null $output
79+
* @return bool
80+
*/
81+
protected function removePackages(array $packages, bool $dev = false, Closure|OutputInterface $output = null)
82+
{
83+
$composer = $this->findComposer();
84+
85+
$command = explode(' ', $composer);
86+
87+
array_push($command, 'remove');
88+
89+
$command = array_merge(
90+
$command,
91+
$packages,
92+
$dev ? ['--dev'] : [],
93+
);
94+
95+
return 0 === (new Process($command, cwd: $this->workingPath, env: ['COMPOSER_MEMORY_LIMIT' => '-1']))
96+
->setTimeout(null)
97+
->run(
98+
$output instanceof OutputInterface
99+
? function ($type, $line) use ($output) {
100+
$output->write(' '.$line);
101+
} : $output
102+
);
103+
}
104+
105+
/**
106+
* Modify the "composer.json" file contents using the given callback.
107+
*
108+
* @param callable(array):array $callback
109+
* @return void
110+
*
111+
* @throw \RuntimeException
112+
*/
113+
public function modify(callable $callback)
114+
{
115+
$composerFile = "{$this->workingPath}/composer.json";
116+
117+
if (! file_exists($composerFile)) {
118+
throw new RuntimeException("Unable to locate `composer.json` file at [{$this->workingPath}].");
119+
}
120+
121+
$composer = json_decode(file_get_contents($composerFile), true, 512, JSON_THROW_ON_ERROR);
122+
123+
file_put_contents(
124+
$composerFile,
125+
json_encode(
126+
call_user_func($callback, $composer),
127+
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
128+
)
129+
);
130+
}
131+
38132
/**
39133
* Regenerate the Composer autoloader files.
40134
*

0 commit comments

Comments
 (0)