Migration to Heroku

Hi, if you read those lines it means the DNS were updated and you’re looking at this blog hosted on Heroku.

It’s been a long time since I wanted to try Heroku for more than a little Sinatra test app, so I decided to try with this blog. We’ll see how it goes in the next weeks.

Published on Sat, 11 Jun 2011 12:20

End of my Rubygems mirror

With the advent of Gemcutter, I don’t feel the need to maintain my own rubygems mirror anymore.

Please remove it from your gem source if you’re using it and replace it by Gemcutter. To install gemcutter as the main source for your gems :

gem install gemcutter
gem tumble

Published on Sat, 05 Dec 2009 17:58

Sinatra, Sequel, HAML, PostgreSQL, UTF-8 and Ruby 1.9.1

Lately, with my friend and colleague Joseph, we made some experiments with the Sinatra Ruby Framework.

As part of the experiment we’ve chosen to stick with our DB of choice PostgreSQL and our preferred template engine HAML, but we decided to give the Sequel ORM a try as well as using Ruby 1.9.1. We also wanted to store our datas as UTF-8 (this part is the most painful of all).

Our first goal was to have a simple application tying everything together and testable with RSpec and Cucumber.

Using Sinatra and HAML is a snap, as it’s a core feature of Sinatra, just be sure to use HAML version >= 2.2.0 as it includes some work to support new Ruby 1.9 String Encoding.

Then comes Sequel, using it is as simple as requiring it and feeding it with database connection information, just be sure to set the :encoding => 'UTF-8' (cf : Sequel::Database.connect method).
Sequel is great in that it has adapters for most commons connectors, first we tried DataObjects’s do_postgres as it should support asynchronous query (and it does !), but we had to fall back to the PG one and even to a patched version.

Let me explain the problem here, and be warned it’s not limited to Sequel, but to any ORM using currently available db connectors, when using a charset different from ASCII-8BIT under Ruby 1.9.
What happens is that ORMs do not force any encoding on String returned by the database connectors even when you specified an encoding (commonly used to set the connection’s “client_encoding”). Current ruby connectors (under Ruby 1.9) do not use the database/client’s connection encoding as a “hint” to determine and set the encoding of returned values.
This is not a problem on Ruby 1.8, but on Ruby 1.9 you get some weird results, the string returned from db have a default encoding “ASCII-8BIT” (in fact default for BINARY), as ORMs do not force encodings this result in a String with the bad Encoding.
Try to display it on a page and you’re welcomed with friendly “incompatible character encodings: ASCII-8BIT and UTF-8.” messages or try to use Webrat with RSpec matchers and you get “incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)”.

