Newer
Older
<?php
namespace Drupal\package_manager;
use Composer\Composer;
use Composer\Factory;
use Composer\IO\NullIO;

s_leu
committed
use Composer\Package\PackageInterface;
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use Drupal\Component\Serialization\Json;
/**
* Defines a utility object to get information from Composer's API.
*/
class ComposerUtility {
/**
* The Composer instance.
*
* @var \Composer\Composer
*/
protected $composer;
/**
* The statically cached names of the Drupal core packages.
*
* @var string[]
*/
private static $corePackages;
/**
* Constructs a new ComposerUtility object.
*
* @param \Composer\Composer $composer
* The Composer instance.
*/
public function __construct(Composer $composer) {
$this->composer = $composer;
}
/**
* Creates a utility object using the files in a given directory.
*
* @param string $dir
* The directory that contains composer.json and composer.lock.
*
* @return \Drupal\package_manager\ComposerUtility
* The utility object.
*/
public static function createForDirectory(string $dir): self {
$io = new NullIO();
$configuration = $dir . DIRECTORY_SEPARATOR . 'composer.json';
// The Composer factory requires that either the HOME or COMPOSER_HOME
// environment variables be set, so momentarily set the COMPOSER_HOME
// variable to the directory we're trying to create a Composer instance for.
// We have to do this because the Composer factory doesn't give us a way to
// pass the home directory in.
// @see \Composer\Factory::getHomeDir()
$home = getenv('COMPOSER_HOME');
putenv("COMPOSER_HOME=$dir");
$composer = Factory::create($io, $configuration);
putenv("COMPOSER_HOME=$home");
return new static($composer);
}
/**
* Returns the canonical names of the supported core packages.
*
* @return string[]
* The canonical list of supported core package names, as listed in
* ../core_packages.json.
*/
protected static function getCorePackageList(): array {
if (self::$corePackages === NULL) {
$file = __DIR__ . '/../core_packages.json';
assert(file_exists($file), "$file does not exist.");
$core_packages = file_get_contents($file);
$core_packages = Json::decode($core_packages);
assert(is_array($core_packages), "$file did not contain a list of core packages.");
self::$corePackages = $core_packages;
}
return self::$corePackages;
}
/**

s_leu
committed
* Returns the names of the core packages in the lock file.
*
* All packages listed in ../core_packages.json are considered core packages.
*
* @return string[]
* The names of the required core packages.
*
* @todo Make this return a keyed array of packages, not just names.
*/
public function getCorePackageNames(): array {

s_leu
committed
$core_packages = array_intersect(
array_keys($this->getLockedPackages()),
static::getCorePackageList()
);
// If drupal/core-recommended is present, it supersedes drupal/core, since
// drupal/core will always be one of its direct dependencies.
if (in_array('drupal/core-recommended', $core_packages, TRUE)) {
$core_packages = array_diff($core_packages, ['drupal/core']);
}
return array_values($core_packages);
}
/**
* Returns the names of the core packages in the dev dependencies.
*
* All packages listed in ../core_packages.json are considered core packages.
*
* @return string[]
* The names of the core packages in the dev requirements.
*
* @todo Make this return a keyed array of packages, not just names.
*/
public function getCoreDevPackageNames(): array {
$dev_packages = $this->composer->getPackage()->getDevRequires();
$dev_packages = array_keys($dev_packages);
return array_intersect(static::getCorePackageList(), $dev_packages);
}
/**
* Returns all Drupal extension packages in the lock file.
*
* The following package types are considered Drupal extension packages:
* drupal-module, drupal-theme, drupal-custom-module, and drupal-custom-theme.
*
* @return \Composer\Package\PackageInterface[]
* All Drupal extension packages in the lock file, keyed by name.
*/
public function getDrupalExtensionPackages(): array {

s_leu
committed
$filter = function (PackageInterface $package): bool {
$drupal_package_types = [
'drupal-module',
'drupal-theme',
'drupal-custom-module',
'drupal-custom-theme',
];
return in_array($package->getType(), $drupal_package_types, TRUE);
};
return array_filter($this->getLockedPackages(), $filter);
}
/**
* Returns all packages in the lock file.
*
* @return \Composer\Package\PackageInterface[]
* All packages in the lock file, keyed by name.
*/
protected function getLockedPackages(): array {
$locked_packages = $this->composer->getLocker()
->getLockedRepository(TRUE)
->getPackages();

s_leu
committed
$packages = [];
foreach ($locked_packages as $package) {

s_leu
committed
$key = $package->getName();
$packages[$key] = $package;
}

s_leu
committed
return $packages;