Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Optional dependencies #8184

Closed
mabar opened this issue Jun 12, 2019 · 7 comments
Closed

[RFC] Optional dependencies #8184

mabar opened this issue Jun 12, 2019 · 7 comments

Comments

@mabar
Copy link

mabar commented Jun 12, 2019

We have tens of packages which optionally integrate with others. To ensure these optional dependencies are installed with correct version if user require them we need to write this:

{
  "require-dev": {
    "vendor/package": "^3.0.0"
  },
  "conflict": {
    "vendor/package": "<3.0.0 || >=4.0.0"
  }
}

Preferred syntax is:

{
  "optional": {
    "vendor/package": "^3.0.0"
  }
}

which would always install package as dev dependency and check correct version if user require package itself.

@alcohol
Copy link
Member

alcohol commented Jun 12, 2019

I am having a hard time understanding what you actually want. The example is not very clear. Either a package is required, or it is not required. There is no such thing as optional. You seem to hint at some kind of conflict resolution, but it is not clear to me how optional packages could solve conflicts.

@mabar
Copy link
Author

mabar commented Jun 12, 2019

Many packages, like Monolog (see composer.json) contains integration of packages which you could use optionally, so they are listed in require-dev instead of require. It allows user to choose if they want install that optional package and use it with Monolog. Problem with that solution is that it allows user install incompatible version of optional package. Currently we need write range of incompatible versions of optional package in conflict to prevent installation of incompatible version.
Proposed solution with optional would act like require-dev during development, but if an user require our optional dependency then version constraint from optional would be checked same way as would be if package is listed in require

@alcohol
Copy link
Member

alcohol commented Jun 12, 2019

contains integration of packages which you could use optionally, so they are listed in require-dev instead of require

No, that is wrong. I suggest you read up on the difference between require and require-dev.

https://getcomposer.org/doc/04-schema.md#require

https://getcomposer.org/doc/04-schema.md#require-dev

Packages listed in require-dev are packages used during the development process (such as phpunit, etc). Packages that do not belong in a production artifact. require-dev is also only read from the root project composer.json, it is completely ignored for dependencies.

@mabar
Copy link
Author

mabar commented Jun 12, 2019

@Seldaek As a author of Monolog, which uses optional dependencies I hope you may understand.

Monolog's current master have require-dev for "elasticsearch/elasticsearch": "^6.0" because there is ElasticsearchHandler which is used by user, not just during development.
There is nothing what would disallow me install e.g. version 1.0.0 of elasticsearch/elasticsearch package which is not compatible with ElasticsearchHandler

@mabar
Copy link
Author

mabar commented Jun 12, 2019

@alcohol I've read all the docs several times. Current solution of optional dependencies is a workaround and I know it. It's why I wrote proposal of new optional parameter.

@Seldaek
Copy link
Member

Seldaek commented Jun 12, 2019

Monolog is a very good example of doing it wrong really.. ElasticSearchHandler should be published as a standalone package with a requirement on both monolog and elasticsearch/elasticsearch, so the version can be enforced. That is why I don't accept any new handlers anymore with external requirements.

Adding optional dependencies are not worth the trouble IMO in composer..

@Seldaek Seldaek closed this as completed Jun 12, 2019
@mabar
Copy link
Author

mabar commented Aug 26, 2019

Related to #6255, #6321 and #6965 for anyone looking for this

Best solution is surely no optional dependencies at all. But sometimes creating packages for every single "optional" dependency is just not well spent time.
I have a translator package which will have once completed integrations into around 15 packages and also bridges between these packages. I would have around 20 and maybe more single-class packages for single thing.
Even symfony uses these bad optional dependencies, e.g. here and here so I guess it's not just my issue

If you guys ever wish to implement it then I would suggest following, BC syntax (at least for these who update composer)

"suggest": {
    "aws/aws-sdk-php": {
        "message": "Description why is it suggested",
        "version": "^1.0.0"
    }
}

"aws/aws-sdk-php": "Description" syntax would still work

Assuming you are going to ever agree, I may send a PR once I don't have too much work with my own open-source.

Composer is great tool btw, I'm sorry if it sounded like I think anything other

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants