#!/usr/bin/env ruby # coding: utf-8 require 'rubygems' require 'bundler/setup' Bundler.require(:doc) require 'yaml' output = "\n" output << <<-TAB.lines.map(&:strip).join TAB output << "\n\n" footnotes = { "platform" => <<-EOF, Indicates that the adapter is expected to work on this platform. Most adapters will at least work on MRI, but some are curently considered unstable, in which case they are not supported on any platform. EOF "multi-thread safe" => <<-EOF, Make adapters thread-safe by using `Moneta::Lock` or by passing the option `threadsafe: true` to `Moneta#new`. There is also `Moneta::Pool` which can be used to share a store between multiple threads if the store is multi-process safe. I recommend to add the option `:threadsafe` to ensure thread-safety since for example under JRuby and Rubinius even the basic datastructures are not thread safe due to the lack of a global interpreter lock (GIL). This differs from MRI where some adapters might appear thread safe already but only due to the GIL. EOF "multi-process safe" => <<-EOF, Share a Moneta store between multiple processes using `Moneta::Shared` (See below). EOF "atomic increment" => <<-EOF, If a store provides atomic increment it can be used with `Moneta::Semaphore`. You can add weak `#increment` support using the `Moneta::WeakIncrement` proxy. EOF "atomic create" => <<-EOF, If a store provides atomic creation it can be used with `Moneta::Mutex`. You can add weak `#create` support using the `Moneta::WeakCreate` proxy. EOF "native expires" => <<-EOF, Add expiration support by using `Moneta::Expires` or by passing the option `expires: true` to `Moneta#new`. EOF "bulk read" => <<-EOF, This indicates that there is some performance gain when fetching multiple values at once using `#values_at`/`#fetch_values` or `#slice`. For instance, the `MGET` instruction in Redis, or the ability to retrieve several rows in one query in SQL. EOF "bulk write" => <<-EOF This indicates that there is some performance gain when storing multiple key/value pairs at once using `#merge!`/`#update`. EOF } YAML.parse_stream(File.read(File.join(File.dirname(File.dirname(__FILE__)), 'feature_matrix.yaml'))) do |document| feature_group = document.to_ruby output << %{\n\n} feature_group['notes'].each do |k,v| footnotes[k] = v end feature_group['backends'].each do |backend| output << '' output << "" output << "" features = backend['features'] | (feature_group['features'] || []) features += backend['platforms'] || [] %w{MRI JRuby threadsafe multiprocess increment create expires persist each_key bulk_read bulk_write}.each do |feature| supported = if features.include? feature "yes" elsif backend['unknown'] && backend['unknown'].include?(feature) "unknown" else "no" end note = if backend['notes'] && backend['notes'][feature] "#{footnotes.keys.index(backend['notes'][feature]) + 1}" else '' end mark = case supported when "yes" "✓" when "no" "✗" when "unknown" '?' end colour = case supported when "yes" '#5F5' when "no" '#F44' when "unknown" '#55F' end output << %{} end html_description = if backend['description'] Kramdown::Document.new(backend['description']).to_html.match('

(.*)

')[1] else '' end output << "" output << '' output << "\n\n" end end output << "
AdapterRequired gems MRI support1 JRuby support1 Multi-thread safe2 Multi-process safe3 Atomic increment4 Atomic create5 Native expires6 Persistent Key Traversal Bulk read7 Bulk write8 Description
#{feature_group['group']}
#{backend['adapter']}#{backend['gems'] || '-'}#{mark}#{note}#{html_description}
\n\n" footnotes.each_value.each_with_index do |note, idx| output << "#{idx+1}. #{note.lines.map(&:strip).join(" ")}\n" end readme = File.open('README.md', 'r+') new_readme = readme.read.sub(/(name="backend-matrix".*?\n).*?(------)/m, "\\1\n#{output}\n\\2") readme.rewind readme << new_readme readme.truncate(readme.tell)