1

for educational proposes I write my own PHP application and add a little plugin system. The application itself uses composer to manage required dependencies.

It is possible that a plugin have his own dependencies (Guzzle etc.) and that two plugins have some overlapping dependencies. To reduce storage and avoid any interference I will use composer with composer installers for the plugins:

/src
/plugins
  /DemoPlugin
    composer.json
    /src
    /config
    ...
/vendor
composer.phar
composer.json
...

So it is possible to install a plugin easy over the "main" application and composer handles all dependencies automatically (incl. autoloading).

But this workflow creates a problem that I cant solve at the moment: It requires that the user uses composer require app/plugin-name and download the plugin from the network. But I cant guarantee that every plugin can be installed this way. For example: Paid plugins, company internal plugins or simple dev plugins which only exists as "zip file".

With composer installers the plugins are stored in a different directory, in place of the "classic" vendor directory. But from my understanding it is not possible to copy a zip based plugin into this plugin folder. I cant find any method to start the installation of the plugin (downloading vendor, maybe setup scripts etc.).

This concludes into my question: It is possible to tell the composer instance from the "main application" that a plugin should be installed (downloading vendor, maybe setup scripts etc.) but dont start a download because the plugin is already placed correctly?

If I run composer install in the plugin directory, composer will download the vendor directly into the plugin directory - with all the problems (duplicate dependencies, no integration into the autoload etc.).

I appreciate any help!

Shutterfly
  • 199
  • 12

1 Answers1

0

What you are looking for is a path repository.

To follow your example you can use the following composer.json

{
    "name": "test/test",
    "type": "test",
    "repositories": [{
        "type": "path",
        "url": "./plugins/**/"
    }],
    "require": {
        "guzzlehttp/guzzle": "^6.3"
    }
}

Where you have the following structure:

├── composer.json
├── composer.lock
└── plugins
    └── DemoPlugin
        └── composer.json

You can eventually require your plugin as you would do usually:

composer require "test/demo:@dev"

And you will see the dependencies are not duplicated (you do not need to install the DemoPlugin package).

Entilore
  • 170
  • 11