{"id":203,"date":"2010-02-14T08:05:20","date_gmt":"2010-02-14T15:05:20","guid":{"rendered":"http:\/\/blog.monnet-usa.com\/?p=203"},"modified":"2010-02-14T09:55:17","modified_gmt":"2010-02-14T16:55:17","slug":"hosting-my-own-ruby-gems-repository","status":"publish","type":"post","link":"https:\/\/blog.monnet-usa.com\/?p=203","title":{"rendered":"Hosting My Own Ruby Gems Repository"},"content":{"rendered":"<h3>What Is A Gem Repository?<\/h3>\n<p>For people not familiar with Ruby, a gem is a code package (a sort of zip file) containing all Ruby source files and resources for a given application or library.<\/p>\n<p>Gems are typically stored in hosted repositories like <a href='#rf'>RubyForge<\/a>, <a href='#gc'>GemCutter<\/a>, or GitHub so that applications and libraries can be shared on the Internet. However anyone can create a repository to host gems as long as the repository conforms to the structure and indexing defined by <a href='#rgps'>RubyGems<\/a> the Ruby package manager.<\/p>\n<p>In the past I have used <a href='#rf'>RubyForge<\/a> as a co-maintainer of the <a href='#rp'>ruby-paypal library<\/a> and I have used <a href='#gc'>GemCutter<\/a> as well.<\/p>\n<h3>So why would I want to create my own repository?<\/h3>\n<p>Well, I am hosting some Ruby apps on <a href='#hu'>Heroku<\/a> which requires you to specify where your external gems come from. This is nice as you can specify a <a href='#rf'>RubyForge<\/a>, <a href='#gc'>GemCutter<\/a>, GitHub or any repository for that matter. However as gems evolve, sometimes older version do not remain available on these repositories. Rails has solved that problem by freezing the gems in its own vendor directory. But if you use another framework (like <a href='#rc'>Camping<\/a> for me, or Sinatra for others), you need a place to freeze your dependencies. So creating and hosting your own repository gives you that flexibility to control which versions of external gems you need.<\/p>\n<h3>Creating the repository<\/h3>\n<p>So I followed instructions from the <a href='#gr'>gem repository creation manual<\/a>. But everytime I would run the command, RubyGems would not find any gems. So I started to browse the code for <a href='#gi'>Gem::Indexer<\/a> and wrote a few lines of code to do the indexing from <a href='#irb'>irb<\/a> launched from your host destination (the one above .\/gems):<\/p>\n<pre class=\"brush: ruby\">\r\nrequire 'rubygems'\r\nrequire 'rubygems\/indexer'\r\n\r\ni=Gem::Indexer.new '.'\r\ni.generate_index\r\n<\/pre>\n<p>And if you want to update the index later:<\/p>\n<pre class=\"brush: ruby\">\r\nrequire 'rubygems'\r\nrequire 'rubygems\/indexer'\r\n\r\ni=Gem::Indexer.new '.'\r\ni.update_index\r\n<\/pre>\n<p>I suspect the issue with the gem command must exist somewhere higher at the command parsing level but I have not looked into it (I just wanted to create my repository and move on).<\/p>\n<p>Once I ran the commands, several files were created, but the most important one is the yaml file which represents the definition of the repository index. It contains a description of all the gems in your repository.<\/p>\n<h3>Sourcing Your Gems<\/h3>\n<p>So now in my .gems file for Heroku I can specify that a given gem comes from my repository using a statement like:<\/p>\n<pre class=\"brush: ruby\">\r\nanexternalgem --source http:\/\/gems.monnet-usa.com\r\n<\/pre>\n<h3>So What?<\/h3>\n<p>Now these gems are frozen. I can now regain control over when I want to update to a later version of that gem.<\/p>\n<p>RubyGems is a very powerful packaging system and like so many Ruby components provides a lot of flexibility.<\/p>\n<h3>References and Resources<\/h3>\n<ul>\n<li><a name='rgps' href='http:\/\/docs.rubygems.org\/'>The RubyGems packaging system<\/a><\/li>\n<li><a name='gr' href='http:\/\/docs.rubygems.org\/read\/chapter\/18'>RubyGems  Gem repository creation manual<\/a><\/li>\n<li><a name='gi' href='http:\/\/rubygems.rubyforge.org\/rdoc\/Gem\/Indexer.html'><\/a><\/li>\n<\/ul>\n<ul>\n<li><a name='irb' href='http:\/\/ruby-doc.org\/docs\/ProgrammingRuby\/html\/irb.html'>IRB the Interactive Ruby Shell<\/a><\/li>\n<li><a name='rf' href='http:\/\/rubyforge.org\/'>RubyForge repository<\/a><\/li>\n<li><a name='rp' href='http:\/\/rubyforge.org\/projects\/ruby-paypal\/'>Ruby-Paypal hoste on RubyForge<\/a><\/li>\n<li><a name='gc' href='http:\/\/gemcutter.org\/'>GemCutter repository<\/a><\/li>\n<li><a name='rc' href='http:\/\/github.com\/camping\/camping'>Ruby Camping<\/a><\/li>\n<li><a name='hu' href='http:\/\/heroku.com\/'>Heroku Cloud Hosting for Ruby<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>What Is A Gem Repository? For people not familiar with Ruby, a gem is a code package (a sort of zip file) containing all Ruby source files and resources for a given application or library. Gems are typically stored in hosted repositories like RubyForge, GemCutter, or GitHub so that applications and libraries can be shared [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[56],"class_list":["post-203","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-ruby"],"_links":{"self":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=203"}],"version-history":[{"count":19,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/203\/revisions"}],"predecessor-version":[{"id":222,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/203\/revisions\/222"}],"wp:attachment":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}