Change record status: 
Introduced in branch: 
3.0.x
Introduced in version: 
3.0.0
Description: 

#3334994: Add new InstalledPackagesList which does not rely on Composer API to get package info introduced a new way to get information about the packages installed by Composer in a particular directory.

The Composer inspector (package_manager.composer_inspector) has a getInstalledPackagesList() method. You pass it a path containing a composer.lock file:

$this->composerInspector->getInstalledPackagesList('/path/to/drupal/project');

It will run composer show and compile the information into an instance of Drupal\package_manager\InstalledPackagesList. To improve performance, these lists are cached in memory until the composer.lock file changes.

InstalledPackagesList is an array-like object that cannot be changed (nothing can be added or removed). It consists of InstalledPackage objects, keyed by package name. Each of those is a simple value object containing the package name, type, version (non-normalized), and optional installation path (some package types, like metapackages, don't have paths) as public properties.

InstalledPackage also has a getProjectName() method, which will try to scan the package's directory for an info file containing a project key. (This only works if the package type is a Drupal module/theme/profile, and comes from the drupal vendor.)

InstalledPackagesList has a getPackageByDrupalProjectName() method, which is the inverse of InstalledPackage::getProjectName(). You can pass it the name of a Drupal project, and it will try to find the Composer package which installed that project (returned as an InstalledPackage object).

InstalledPackagesList also contains the following methods from ComposerUtility: getPackagesNotIn(), getPackagesWithDifferentVersionsIn(), and getCorePackages(). These behave exactly the same way as they do in ComposerUtility, except that they return new InstalledPackagesList objects containing the requested subsets.

Impacts: 
Module developers