Every once in a while, I want my gem to depend on another gem, but without some of that other gem's dependencies (because they aren't all necessary for what I'm using). For example, middleman vendors Padrino because it just wants part of Padrino's helpers and we don't want to pull in all of Padrino's many dependencies. Another example is a Middleman extension I'm building that wraps a Rails extension - I want to depend on and use the classes defined in the Rails extension, but I don't want to bring along the Rails dependency from the extension gem.
I'm imagining a pattern like this:
s.add_dependency("ngmin-rails", ["~> 0.4.0"], :without => ["rails"])
should the gem you're depending on not just fix its dependency tree to pull in what it needs and not everything else?
I'd tend to agree with @robgleeson -- if it's not a true dependency but instead a built-in integration, it shouldn't be in the gemspec.
Optional dependencies are a longstanding feature request with many complicated issues surrounding their implementation. I have not bothered to attempt it due to more pressing needs.
I would be willing to assist in implementing it as an advisor, though, but be warned that there are implications beyond the obvious.
Thanks for the feedback. It's true that I could try to convince the other projects to refactor their gems into multiple gems in order to isolate the dependencies (for example, factoring out the support code from the railtie part of a Rails plugin so I can use just the support code). That'll be difficult for all the different gems this applies to, however - this is why we end up vendoring the code every once in a while rather than declaring a dependency.
@drbrain do you think this is similar to optional dependencies? Or just that optional dependencies would be one solution to this problem (convince the plugin gems to model their Rails dependencies as optional)?
Oh, another point that I should bring up is that I don't think it's really appropriate to say that plugins shouldn't declare dependencies on the thing they plug in to - how else should they express a version requirement? For example, if I make a Rails plugin that only works on Rails ~> 4.0, shouldn't I declare that dependency in order to help my users only use a compatible version?
if you depend on all of rails then that'd make sense. if you depend on a small subset of rails (like active_support) then a dependency on ~> 4.0.0 of active_support would make more sense to me. runtime dependencies should satisfy code dependencies and if your code doesn't use active_record then that's not a code dependency.
yeah, I understand the real world doesn't always work like the ideal world. rack-test is unlikely to be needed in production but probably bootstraps some code in actionpack for testing controllers or something like that. "rails"(the metagam) has a lot of dependencies and it does a great job on depending on the universe for you, so if you can limit your scope to "actionpack" it can speed up install, boot time and probably runtime performance too. i understand even if you did that, you would depend on "rack-test" through actionpack and its unlikely to be something you need to ship to production(although i do not know for sure).
This sounds to me to be similar in scope to the optional dependencies.
I normally declare a dependency in plugins to be sure the correct API and features are present for the plugin.
PS: ~> 4.0.0 and similar dependencies with two dots is almost always wrong
that's true, "~> 4.0" is probably better.