21 Jun 2009

Quantifying what's better about Mac OS X

I’m the only Mac user out of a group of mates who are mostly Linux and Windows users. Time and time again, my choice of platform is on trial. Common arguments include “Apple hardware is expensive”, “It’s proprietary and locked down” and “I can do everything I need to”.

Jim Whimpey has thought about quantifying what’s better about Mac OS X. It’s the attention to detail on the littlest of things, a consistent user experience and the only platform which stays out of my way the most.

At work we’re predominantly a Mac environment with no mandated software. Everything just works.


21 Jun 2009

IRB for teaching Ruby interactively

As Rubyists, we’re familiar with the IRB for quickly experimenting with language features and new ideas. I was interested to see how this would translate when demonstrating Ruby in an informal teaching environment.

I invited Ashley Kyd and Owen Stickley for some Ruby 101. Ashley is interested in learning rails and Owen is interested in automating system tasks.

We each had our own laptops and a projector. Plugged a laptop in to the projector and asked everyone to start the IRB.

As the teacher, I could demonstrate Ruby’s features while Ashley and Owen followed and continued to experiment themselves. I think this style of interactive learning is more engaging by providing immediate feedback and lowering the barrier to entry.

Even after the initial learning phase, I’m sure that Ashley and Owen will continue to use and appreciate the IRB.


31 May 2009

220KM round trip, mountains, dams, crisp air and country roads

Scenic stop on Mount Mee

It’s the first weekend I’ve had no obligations to uni, friends or family. Couldn’t think of a better way to celebrate than a long ride with my old man and his mate.

We started on Brisbane’s southside and followed the Ipswitch motorway. Our route took us over the Wivenhoe Dam wall, past Somerset, through Kilcoy and over Mount Mee with various stops on the way. It was an epic ride, out for a total of seven hours.

With the recent heavy rains, the inland routes are looking spectacular. The dams had attracted a tonne of people interested in water sports and family picnics.

Being low to the ground with no obstructions, riding fast in between giant mountains and feeling the wind against your face is amazingly refreshing.


29 Apr 2009

Jekyll meets DreamHost. Automated deployment for Jekyll with Git

It has been just under a month since I launched this blog, and the first thing I promised myself was to automate deployment. If you have an existing GitHub account you might want to consider GitHub Pages, it’s quick and easy.

Why not GitHub Pages?

How will it work?

I am interested in achieving the same functionality offered by GitHub Pages with DreamHost. That is, a single push automatically generates the site, removing the pain of manually copying files and directories.

We are going to create a bare repository for pushing to. Every time you push, we will use the post-receive hook to execute a Bash script. The Bash script clones the repository with a working directory, executes jekyll and cleans up. Hooks in Git behave like events.

Preparing a Jekyll-friendly environment

Jekyll is not available on DreamHost. You will need to build your own RubyGems and install Jekyll with its dependancies. John Nunemaker has written an excellent guide.

If you are interested in code highlighting, you will also want to install Pygments. Pygments is a Python syntax highlighter that Jekyll uses to parse and wrap your code snippets in the appropriate HTML tags.

$ mkdir ~/lib/python
$ echo 'export PYTHONPATH="$HOME/lib/python:/usr/lib/python2.3"' >> ~/.bash_profile
$ source ~/.bash_profile

Download and build Pygments from source.

$ cd ~/src
$ wget http://pypi.python.org/packages/source/P/Pygments/Pygments-1.0.tar.gz
$ tar -xvzf Pygments-1.0.tar.gz
$ cd Pygments-1.0
$ python setup.py install --home=$HOME

Git it all together

Initialise a bare repository to push to. It is potentially dangerous to push to a remote repository with a working directory.

$ mkdir ~/src/your_git_repo.git
$ cd ~/src/your_git_repo.git
$ git --bare init

Add DreamHost as a remote in your local repository.

$ git remote add dreamhost ssh://user@server.com/home/user/src/your_git_repo.git

Write a Bash script to clone the repository, execute Jekyll and clean up. Jekyll will generate its output in to your publicly accessible directory.

# ~/bin/generate_public_www
#!/bin/bash
GIT_REPO=$HOME/src/your_git_repo.git
TMP_GIT_CLONE=$HOME/tmp/your_git_repo
PUBLIC_WWW=$HOME/var/www/your_site

git clone $GIT_REPO $TMP_GIT_CLONE
jekyll $TMP_GIT_CLONE $PUBLIC_WWW --pygments
rm -Rf $TMP_GIT_CLONE
exit
$ chmod +x ~/bin/generate_public_www

Add the Bash script in the post-receive hook of your bare repository. Hooks are Bash scripts too.

# ~/src/your_git_repo.git/hooks/post-receive
#!/bin/sh
$HOME/bin/generate_public_www
exit
$ chmod +x ~/src/your_git_repo.git/hooks/post-receive

Programmers should be lazy

Congratulations, you’re done! Every time you push to DreamHost, Jekyll will build the site. Cool, huh?!

$ git push dreamhost master

Bonus: You now have a redundant copy of your repository.

Update: 31 May 2009

Jay Williams followed this guide and experienced an annoying problem with the Git post-receive hook. After some trouble-shooting, it appeared that the hook was never executed because the user he was shelling in with didn’t have the access to the compiled binaries in its path.

