Bootstrap fails when plugin file specifies gem version range

As far as I can tell, it’s legal to specify gem version ranges in a Ruby file, e.g.:

gem 'ruby-saml', '~>1.7'
gem 'omniauth-saml', '~>1.10'

and running a gem install manually will succeed as expected, e.g.:

$ gem install ruby-saml -v '~>1.7'
Successfully installed ruby-saml-1.7.2
Parsing documentation for ruby-saml-1.7.2
Done installing documentation for ruby-saml after 1 seconds
1 gem installed

However, bootstrap will fail when anything other than a plain number is used:

ERROR:  While executing gem ... (Gem::Requirement::BadRequirementError)
    Illformed requirement ["/home/discourse"]
I, [2018-03-13T12:15:08.087153 #16]  INFO -- : gem install ruby-saml -v ~>1.7 -i /var/www/discourse/plugins/discourse-saml/gems/2.4.2 --no-document --ignore-dependencies

You are specifying the gem ruby-saml in /var/www/discourse/plugins/discourse-saml/plugin.rb, however it does not exist!
Looked for: /var/www/discourse/plugins/discourse-saml/gems/2.4.2/specifications/ruby-saml-~>1.7.gemspec

In bundle and rubygems, sure, but in our gem specification for plugins it is not allowed, we need to know the exact version so we can consistently debug our plugins.

3 Likes

I’m not saying plugins shouldn’t use explicit gem versions - I’m saying that bootstrap shouldn’t fail (or should fail with a useful error) when otherwise-legal language syntax/features are used.

Not following, this should fail way earlier in your local dev environment

Why should it fail? 

I am not following you are building a plugin in production without a development environment for the plugin?

We’re obviously talking at cross-purposes here.

I want to be able to specify a gem version range in my plugin, as is legal, as subversion/point releases of gems should maintain backwards-compatibility and only introduce bugfixes.

Attempting to install a plugin which includes a (legal) gem version range fails and does not generate an explicit error message.

Without wanting to put words in your mouth, you appear to be saying this is not supported because you (by policy rather than a technical reason) use explicit gem versions in plugins, and so this should be detected during plugin development.

The following questions are rhetorical.


So - at what point is it made clear that plugins should only use explicit gem versions because of your (internal?) development methodology?

For example, it’s not in https://github.com/discourse/discourse/blob/master/docs/VAGRANT.md or in discourse/DEVELOPER-ADVANCED.md at master · discourse/discourse · GitHub, or following the links from discourse/CONTRIBUTING.md at master · discourse/discourse · GitHub to Discourse Development Contribution Guidelines and from there to Beginner's Guide to Creating Discourse Plugins Part 1: Creating a basic plugin this isn’t - as far as I can see - mentioned at any point.

Hence my question - why should this fail?


My take-away from this is that as a “beginning” plugin developer I must adapt my normal practices to match how you write Discourse, much in the same way Rails isn’t really Ruby. It appears the barrier for entry is higher than I had originally thought and so needs more work on my part to create a development environment (with all its moving parts) that matches as closely as possible those in use by others, rather than developing on a “production mirror” (which, for example, normally makes sure that any changes I make will be exactly reflected when deployed).

Core is specific about gem versions cause we ship with a lockfile, plugins simply follow the same pattern

Maybe bundler out to be amended to properly allow for cascading lockfiles, but it has nothing like that today

3 Likes