php-composer-reader icon indicating copy to clipboard operation
php-composer-reader copied to clipboard

Add ability to check installed package versions

Open tacman opened this issue 9 months ago • 3 comments

I'd love to be able to check the installed version of a package, not just the one defined in the require/require-dev section.

In particular, I want to know if Symfony 7.3-beta2 is already installed, and if not run a few commands, including composer update (after setting the minimum stability to beta, etc.)

I realize that this means reading the composer.lock file (if it's available) as well, so I know it's not a trivial task.

tacman avatar May 11 '25 12:05 tacman

so you mean to find out transitive dependencies which are not defined in the composer.json? Because you can read the require or the require-dev section already.

nadar avatar May 11 '25 17:05 nadar

No. I mean which version is actually installed.

I have minimum stability set to beta and want to know the exact version that is installed which lives in the lock file

tacman avatar May 11 '25 20:05 tacman

ah i see, just did a quick chatgpt research, should not be a problem (if true, its not verified):

use Composer\InstalledVersions;

$packageName = 'monolog/monolog';

if (InstalledVersions::isInstalled($packageName)) {
    $prettyVersion = InstalledVersions::getPrettyVersion($packageName);
    $versionRef    = InstalledVersions::getReference($packageName);

    echo sprintf(
        "%s is installed at %s (commit %s)\n",
        $packageName,
        $prettyVersion,
        $versionRef
    );
} else {
    echo "$packageName is not installed.\n";
}

just do this.

adding the option to this library could look like this (if true, not tested)


use Composer\Factory;
use Composer\IO\NullIO;

// build a composer\Composer instance (no I/O)
$io       = new NullIO;
$composer = Factory::create($io, __DIR__ . '/composer.json');
$locker   = $composer->getLocker();

// load the lock data
$lockData = $locker->getLockData();

// $lockData is an array with keys 'packages', 'packages-dev', etc.
$allPackages = array_merge(
    $lockData['packages'] ?? [],
    $lockData['packages-dev'] ?? []
);

$packageName = 'monolog/monolog';
foreach ($allPackages as $pkg) {
    if ($pkg['name'] === $packageName) {
        printf(
            "%s => version %s (installed as %s)\n",
            $pkg['name'],
            $pkg['version'],
            $pkg['source']['reference'] ?? $pkg['dist']['reference'] ?? 'n/a'
        );
        break;
    }
}

nadar avatar May 12 '25 06:05 nadar