Copying your .bash_profile to .bash_rc should solve the issue.

cd ~/
cp .bash_rc .bash_rc.old
cp .bash_profile .bash_rc

23 Apr 2009

Git rebase for linear history

Subject: Suggestion to rebase after committing and before pushing
To: Development Team
Date: 20 April 1:54:29 PM

What’s the issue?

Looking at our history, I’ve noticed that there is a lot of “Merge branch ‘master’ of XYZ”. Technically, this is fine but I feel it obscures the important history of the repository. No one cares that there was a merge, and following funky, rainbow lines in GitX is unnecessary effort.

Why does this happen?

Sometimes it’s unavoidable. If you’ve been developing on a separate branch, you’re eventually going to have to merge it in to master. I’m not talking about that. In fact, you’d probably want to know about that merge.

Let’s look at a simplified scenario for a merge we don’t care about.

’X’ and ‘Y’ pull from the repository at 9AM. ‘X’ works on a patch, commits, pulls and pushes to the repository at 9:30AM. ‘Y’ works on a patch, commits, pulls and pushes to the repository at 10AM. Sounds good, right?

Pulling is equivalent to fetching and merging, resulting in “Merge branch ‘master’ of XYZ” and more funky, rainbow lines.

Suggestion

You could stash your changes, pull, pop and push. That’s great until you have about 2 or 3 commits you want to push. Plus, I don’t want to have to think about this.

Enter rebase.

You can rebase your “local/master” branch against “origin/master”. This is not the same as rebasing an already shared branch, because your commits have not been published. You should never rebase something you’ve already pulled down.

Suggested workflow might look something like this.

$ git commit
$ git pull
$ git rebase -i origin/master
$ git push origin master

This has the advantage that you don’t need to execute the last two commands if there is nothing new pulled down from the second command. It also gives you a chance to squash commits into something more meaningful. Sometimes you want to do this, sometimes it’s better to keep them separate. I’ll leave that to you.

Generally this isn’t an issue, but last week we saw a flurry of commits to the repository. Such a process would keep the history nice and linear.

Cheers,
Tatey

PS: I’ve been secretly doing this.


12 Apr 2009

Layouts with Smarty

Smarty doesn’t appear to support layouts, an incredibly useful concept for separating reusable markup in views.

Documentation has an example using the {include} tags for including a header and footer template in to each of your views. I think this approach is repetitive and not as flexible as it ought to be.

My expectations:

Fortunately, there is a fetch() function that returns the template output as a string. Taking the earlier example of the header and footer, I wrote a simple wrapper function to do this for me.

<?php
// includes/controllers/base_controller.php
require('Smarty.class.php');

public function __construct()
{
  $this->smarty = new Smarty();
}

public function render_layout($view, $layout = 'application')
{
  echo(
    $this->smarty->fetch('layouts/' . $layout . '/header.tpl') .
    $this->smarty->fetch($view) .
    $this->smarty->fetch('layouts/' . $layout . '/footer.tpl')
  );
}
<?php
// includes/controllers/items_controller.php
public function show()
{
  $this->smarty->assign_by_ref('item', Item::find_by_id($this->params['id']));
  $this->render_layout('items/show');
}

While it’s no where near as nice as layouts in Rails, it is a small amount of effort for greater flexibility in your views with Smarty.


06 Apr 2009

Having a flashback

Searching for a mock up in my abandoned design directory, I stumbeld on some interesting images. They were created in Flash, when it was owned by Macromedia and the major release number was 4.

P200

P200

Second family computer. Intel Pentium 200Mhz with a 17” CRT. Memories of Command & Conquer, Team Fortress Classic, mIRC, FrontPage, non-breaking spaces and Internet Explorer 4.0.

The Water Tank

The Water Tank

Second or third personal computer. Intel Pentium 4 1.6GHz with water cooling and an 16x2 LCD for displaying system statistics. Memories of Warcraft 3, Counter-Strike, Mandrake Linux, Stylesheet enlightenment, Photoshop 5.0, and Mozilla Phoenix.

Like P200, there was suppose to be a matching display. I drew it, I just can’t find it. I had the intention that the “on” button would boot the computer in to Windows XP.

View a photo of the box in all its glory. Like anyone else interested in PC hardware as a young teenager, you had a powerful computer and a shitty desk, chair and keyboard.


05 Apr 2009

Obligatory hello, world!

I’ve spent a good part of today on the seventh iteration of tatey.com.

  1. Design
  2. XHTML/CSS
  3. Jekyllfy
  4. About content
  5. Generate and publish

It’s generated by Jekyll, a blog-aware, static site generator in Ruby. Posts are in Markdown and the source resides on GitHub, never to be lost again! Site conforms to the XHTML 1.0 and CSS 2.1 specifications. All pages are valid and semantic. I’ve only tested in Firefox 3.0.8 and Safari 4b on Mac OS X. If you find an error, please let me know.

Next step is to automate deployment.


Tate Johnson is a 22 year old Ruby on Rails developer and university student living in Brisbane, Australia. He enjoys riding bicycles, motorbikes, taking photos and travelling. Subscribe to the feed.