Ocramius / PackageVersions

:package: Composer addon to efficiently get installed packages' version numbers
MIT License
3.22k stars 67 forks source link

Add possibility to check for the existence of an dependency too #42

Closed QuingKhaos closed 7 years ago

QuingKhaos commented 7 years ago

Use Case: Check if a dependency isn't installed at all and if it is installed check the version constraint.

Scenario: Having optional code, which should be only executed if a given dependency is installed and at the right version. Currently doing the following:

<?php

use Composer\Semver\Semver;
use PackageVersions\Versions;

try {
    $embedVersion = Versions::getVersion('embed/embed');
    if (!Semver::satisfies($embedVersion, '^3.0')) {
        throw new DependencyUnsatisfiedException(\sprintf(
            'You must install embed/embed:^3.0 to create videos from remote. Got: %s',
            \explode('@', $embedVersion)[0]
        ));
    }
} catch (\OutOfBoundsException $e) {
    throw new DependencyUnsatisfiedException('You must install embed/embed:^3.0 to create videos from remote.');
}

Either a new hasDependency() or a new $throw parameter could work. Don't know which is better for the public API. A $throw parameter wouldn't cause an extra call. With it my code would look like this:

<?php

use Composer\Semver\Semver;
use PackageVersions\Versions;

$embedVersion = Versions::getVersion('embed/embed', false); // returns version or null
if (!embedVersion || !Semver::satisfies($embedVersion, '^3.0')) {
    throw new DependencyUnsatisfiedException(\sprintf('You must install embed/embed:^3.0 to create videos from remote.'));
}
Ocramius commented 7 years ago

This seems like a weird use-case for this library. What I could do is exposing the constant being generated (unsure if I want to keep BC compliance there though), and then you'd be on your own.

Still, I believe that you should try something different for your embed/embed dependency:

  1. Ask the user to explicitly pass in an EmbedAdapter, provided by a secondary package of yours, optionally installed, requiring embed/embed:^3
  2. Add a "conflict": {"embed/embed": "<3 || >=4"}, then use class_exists()
QuingKhaos commented 7 years ago

The constant being generated is already exposed because default visibility is public. But I assume it's nothing of the public API, especially it won't be available, when --no-scripts was called and it falls back to the FallbackVersions.

Maybe I overestimated the use cases of the lib and the class_exists() check is the way to go in my use case :blush:

malukenho commented 7 years ago

Closed as invalid