Composer: Skipping a dependency

Today Henrik Bjørnskov asked me if it was possible to prevent Composer from installing a package which is a dependency of another package you wish to install. The answer is yes, and this is how:

Let’s say we’re installing bakery/blueberry-cupcake 1.0 which depends on farm/blueberries 1.0. However we’d rather just have the cupcake and there’s no alternative cupcake package. So we’ll tell composer there’s an alternative to farm/blueberries 1.0 called imaginary/blueberries which aren’t blueberries at all.

{
    "repositories": [{
        "type": "package",
        "package": {
            "name": "imaginary/blueberries",
            "type": "metapackage",
            "version": "1.0",
            "replace": {"farm/blueberries": "*"}
        }
    }],
    "require": {
        "bakery/blueberry-cupcake": "1.0",
        "imaginary/blueberries": "1.0"
    }
}

Metapackage is a package type which lets composer know that there are no actual source files associated with the package and it exists solely for composer.

After running composer update to update the lock file and install packages composer show --installed informs us that we have successfully installed bakery/blueberry-cupcake with imaginary/blueberries:

$ composer show --installed
bakery/blueberry-cupcake 1.0
imaginary/blueberries 1.0

A simpler solution without a metapackage is available in this situation as well. Your project can directly replace the farm/blueberries package too.

{
    "require": {
        "bakery/blueberry-cupcake": "1.0"
    },
    "replace": {
        "farm/blueberries": "*"
    }

However this solution will lead to problems if you wish to depend on this package from other packages which want to keep the original dependency.

Need Composer Consulting? Contact me at composer-consulting@forumatic.com.
Advertisement

3 comments

    1. Indeed, I had already updated the article with “replace”:{“farm/blueberries”:”*”} as an alternative. But this results in problems when publishing the package as explained in the last sentence of the article now. But of course provide would work in this case too, unless farm/bluerries itself only gets installed as a provider of a 4th package. In that situation farm/blueberries would still be installed because “provide” does not create a conflict with the farm/blueberries package.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s