So here are the libraries versions to use to have a working Sinatra, Sequel with Postgres, HAML, RSpec, Cucumber stack :

  • Sinatra >= 0.9.4
  • Rack-Test >= 0.4.1
  • Webrat >= 0.5.0
  • kamk-pg >= (http://github.com/kamk/pg/tree/master)
  • Sequel >= 3.0.0
  • RSpec >= 1.2.8
  • Cucumber >= 0.3.94

Then you need to monkey-patch Rack (this is highly untested, it worked for my current app but it should not be used in production environment) :

module Rack
  module Utils
    def escape(s)
      regexp = case
        when RUBY_VERSION >= "1.9" && s.encoding === Encoding.find('UTF-8')
          /([^ a-zA-Z0-9_.-]+)/u
          /([^ a-zA-Z0-9_.-]+)/n
      s.to_s.gsub(regexp) {
      }.tr(' ', '+')

This does 2 things :

  • it’s using bytesize($1) to correctly handle multibyte chars (taken from http://github.com/rack/rack/commit/ce26ede59d9e833ee233edff8d9ec73c6ecb0998)

  • it’s using a regexp with “u” (unicode) modifier when dealing with UTF-8 Strings under Ruby 1.9.

There you go, you can finally test your Sinatra apps outside-in even when using non-us languages under Ruby 1.9. Isn’t that great ?

Published on Thu, 20 Aug 2009 10:38

RubyGems mirror update

Due to the increasing time/resources needed to generate the indices for my rubygems mirror, I decided to stop generating the ones for old RubyGems versions (<= 1.2.0) and switch to the —update option.

This greatly help with the load generated on the server by the mirroring/indexing process. From now on I will only generate the legacy indices (for RubyGems <= 1.2.0) twice a day : 12AM UTC+2/12PM UTC+2.


Published on Sun, 21 Jun 2009 20:13

Creating your own RubyGem mirror

In case you want to create your own RubyGem mirror here’s how I did mine.

From now on, let’s pretend we will store the mirrored gems in : /data/rubygems.mirror

First you need to create a config file (YAML format) specifying the source and destination for your mirror (put it in /data/gemmirror.config for example) :

- from: http://gems.rubyforge.org
  to: /data/rubygems.mirror

- from is the master mirror you will pull from
- to is the directory where your mirror files will be stored

Then all you have to do is to add this commands as a cron task :

/usr/bin/gem mirror --config-file=/data/gemmirror.config && /usr/bin/gem generate_index -d /data/rubygems.mirror

/usr/bin/gem mirror —config-file=/data/rubygemmirror : will mirror the gems using informations in /data/rubygemmirror file
/usr/bin/gem generate_index -d /data/rubygems.mirror : will generate an optimized index to reduce the datas transfered on index update

Here’s what you asked for Nick !

Published on Fri, 23 May 2008 22:06

RSpec and HAML Helpers

Today I faced a problem with specing a helper where I use the haml_tag/puts methods (haml_tag was previously open).

Here’s a solution working with Rails 2.0.2, RSpec 1.0.3 and HAML 1.8.2 :

in spec_helper.rb add :

Spec::Runner.configure do |config|
  # Activate haml to spec helpers
  config.with_options(:behaviour_type => :helpers) do |config|  
    config.include Haml::Helpers  
    config.include ActionView::Helpers  
    config.prepend_before :all do  
       # Update from Evgeny comment, with HAML >= 1.8.2, you can call

       # Old way for HAML <= 1.8.2
       # @haml_is_haml = true  
       # @haml_stack = [Haml::Buffer.new]  


then you can write your helper spec like this :

describe ApplicationHelper do
  describe "#top_navigation_menu when logged in" do
    it "returns the menu" do
      @user = mock_model(User)
      capture_haml {
      }.should_not be_empty

The interesting method is capture_haml, which does the same as Rails builtin capture but for HAML.
haml_tag/puts methods write output directly to the buffer and does not return the generated content as a String, thus we cannot just test on the method output.

Published on Wed, 21 May 2008 21:35

Bad key bindings over ssh from a mac

I encountered, for some time now, problems when connecting over ssh from my mac to a linux machine.
These problems were related to backspace/delete key in both nano and zsh the solutions I found today are :

For zsh type :

echo "bindkey ^? backward-delete-char" >> ~/.zshrc
echo "bindkey ^[[3~ delete-char" >> ~/.zshrc

WARNING : you should type these commands not copy/paste them, ^? sequence is obtained using ctrl+v then [backspace key].

For nano type :

## Fix Backspace/Delete confusion problem.
echo "set rebinddelete" >> ~/.nanorc

All should works now.

Published on Sat, 23 Feb 2008 20:44

Automount shared directory on Leopard

Following my last post, here’s another handy new thing to do in Leopard. I never used this in Tiger (MacOS X.4) because it was not practical (besides being possible), but I swear it was usable by the time.
Auto-mounting remote shared server (Samba, NFS, AFS) wherever I want, without being stuck with a dead Finder.app whenever I lost wifi network, I change room or my mac goes to sleep (yep I used to have some problems with this).
So now how to do this ? NetInfo is gone so where can I define my automount points, remember when I said NetInfo is dead for the best ?

First, you should edit /etc/auto_master :

sudo nano /etc/auto_master

The stock version should looks like this :

# Automounter master map
+auto_master    # Use directory service
/net      -hosts    -nobrowse,nosuid
/home      auto_home  -nobrowse
/Network/Servers  -fstab
/-      -static

You need to add a line like this, just before /- -static. :

/my/mount/point/path    auto.smb

Where /my/mount/point/path will be the full path to the directory where remote shared folders will appears. Mine is set to /Users/_myusername_/Desktop/Shares.

Now create a new file in /etc/auto.smb :

sudo nano /etc/auto.smb

And add one line per remote folder you want to mount automatically, each line should looks like this :

www -fstype=smbfs ://username:password@remote_server_name_or_ip/shared_folder_name

www : this is the name you want to give to the remote folder locally

-fstype=smbfs : specify the kind of filesystem to use, I only cover samba here.

://username:passwordremote_server_name_or_ip/shared_folder_name@ : this is the informations to connect to the remote server. Change username and password with yours, specify remote_server_name_or_ip to reflect the way you access the machine and set shared_folder_name to the name of the remote folder.

Then set permission on the new file :

sudo chmod 600 /etc/auto.smb

Now restart automount daemon :

automount -vc

You should see your new mount point as well as stock ones :

automount: /net updated
automount: /home updated
automount: /my/mount/point/path updated
automount: no unmounts

Notice just like /etc/hosts that Leopard seems to only detect a change if a line is added/removed, so anytime you make a change that does not change the line number in the file add a comment (#) at the beginning or end to force a reload.

Published on Sat, 26 Jan 2008 22:28

Hosts aliases in Leopard

Back in Tiger days, I used to love having aliases pointing to localhost or other servers saving me some typing and allowing me to use Apache vhosts locally. To achieve this without restarting the whole system, I used NetInfo to add a new Machine entry, this works great, no restart needed only NetInfo reload.

With Leopard, NetInfo is gone (for the best) and it has been replaced by a folder hierarchy full of flat .plist files. No more NetInfo Manager, but a new dscl command and a bunch of related one : dscacheutil (lookupd replacement), dseditgroup, dsmemberutil, etc.

For today, we’ll use dscl and dscacheutil, let’s create a new Host entry to map myvhost.loc to (I like adding .loc to distinguish my added hosts, but you’re free to use anything else) :

sudo dscl localhost -create /Local/Default/Hosts/myvhost.loc IPAddress

Then to be sure it’s looked up correctly by software (in fact it’s only needed if you tried to access the myvhost.loc before adding it) :

sudo dscacheutil -flushcache

A little handy feature of the new dscacheutil when we’re at it :

sudo dscacheutil -cachedump -entries Host

This will list all entries cached by Leopard, it can comes in handy when trying to solve a name resolution problem.

And finally if you want to get ride of your entry later on :

sudo dscl localhost -delete /Local/Default/Hosts/myvhost.loc

[Update 2008/01/07]
Benjamin Stiglitz wrote a comment to say /etc/hosts is now automatically watched for changes on Leopard, so there’s no more need to play with dscl to add simple host. Thanks again Benjamin.

Published on Sat, 05 Jan 2008 18:36

RSpec 1.1

David Chelimsky anounced this morning the release of RSpec 1.1 (as of now the website is not up to date) RSpec 1.1 and just now the brand new website hosting.

What’s in this release ?

  • Nested Example Groups : allows you to nest your describe blocks resulting in group sharing common specifications.
  • Support for Rails 2.0.1
  • Test::Unit interoperability : switch smoothly from Test::Unit to RSpec by allowing you to run your Test::Unit tests with RSpec. The goal here is to provide a way to progressively transition your tests to RSpec syntax.

More infos on David blog post about the RSpec 1.1 release

Congratulation and many thanks to everyone involved in this release !

Published on Fri, 14 Dec 2007 09:55