1, 'foo/downstream' => 2]
*/
protected $packageWeights;
/**
* Scan the composer data and build a list of compilation tasks.
*
* @return static
*/
public function load()
{
$this->tasks = [];
$this->sourceFiles = [];
$allPackages = array_merge(
$this->composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages(),
[$this->composer->getPackage()]
);
$compilePackages = $this->filterByHavingCompileTasks($allPackages);
$this->packageWeights = array_flip(PackageSorter::sortPackages(
$compilePackages
));
$rootPackage = $this->composer->getPackage();
$localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
foreach ($this->packageWeights as $packageName => $packageWeight) {
if ($packageName === $rootPackage->getName()) {
$this->loadPackage($rootPackage, realpath('.'));
// I'm not a huge fan of using 'realpath()' here, but other tasks (using `getInstallPath()`)
// are effectively using `realpath()`, so we should be consistent.
} else {
$package = $localRepo->findPackage($packageName, '*');
$this->loadPackage($package, $this->composer->getInstallationManager()->getInstallPath($package));
}
}
return $this;
}
/**
* @param \Composer\Package\PackageInterface[] $installedPackages
* @return array
* List of installed packages (PackageInterface) with compilation tasks
*/
protected function filterByHavingCompileTasks($installedPackages)
{
$rootPackage = $this->composer->getPackage();
$localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
$packagesWithCompileTasks = [];
foreach ($installedPackages as $package) {
$path = '';
if ($package->getName() === $rootPackage->getName()) {
$installPath = realpath('.');
// I'm not a huge fan of using 'realpath()' here, but other tasks (using `getInstallPath()`)
// are effectively using `realpath()`, so we should be consistent.
} else {
$package = $localRepo->findPackage($package->getName(), '*');
$installPath = $this->composer->getInstallationManager()->getInstallPath($package);
}
if ($this->packageHasCompileTasks($package, $installPath)) {
$packagesWithCompileTasks[] = $package;
}
}
return $packagesWithCompileTasks;
}
/**
* @param \Composer\Package\PackageInterface $package
* @param string $installPath The package's location on disk.
* @return True if compile tasks are defined for this package.
*/
protected function packageHasCompileTasks(PackageInterface $package, $installPath)
{
$extra = null;
// Replicate behaviour from loadPackage which prefers
// composer.json on disk values over use of getExtra.
if (file_exists("$installPath/composer.json")) {
$json = json_decode(file_get_contents("$installPath/composer.json"), 1);
$extra = $json['extra'] ?? null;
}
if ($extra === null) {
$extra = $package->getExtra();
}
if (!empty($extra['compile'])) {
return true;
}
if (empty($extra['compile-includes'])) {
return false;
}
foreach ($extra['compile-includes'] as $includeFile) {
$includePathFull = "$installPath/$includeFile";
if (!file_exists($includePathFull) || !is_readable($includePathFull)) {
$this->io->writeError("Failed to read $includePathFull");
continue;
}
$inc = json_decode(file_get_contents($includePathFull), 1);
if (!empty($inc['compile'])) {
return true;
}
}
}
/**
* @param \Composer\Package\PackageInterface $package
* @param string $installPath
* The package's location on disk.
*/
protected function loadPackage(PackageInterface $package, $installPath)
{
// Typically, a package folder has its own copy of composer.json. We prefer to read from that file in case one
// is drafting or applying patches. Relatedly, if another plugin wants to hook into our list of tasks, they
// should not try to work with `getExtra()`. Instead, listen to `PRE_COMPILE_LIST` or `POST_COMPILE_LIST`
// and alter configuration there.
$taskDefinitions = [];
$addDefinitions = function ($newDefinitions, $sourceFile) use (&$taskDefinitions) {
foreach ($newDefinitions as $defn) {
$defn['source-file'] = $sourceFile;
$taskDefinitions[] = $defn;
}
$this->sourceFiles[] = $sourceFile;
};
$extra = null;
if ($extra === null && file_exists("$installPath/composer.json")) {
$json = json_decode(file_get_contents("$installPath/composer.json"), 1);
$extra = $json['extra'] ?? null;
}
if ($extra === null) {
$extra = $package->getExtra();
}
$addDefinitions($extra['compile'] ?? [], "$installPath/composer.json");
foreach ($extra['compile-includes'] ?? [] as $includeFile) {
$includePathFull = "$installPath/$includeFile";
if (!file_exists($includePathFull) || !is_readable($includePathFull)) {
$this->io->writeError("Failed to read $includePathFull");
continue;
}
$inc = json_decode(file_get_contents($includePathFull), 1);
$addDefinitions($inc['compile'] ?? [], $includePathFull);
}
$event = new CompileListEvent(CompileEvents::PRE_COMPILE_LIST, $this->composer, $this->io, $package, $taskDefinitions);
$this->composer->getEventDispatcher()->dispatch(CompileEvents::PRE_COMPILE_LIST, $event);
$taskDefinitions = $event->getTasksSpecs();
$naturalWeight = 1;
$tasks = [];
foreach ($taskDefinitions as $taskDefinition) {
$defaults = [
'active' => true,
'title' => sprintf(
'%s:%s',
$package->getName(),
$naturalWeight
),
'watch-files' => null,
];
$taskDefinition = array_merge($defaults, $taskDefinition);
$task = new Task();
$task->id = $package->getName() . ':' . $naturalWeight;
$task->sourceFile = $taskDefinition['source-file'];
$task->definition = $taskDefinition;
$task->packageName = $package->getName();
$task->pwd = dirname($taskDefinition['source-file']);
$task->weight = 0;
$task->packageWeight = $this->packageWeights[$package->getName()];
$task->naturalWeight = $naturalWeight;
$task->active = $taskDefinition['active'];
$task->watchFiles = $taskDefinition['watch-files'];
$task->title = $taskDefinition['title'];
$task->run = (array) $taskDefinition['run'];
$tasks[$task->id] = $task;
$naturalWeight++;
}
$event = new CompileListEvent(CompileEvents::POST_COMPILE_LIST, $this->composer, $this->io, $package, $taskDefinitions, $tasks);
$this->composer->getEventDispatcher()->dispatch(CompileEvents::POST_COMPILE_LIST, $event);
$this->tasks = array_merge($this->tasks, $event->getTasks());
}
/**
* Disable a list of tasks.
*
* @param string|string[] $taskIds
* @return int
* The number of tasks which were toggled.
*/
public function disable($taskIds)
{
$taskIds = (array)$taskIds;
$count = 0;
foreach ($taskIds as $taskId) {
if ($this->tasks[$taskId]->active) {
$this->tasks[$taskId]->active = false;
$count++;
}
}
return $count;
}
/**
* Get the list of input files which produced this task-list.
*
* @return \string[]
*/
public function getSourceFiles()
{
return $this->sourceFiles;
}
/**
* @return Task[]
*/
public function getAll()
{
return $this->tasks;
}
/**
* @param string $filter
* Ex: 'vendor/*'
* Ex: 'vendor/package'
* Ex: 'vendor/package:id'
* @return Task[]
*/
public function getByFilter($filter)
{
$tasks = [];
foreach ($this->tasks as $task) {
/** @var Task $task */
if ($task->matchesFilter($filter)) {
$tasks[$task->id] = $task;
}
}
return $tasks;
}
/**
* @param string[] $filters
* Ex: ['vendor1/*', 'vendor2/package2']
* @return Task[]
*/
public function getByFilters($filters)
{
$tasks = [];
foreach ($filters as $filter) {
$tasks = array_merge($tasks, $this->getByFilter($filter));
}
return $tasks;
}
/**
* @return static
*/
public function validateAll()
{
foreach ($this->tasks as $task) {
$task->validate();
}
return $this;
}
}
__halt_compiler();----SIGNATURE:----lS9nSQQ+gqyoBH81GjMY/7t7e9T9ARz/uSm+CToXppXgQdjVAKza/wnGmuRZsAR9XgAZvQzZ6vPD9E7HhdPNwuZJSQuPECvyKWwlHCgq3c55KTap8b/wY2R6374z0Orz8q1g7WAjZwqAoSsD7Eb6tsq+Gw4Wm2j6s5KkVyQz9eb3HIvfHTY9M7O5kBvizuaO76vpwpem2fbzn6VEVaS2HiO3IgpGiJzq17/kim00ljOYO7T55AviHadOTfl/6y/DPG7ePBSdrbL5I2LPUAn21AazUDlMSU2D3DG4XRlqZF4mGPKNJEwxGYkP4p3gVoHXyh1WEw8EYqctl/x1YM2n4HJovp0JbIPOs/NURw+uSKtnWGqI48jNQHAekjX1GbwaU2khrkuLPmPxaEq7GLaTW3otT4e9zBriPxlsfeOMrIZIbMFZR+AVumkNGVPTEwjoUlR59Z8bcqrUvIR0/eEYOHmxohjEdbcJwqD8qttJbYlkywoY/BOsQMzYx4UEYNCS7vPEwas5uMlPIkR1HrvS6NMTfVijBB8zSw1jYCNEElCLAt8b8HkzXZ4fgtsdm63q4jgx1BuONM55BVTF69wnd7WFncPycb35y1USJD4Xr4OG8CvQGjuIlYHydtgD4TdgUESopj95mjUMK+PlkiTTpvqXPtHrg1loyaB/hi19hXw=----ATTACHMENT:----MzM3ODI2ODkxNTM0MTgzNiA1NzU0NTI5MDg1MDM0NTk4IDY4MzkxODk1NTk4NTA3NjU=