Get the composer version of installed modules

Maybe my code can be useful for you (tested in the observer):

/**
 * @var \Magento\Framework\App\DeploymentConfig
 */
protected $deploymentConfig;

/**
 * @var \Magento\Framework\Component\ComponentRegistrarInterface
 */
protected $componentRegistrar;

/**
 * @var \Magento\Framework\Filesystem\Directory\ReadFactory
 */
protected $readFactory;

/**
 * @param \Magento\Framework\App\DeploymentConfig $deploymentConfig
 * @param \Magento\Framework\Component\ComponentRegistrarInterface $componentRegistrar
 * @param \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
 */
public function __construct(
    \Magento\Framework\App\DeploymentConfig $deploymentConfig,
    \Magento\Framework\Component\ComponentRegistrarInterface $componentRegistrar,
    \Magento\Framework\Filesystem\Directory\ReadFactory $readFactory
) {
    $this->deploymentConfig = $deploymentConfig;
    $this->componentRegistrar = $componentRegistrar;
    $this->readFactory = $readFactory;
}

/**
 * Get module composer version
 *
 * @param $moduleName
 * @return \Magento\Framework\Phrase|string|void
 */
public function getModuleVersion($moduleName)
{
    $path = $this->componentRegistrar->getPath(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        $moduleName
    );
    $directoryRead = $this->readFactory->create($path);
    $composerJsonData = $directoryRead->readFile('composer.json');
    $data = json_decode($composerJsonData);

    return !empty($data->version) ? $data->version : __('Read error!');
}

/**
 * Collect enabled modules version
 *
 * @param Observer $observer
 */
public function execute(Observer $observer)
{
    $modules = $this->deploymentConfig->get('modules');
    $modulesWithVersion = [];
    foreach ($modules as $moduleName => $isEnabled) {
        if (!$isEnabled) {
            continue;
        }

        $modulesWithVersion[$moduleName] = $this->getModuleVersion($moduleName);
    }
}
  1. Collects all enabled module names from the config
  2. Reads their composer.json one-by-one and saves version

Result (in debug):

Result


I need something that will work on both install methods (composers and clone repo).

That's probably the tricky part as you said because you can't use the Composer packages classes directly when installed via GitHub.

My suggestion would be to loop through the modules folder and use a mix of the following:

  • Magento\Framework\Composer\ComposerJsonFinder::findComposerJson() to find the composer.json file
  • then use \Composer\Factory::create(new BufferIo(), $composerJsonFile) to create a composer instance.
  • once you have that , I'm pretty sure you can call getConfig() on the Composer file to get the details of that file.

NB: all I'm saying here is highly theorical based on my assumptions