mirror of
https://github.com/danog/psalm.git
synced 2025-01-08 14:08:43 +01:00
80 lines
2.6 KiB
PHP
80 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace Psalm\Internal\PluginManager;
|
|
|
|
use Psalm\Internal\Composer;
|
|
use RuntimeException;
|
|
|
|
use function array_filter;
|
|
use function json_encode;
|
|
use function rtrim;
|
|
use function urlencode;
|
|
|
|
use const DIRECTORY_SEPARATOR;
|
|
use const JSON_THROW_ON_ERROR;
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
class PluginListFactory
|
|
{
|
|
private string $project_root;
|
|
|
|
private string $psalm_root;
|
|
|
|
public function __construct(string $project_root, string $psalm_root)
|
|
{
|
|
$this->project_root = $project_root;
|
|
$this->psalm_root = $psalm_root;
|
|
}
|
|
|
|
public function __invoke(string $current_dir, ?string $config_file_path = null): PluginList
|
|
{
|
|
try {
|
|
$config_file = new ConfigFile($current_dir, $config_file_path);
|
|
} catch (RuntimeException $exception) {
|
|
$config_file = null;
|
|
}
|
|
$composer_lock = new ComposerLock($this->findLockFiles());
|
|
|
|
return new PluginList($config_file, $composer_lock);
|
|
}
|
|
|
|
/** @return non-empty-array<int,string> */
|
|
private function findLockFiles(): array
|
|
{
|
|
// use cases
|
|
// 1. plugins are installed into project vendors - composer.lock is PROJECT_ROOT/composer.lock
|
|
// 2. plugins are installed into separate composer environment (either global or bamarni-bin)
|
|
// - composer.lock is PSALM_ROOT/../../../composer.lock
|
|
// 3. plugins are installed into psalm vendors - composer.lock is PSALM_ROOT/composer.lock
|
|
// 4. none of the above - use stub (empty virtual composer.lock)
|
|
|
|
if ($this->psalm_root === $this->project_root) {
|
|
// managing plugins for psalm itself
|
|
$composer_lock_filenames = [
|
|
Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR)),
|
|
];
|
|
} else {
|
|
$composer_lock_filenames = [
|
|
Composer::getLockFilePath(rtrim($this->project_root, DIRECTORY_SEPARATOR)),
|
|
Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR) . '/../../..'),
|
|
Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR)),
|
|
];
|
|
}
|
|
|
|
$composer_lock_filenames = array_filter($composer_lock_filenames, 'is_readable');
|
|
|
|
if (empty($composer_lock_filenames)) {
|
|
$stub_composer_lock = (object)[
|
|
'packages' => [],
|
|
'packages-dev' => [],
|
|
];
|
|
$composer_lock_filenames[] = 'data:application/json,'
|
|
. urlencode(json_encode($stub_composer_lock, JSON_THROW_ON_ERROR));
|
|
}
|
|
|
|
return $composer_lock_filenames;
|
|
}
|
|
}
|