Many version controls systems today have some form of “external” or “submodule” feature that’s basically just a way to embed one repository (or a piece of one) in another. After working with a few of these systems in a variety of scenarios, I’ve come to the conclusion that they are more trouble than they’re worth. But I didn’t know of any good alternatives… until now.
I’ve discovered that Bundler is very useful as a “repository manager.” It’s not just useful for Ruby projects; you don’t even need to use gems! You can keep all projects/libraries as simple repositories (with no externals) wherever you want, and have Bundler keep track of things for you. (A similar but slightly different method is also very useful for managing tools. See: Stealing Ruby Gems)
For each repository that is depended on by other repositories, put a .gemspec file and a tiny ruby script in the root. (The Ruby file can relocated.) They should look something like this:
The Ruby script is simply a little helper file that we can use to get the path to our library, whether it’s in some local directory, an installed gem, or an installed gem fetched from a git repo.
In a project that depends on these libraries, add a Gemfile similar to the following:
Bundler gives you a lot of control over where your “gem” can come from. You can have it pull from a local directory, a git repository, or a regular gem. See Bundler’s page on gemfiles for more information.
In your project, add a Ruby script like this to get the path of your library (no matter where it is):
If you’re using Rake or Ceedling or another Ruby-based build system, you can just require my_awesome_lib directly and use My_Awesome_Lib.location where ever a path to your library is needed.
On the command line, go to where you have the Gemfile and type:
And that’s it! You should now be able to use my_awesome_lib_path.rb (or similar) to get the path to your library (for use in your include paths in your build system or whatever).
If you want to change where you’re pulling your library from, you just have to change the Gemfile.