Question

I'm developing an app in Ruby. It started as a small command-line utility but it's now getting quite big, with basically three different apps: A command-line util, a Sinatra web server and another server exposing a RESTful web API, all three relying on a database for doing various different things with the same data.

Following this great article by Yehuda Katz, I'm managing all my dependencies with bundler, and have my Gemfile.lock committed into source control. I rely on many third party dependencies, and for some I do care about specific versions (because of known issues).

Now, all three parts of the app are using some common infrastructure code: mainly a Data Access Layer used to communicate with a database, and one or two other common classes. But other than that they can be considered separate apps. If this were some other language, like Java, I'd probably split it into three applications, and put the common DAL code in a class-library referenced by all three.

In Ruby, I know that gems should be used to package code libraries. So I was thinking about creating three gems for the apps and fourth gem with the common library code. Or maybe three "non-gem" apps, all relying on a common gem.

The thing is, I'm not sure how to manage third-party dependencies that way. In the aforementioned article, YK states that for gem development the Gemfile.lock should not be added to source control. In my case, I do need specific versions of some of the third-party gems I'm using, and the Gemfile.lock has been very important during an initial deployment recently. Also, I don't intend on publishing these gems, as it's not an open source project. I just need a nice clean way to manage my dependencies, both third-party gems and internal.

So...

  • Should I create four different gems?
  • Should I just split it into three apps, all relying on one common gem I'll create?
  • What about the Gemfile.lock? In which of these would it be wise to keep it in source control, and why?
  • Is there some downside or advantage developing something as a gem vs just a plain app, if it's not intended to be published?

I would love to hear some suggestions and opinions from seasoned Rubyists about how to do this...

Thanks.

Was it helpful?

Solution

Gems don't need the Gemfile.lock file, since their dependencies are declared in the gemspec.
To add a dependency use add_runtime_dependency:

spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'

But this is not specific enough for deployment scenarios!
Well, true, but for a gem deployment means it is deployed into an application. The application should have the Gemfile.lock file to pin down the specific library versions.

An application deployment needs to be fully replicable, so build numbers of all library versions should be meticulously maintained. Gems, on the other hand, strive to be compatible to as many versions as possible to be re-usable, otherwise, one gem update will break all the gems which depend on it.

As for the rest of your question (whether and how to split your app into gems) - I believe this is not the right forum for that, as it is too broad for SO, but I wish you luck on your endeavor for making your software more manageable and more re-usable!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top