Be Genius

Fork Me
Mugshot

Hi, I'm Bodaniel Jeanes.

I'm a Ruby developer from Brisbane, Australia

I work at Mocra where I hack on awesome code. Follow me, recommend me, and link with me.

64-bit Postgres and Rails on Snow Leopard

Dependencies

Install the GEOS and PROJ frameworks from here

Postgres

Download and Compile

http://ftp2.au.postgresql.org/pub/postgresql/source/v8.4.1/postgresql-8.4.1.tar.bz2 | tar xjf -
cd postgresql-8.4.1
./configure
make && sudo make install

The files are now all installed in the right places, onwards to making them usable!

Create a postgres User and Group

This is adjusted from the instructions in the comments here).

# Find unused Group ID and User ID:
export GROUPID=`sudo dscl . -list /Groups PrimaryGroupID | ruby -e 'puts STDIN.read.scan(/\d+/m).map{|i|i.to_i}.uniq.sort.last.succ'`
export USERID=`sudo dscl . -list /Users UniqueID | ruby -e 'puts STDIN.read.scan(/\d+/m).map{|i|i.to_i}.uniq.sort.last.succ'`

# Create group:
sudo dscl . -create /Groups/_postgres
sudo dscl . -create /Groups/_postgres PrimaryGroupID $GROUPID
sudo dscl . -append /Groups/_postgres RecordName postgres

# Create user:
sudo dscl . -create /Users/_postgres
sudo dscl . -create /Users/_postgres UniqueID $USERID
sudo dscl . -create /Users/_postgres PrimaryGroupID $GROUPID
sudo dscl . -create /Users/_postgres UserShell /bin/bash
sudo dscl . -create /Users/_postgres RealName "PostgreSQL Server"
sudo dscl . -create /Users/_postgres NFSHomeDirectory /usr/local/pgsql
sudo dscl . -append /Users/_postgres RecordName postgres

