RubyRef : easy access to Ruby documentation

- ruby roda documentation

I don’t know about you, but I can’t really remember the last time I added a bookmark to my browser (at least not on purpose, -D is right next to -F after all). So when I saw rustref.com, I knew I wanted to build something like this for the Ruby community, which is now available as rubyref.net.

tl;dr

RubyRef defines a list of CNAME records of the form *.rubyref.net which redirect to different Ruby related documentation sites. For example ruby.rubyref.net brings you to the core documentation, whereas api.ruby.net redirects to the C API documentation and awesome.rubyref.net will take you to the awesome-ruby repository on GitHub.

Architecture

Update: It’s now a static site generated with Middleman and hosted on Netlify, but the CloudFlare page rules are still used, as is the Rake task.

Manually defining a bunch of CNAMEs is not what I call a fun afternoon activity, but writing code is. So RubyRef uses a Roda app in combination with Cloudflare page rules to achieve its goal. Let’s have a look at the app first (current code / roda branch):

# frozen_string_literal: true

require 'roda'
require 'json'

class RubyRef < Roda
  REDIRECTS = JSON.parse(File.read('redirects.json'))

  plugin :assets, css: 'style.css'
  plugin :render

  route do |r|
    r.assets

    r.root do
      render :index
    end

    r.on 'redirect', String do |subdomain|
      r.redirect REDIRECTS.fetch(subdomain) { '/' }
    end

    r.redirect '/'
  end
end

This reads a list of redirects from a file called redirects.json, where the various CNAMEs are mapped to their respective target URLs. The actual redirects happen through requests of the form GET https://rubyref.net/<CNAME> and the code necessary to achieve this couldn’t be any simpler.

However, in the interest of less typing and faster autocompletes the redirects should be of the form https://<CNAME>.rubyref.net and to achieve that the following Cloudflare page rule is used:

Cloudflare page rule

So far so good, there’s however one last problem: Cloudflare does not offer proxying for wildcard CNAMEs in their free tier, so I wrote a little Rake task using the Cloudflare gem to automatically add “dummy” CNAMEs pointing to “rubyref.net” via the Cloudflare API:

namespace :cloudflare do
  desc 'Update Cloudflare CNAMEs'
  task :update_cnames do
    redirects = JSON.parse(File.read('redirects.json'))

    email = ENV.fetch('CLOUDFLARE_EMAIL')
    key = ENV.fetch('CLOUDFLARE_KEY')
    zone_id = ENV.fetch('CLOUDFLARE_ZONE')

    connection = Cloudflare.connect(key: key, email: email)
    zone = connection.zones.find_by_id(zone_id)
    cnames = zone.dns_records.all.select { |dns| dns.record[:type] == 'CNAME' }
    cnames.map! { |cname| cname.record[:name] }

    redirects.each_key do |cname|
      name = "#{cname}.rubyref.net"
      next if cnames.include?(name)

      puts "Setting CNAME: #{name}"
      zone.dns_records.post(
        {
          type: 'CNAME',
          name: name,
          content: 'rubyref.net',
          proxied: true
        }.to_json,
        content_type: 'application/json'
      )
    end
  end

With all the CNAMEs defined the page rule now works and the Roda app takes care of the rest 🎉

Contributing

If you want to see new sites added to RubyRef, just open a PR with the extra lines added to redirects.json and I will take care of the rest.