2

I'm trying to fold league/omnipay into a plugin suite in such a way that it's modular. So the core project module has this composer.json:

{
    "require": {
        "league/omnipay": "^3.2"
    },
    "config": {
        "allow-plugins": {
            "php-http/discovery": true
        }
    }
}

All good. When I do composer require or composer update it grabs all the dependencies and dumps them in plugins/core_module/vendor/.

Next I want to bundle up a bunch of companion plugins that offer various specific gateways: PayPal, Stripe, WorldPay. etc so users can choose which ones they want for their site.

PayPal, for example, requires the following composer.json:

{
    "require": {
        "league/omnipay": "^3.2",
        "omnipay/paypal": "^3.0"
    }
}

The annoying thing is that it downloads a bunch of dependencies into its own vendor directory that also include the ones already downloaded in the core module. That's duplication I don't want.

What I would like is to somehow instruct Composer (and, by inference, my PHP application when it needs to load the classes) that "the league/omnipay library is over there, mate --->" so it only downloads/updates the extra stuff it needs specifically for the PayPal integration. Likewise for Square, Stripe, etc modules.

I've tried messing around with things like this:

...
    "repositories": [
    {
      "type": "path",
      "url": "../core_module/vendor/omnipay"
    }
  ],
...

but it still downloads the entire dependency tree into the gateway's own vendordirectory, so I'm probably not using the feature correctly.

Once installed, the various plugins all sit alongside one another:

plugins/core_module
plugins/gateway_paypal
plugins/gateway_stripe
plugins/...

so relative paths will work.

How can I instruct Composer to only download/maintain one copy of each dependency and not duplicate the ones in core_module?

Or, if that's not possible, what other options are available? (symlinks might work, but I need to consider Windows users too).

One thing I have not yet tried, which might work according to other SO topics, is adding this to each gateway plugin's composer.json:

{
    "config": {
        "vendor-dir": "../core_module/vendor/"
    }
}

In theory, I suspect that will then install the dependencies to the sibling directory's vendor folder which may then "see" that there are already some dependencies there and just fill in the gaps.

My only reservation is this approach doesn't keep things compartmentalised, so if someone decides to ditch PayPal and go with Stripe in future, unpicking it is more complicated and potentially leaves behind disk cruft. If the PayPal gateway code and dependencies could be confined to its own gateway_paypal folder, deletion is simply a case of removing the entire directory. I'd much prefer that than polluting the core_module vendor dir, if possible.

13
  • 1
    I totally understand that, but that packages are rarely very big in size. The advantage of "duplication" is, that every app has its very own dependencies and scopes. Imagine you upgrade one package wich has some deprecations, then you will have to check all applications and you may kill them all at once. Another way to work around this, which comes into my mind is using symlinks. But you should really think of the risks. Commented May 8 at 9:30
  • 1
    That's duplication I don't want...can you explain why it's a problem for you? Duplication is not, per se, a problem on its own...so what are the consequences of duplication which you are trying to avoid here? As Markus said, having all your plugins depend on a single copy of the dependencies potentially introduces extra overhead of testing whenever you want to update a library, and might prevent an upgrade from happening across the whole suite if it causes a test to fail in just one of them. You might be happy with that risk, but you haven't articulated the benefits you want in return. Commented May 8 at 10:31
  • 1
    That is not true. Symlinks work very well on Windows. I am using it all the time. Use mklink /J for that. Commented May 21 at 8:24
  • 1
    that's an additional 24MB of needless space...agreed it's probably unnecessary, but then again in modern terms that's a completely trivial amount of storage. You wouldn't even notice - that's half a dozen photos from your phone, or a handful of documents. If this was 1995 I might take that complaint more seriously. It's annoying but I wouldn't say it's worth re-engineering your whole setup for. However that's just my opinion, obviously. Commented May 21 at 8:50
  • 1
    What are you talking about symlink() calls within PHP? What does this have to do with composer paths? And now you are mixing two complete different OS? This totally off topic your asked question. Also I can not wrap my mind about why you would risk app damage over standardized best practice. Do you run it on a SD card that 24 MB does matter? Commented May 21 at 11:25

0

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.