That’s the clean way of making a user (so it doesn’t show up in your Accounts preference pane, etc.

Clean up

sudo touch /var/log/psql.log
sudo mkdir /usr/local/pgsql/data
sudo chown -R postgres:postgres /usr/local/pgsql/data /var/log/psql.log

# Put Postgres in your path
export $PATH="/usr/local/pgsql/bin:$PATH"
sudo sh -c 'echo /usr/local/pgsql/bin > /etc/paths.d/pgsql'

Thanks to Apple we have a nice way of setting the PATH across the entire system so every app should now know how to find the Postgres binaries and the data directory is now set up to store the database files — now, we just need to create them.

Initialise the Database

# Become the postgres user
sudo su - postgres

# If this throws next commant throws an error about shared memory, 
# try putting "these lines":http://gist.github.com/224815 into 
# /etc/sysctl.conf, rebooting, and trying again:
initdb -D /usr/local/pgsql/data -E UTF8

# Start the database
postgres -D /usr/local/pgsql/data >/var/log/psql.log 2>&1 &

# Create a test database and check you can connect to it
createdb test
psql test

# Just create a superuser for general dev tasks
createuser postgres

# we don't want to be the postgres user anymore
exit

Your done with the Postgres setup now!

PostGIS

curl http://postgis.refractions.net/download/postgis-1.3.7SVN.tar.gz | tar xzf -
cd postgis-1.3.7SVN
./configure --with-geosconfig=/Library/Frameworks/GEOS.framework/unix/bin/geos-config --with-projdir=/Library/Frameworks/PROJ.framework/unix
make && sudo make install

Phew! That one was easy.

Postgres Ruby Gem

This is the part that everyone cares about the most. If this works your Rails apps should start working like a charm.

sudo env ARCHFLAGS='-arch x86_64' gem install pg

Fix for "dynamic_pager: cannot open swap directory /private/var/vm" in OS X (possibly just Snow Leopard)

Today my Snow Leopard install was going so slow it felt like I was trying to swim through molasses. The system was literally so slow that typing text into some text fields (especially TextMate) lagged at about a rate of 1 character per second, and opening files (or even running touch on them) took a couple of seconds.

After a few fruitless restarts and a keen eye on my logs I started noticing these errors in Console.app:

9/07/09 3:01:37 PM	com.apple.launchd[1]	(com.apple.dynamic_pager[2445]) Exited with exit code: 1
9/07/09 3:01:37 PM	com.apple.launchd[1]	(com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds
9/07/09 3:01:47 PM	com.apple.dynamic_pager[2481]	dynamic_pager: cannot open swap directory /private/var/vm
9/07/09 3:01:47 PM	com.apple.launchd[1]	(com.apple.dynamic_pager[2481]) Exited with exit code: 1
9/07/09 3:01:47 PM	com.apple.launchd[1]	(com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds
9/07/09 3:01:57 PM	com.apple.dynamic_pager[2546]	dynamic_pager: cannot open swap directory /private/var/vm
9/07/09 3:01:57 PM	com.apple.launchd[1]	(com.apple.dynamic_pager[2546]) Exited with exit code: 1
9/07/09 3:01:57 PM	com.apple.launchd[1]	(com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds
9/07/09 3:02:07 PM	com.apple.dynamic_pager[2547]	dynamic_pager: cannot open swap directory /private/var/vm
9/07/09 3:02:07 PM	com.apple.launchd[1]	(com.apple.dynamic_pager[2547]) Exited with exit code: 1
9/07/09 3:02:07 PM	com.apple.launchd[1]	(com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds

I don’t know how or why they started but I was able to fix it by simply running sudo mkdir /private/var/vm in Terminal. Within a few seconds of creating the directory, the errors ceased and I could see a swapfile created inside the directory.

I have no idea what caused the directory to be deleted in the first place or why OS X isn’t smart enough to try creating it, but the fix is simple and instantly effective.

Note: I am not sure if this is a Snow Leopard specific issue or not, but it very well might be. Also, these started right after installing Adobe CS4, so I feel pretty confident blaming that for now.

Colemak

About a year ago I found out about the Colemak keyboard layout. This is what it looks like:

I was instantly intrigued and was drawn to a few key features:

Long story short: it took me a few tries to commit to learning it (3 tries over year in fact). Eventually I went cold turkey for a week and haven’t looked back. Typing is more comfortable and faster already.

Getting Colemak on OS X is as simple as following the simple Installation instructions. The instructions seem out of date when it comes to re-mapping caps lock to backspace. It is as simple as downloading PCKeyboardHack, installing it, rebooting, and choosing the option in its preference pane to remap caps lock to delete (key code 51).

Snow Leopard

Colemak itself works fine under Snow Leopard, however the PCKeyboardHack utility does not work, because it is hardcoded to only load the kernel driver if it recognises the OS version. Luckily it is open source, and I was able to import the Mercurial project into a GitHub project, modify it, and build a version that works fine on Snow Leopard.

Dead Keys that Apple uses on the QWERTY layout

One thing I loved about the QWERTY layout on OS X was the sensible dead key and alternate character behaviours, allowing users to quickly and logically input characters such as: , é, ¡, ¿, », ‡, °, etc. The version of Colemak, for one reason or another, moved or simply didn’t have many of these shortcuts.

So, I created my own Colemak layout bundle that moves the dead key positions to preserve the associations with the character position changes from QWERTY to Colemak. This means, for example,  can be created by pressing ⌥⇧K on either keyboard layout (where K is the key that outputs K, not the key that physically says K on it).

My version of the Colemak bundle is available on my GitHub and a direct download to a zip file is available here. Simply put the .bundle file in your ~/Library/Keyboard Layouts directory. The bundle includes both the original keyboard layout and my re-created one so you can switch between them if you need both, for any reason.

Snow Leopard for the Ruby Developer

After the 2009 WWDC release, I decided to give Snow Leopard a try on my production machine. Crossing my fingers, expecting a plethora of broken gems and databases, I wiped my hard drive clean and installed the latest build.

Much to my surprise, most things worked flawlessly and exactly as it did on Leopard.

What Ships with Snow Leopard

$ gem --version
1.3.1

$ ruby --version
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]

$ gem list

*** LOCAL GEMS ***
 
actionmailer (2.2.2, 1.3.6)
actionpack (2.2.2, 1.13.6)
actionwebservice (1.2.6)
activerecord (2.2.2, 1.15.6)
activeresource (2.2.2)
activesupport (2.2.2, 1.4.4)
acts_as_ferret (0.4.3)
capistrano (2.5.2)
cgi_multipart_eof_fix (2.5.0)
daemons (1.0.10)
dnssd (0.6.0)
fastthread (1.0.1)
fcgi (0.8.7)
ferret (0.11.6)
gem_plugin (0.2.3)
highline (1.5.0)
hpricot (0.6.164)
libxml-ruby (1.1.2)
mongrel (1.1.5)
needle (1.3.0)
net-scp (1.0.1)
net-sftp (2.0.1, 1.1.1)
net-ssh (2.0.4, 1.1.4)
net-ssh-gateway (1.0.0)
rails (2.2.2, 1.2.6)
rake (0.8.3)
RedCloth (4.1.1)
ruby-openid (2.1.2)
ruby-yadis (0.3.4)
rubynode (0.1.5)
sqlite3-ruby (1.2.4)
termios (0.9.4)
xmpp4r (0.4)

Quite possibly these default gems and versions will change between now and the final release of Snow Leopard. For instance, this seed comes with Rails 2.2.2, even though we are already at 2.3.2. Snow Leopard doesn’t come out till September and by then we could have an even newer version of Rails that might be bundled.

What doesn’t work, and how to fix it.

Textmate – Everything works fine except for the following shortcuts: ⌘←, ⌘→, ⌘⇧←, and ⌘⇧→. These shortcuts are for moving the text insertion point to beginning and end of line, and selecting to beginning and end of line, respectively. The fix is easy, simply download and double click the TextMate macros attached to this ticket

Nokogiri – Nokogiri installs fine but gives error “native.bundle: mach-o, but wrong architecture” when used. Getting around this is as easy as running sudo gem install nokogiri -s http://tenderlovemaking.com/ to get the latest development release which includes a fix for this.

do_sqlite3 – I haven’t personally used this or tried to fix it but I saw report of it not working by @benlovell

Passenger PrefPane – Preference pane does not load. No known fix (it’s probably an easy fix but I haven’t looked enough into it to try).

Ghost - Manage hostnames effortlessly

Background

Ghost is a gem that provides a command and a Ruby API for managing hostnames locally, much as people do manually by editing /etc/hosts now.

Sometime last year I was having to add lots of Passenger virtual hosts on my development machine and felt that having to constantly edit the /etc/hosts file was a bit archaic for my liking and that there must be a nicer way of accomplishing the same task.

Having seen the Passenger Preference Pane added hostnames without requiring the user to do anything special, I had a peak into its source and discovered the dscl (man page) command that comes with Leopard.

For the hell of it I decided to write my Ghost gem using this command and use it to make a nice wrapper that has an easier syntax than dscl, and that is less effort than manually editing my hosts file. Happy with the result, a few other people requested support for other unix systems and Mitchell V Riley was kind enough to patch Ghost to fall back to processing and editing the /etc/hosts file when not on Leopard.

Usage

$ ghost add mydevsite.local
  [Adding] mydevsite.local -> 127.0.0.1

$ ghost add staging-server.local 67.207.136.164
  [Adding] staging-server.local -> 67.207.136.164

$ ghost list
Listing 2 host(s):
  mydevsite.local      -> 127.0.0.1
  staging-server.local -> 67.207.136.164

$ ghost delete mydevsite.local
  [Deleting] mydevsite.local

$ ghost list
Listing 1 host(s):
  staging-server.local -> 67.207.136.164

$ ghost modify staging-server.local 64.233.167.99
  [Modifying] staging-server.local -> 64.233.167.99

$ ghost list
Listing 1 host(s):
  staging-server.local -> 64.233.167.99

$ ghost empty
  [Emptying] Done.

$ ghost list
Listing 0 host(s):

Other

Since creating Ghost I’ve used the Ruby library to add an initializer to my Rails projects that add the domain locally if running under Passenger in development mode (some configuration is needed to let it do this as it needs sudo).

Also, I have heard reports that entries in the /etc/hosts file are ignored in Snow Leopard. I haven’t tried because I only ever use Ghost now, but I do know that Ghost still works well.

Caveats

It only works on Unix-based systems and the /etc/hosts path is hard-coded. Windows support is entirely possible if somebody wants to use it. It isn’t something I am likely to do as I haven’t booted Windows in at least a year. In fact, I don’t think I have even ever installed Ruby on Windows before…