13 May 2013

Installing ruby 2 + Rails 4 on Ubuntu 12.04 LTS

Installing Ruby 2 + Rails 4 on Ubuntu 12.04 LTS

Update Dec 2013: You may also wish to read benkwok's blog post on installing ruby and rails. I've also posted my notes from installing for an existing project which doesn't entirely replace this post but reflects my more recent learnings.

There's a few of these blog posts around, but here's mine for my own benefit (I'm sure this won't be the last time I do it!).

If you have a packaged ruby / rails / rvm / rbenv etc installed, get rid of them all, eg:

$ ruby --version
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
$ sudo apt-get remove ruby

Don't use rvm; and make sure it's been literally purged from your system. It's a pain to remove as it gets into all sorts of places and even apt-get purge doesn't undo changes to the profile etc. If you want to know more about the reason for not using it then read the rbenv "why" page, it's persuasive stuff.

My recommendation from experience so far is to use rbenv to install the latest and greatest RoR (Ruby on Rails). Don't bother with the ubuntu packaged version of rbenv (from apt etc) as you'll be off the beaten track and will have to figure out the ruby-build plugin installation yourself. The local user install is painless and works well. The instructions say to make sure rvm is removed first as it's incompatible.

rbenv installation

Install rbenv into your home directory:
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv

Set up the environment as per the (ubuntu specific) rbenv installation instructions:

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile
$ echo 'eval "$(rbenv init -)"' >> ~/.profile

Unless you've done anything before, there is no ~/.profile file before hand, so the contents will then be:

$ cat ~/.profile
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

Restart the login shell:

$ exec $SHELL -l

Check rbenv is now available:

$ rbenv
rbenv 0.4.0-45-g060f141
Usage: rbenv <command> [<args>]
...

Set up the ruby-build plugin (as linked in the rbenv readme)

$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Install the necessary ssl library:

$ sudo apt-get install libssl-dev

If you don't install the openssl development libraries you get this:

BUILD FAILED
...
The Ruby openssl extension was not compiled. Missing the OpenSSL lib?




Ruby installation

Install the latest ruby (version name obtained from release info on ruby blog), takes 5-10 mins

$ rbenv install 2.0.0-p0

Now select the installed ruby as the default for your user (ref: https://github.com/sstephenson/rbenv#choosing-the-ruby-version)

$ rbenv global 2.0.0-p0 
tim@atom:~$ ruby --version
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]


Rails installation

Now as per the Rails 4 RC1 announcement install the release candidate of Rails 4 (this was the latest at time of writing). Takes 5-10 mins.
$ gem install rails --version 4.0.0.rc1 --no-ri --no-rdoc

Tell rbenv to create the new shims and see the installed rails:
$ rbenv rehash
$ rails --version
Rails 4.0.0.rc1



All done! That wasn't so hard, it was all the blind alleys that took the time.

Now use bundler as recommended in the rbenv readme to set up an app etc.

Thanks for listening :-)

Footnote: It pains me somewhat to have to use installations outside of the Ubuntu package manager, however it seems there are some grumblings about the packaged versions of the above software. Add into this that I wish to use the latest RoR on an LTS release of Ubuntu which seeing as the Rails community don't seem to provide debs / repos etc leaves a packaged version out of the question for now. I've learned previously the hard way the destructive effect of randomly installing everything you find outside the package management system of a distro so have tread carefully when creating the above information.

Further reading http://benkwok.wordpress.com/2013/08/15/install-rails-on-ubuntu-12-04-lts-with-rbenv/

02 April 2013

Java checked and runtime exceptions and how to transition

As primarily a C# programmer I've never been sold on checked exceptions, mostly seeing them as an unnecessary nuisance forcing programmers to introduce reams of boilerplate throws / try-catch blocks into their consuming code to propagate these exceptions up the stack.

Whilst coding on https://github.com/timabell/FreeTTS I was forced to deal with this personal demon.

I've read that checked exceptions are a way of making exceptions be part of the declared API for some class or library, and that it forces client programmers to handle error conditions that the API programmer knows are likely to occur (e.g. the library relies on the filesystem internally so declares it throws a IOException when calling a relevant method.

I have some sympathy with this idea and can see how it can allow for more robust code when done well. My experience has generally been that it is not handled well and the reaction is to add a lot of meaningless code or to throw away the exception and hide the problem, causing difficulties troubleshooting later.

When I've been in control of the API I've been tempted to always through runtime exceptions and avoid the problem entirely, however this time whilst working on someone else's class I came across a call to an external library that threw an IOException which I couldn't change. This made me think a bit harder about the problem. I initially thought my options were to immediately catch and rethrow as a runtime exception or to add throws IOException / throws Exception to every piece of the call chain.

I tried the latter approach of propagating the throws up through many layers, which although messy did work; right up until I hit a call within a toString() method, which is defined by Object and doesn't allow you to change the API of the method (by adding a checked exception). Incidentally I think that having toString() rely on code that could throw a file system exception like this did is a dodgy design, but that wasn't my code and would have been a large rewrite.

So after a bit of grumbling to myself I looked more closely at the fault line between the checked exception being thrown and the rest of the codebase. The existing code was just ignore the error with catch {} (shudder) and returning null, making it hard to troubleshoot a failing JUnit test.

I think the answer to the conundrum is that for each method in the chain you have to decide if callers of the method could usefully handle the error condition, or whether they could add any useful information to the stack trace to assist troubleshooting. Here's roughly the approach I've taken which I think should be illustrative:

Method that throws

String getSomething(string filename) throws IOException {
    // do some file IO
    return someData;
}

Next method up. Doesn't compile as checked exception not handled, what to do?

String loadFoo() {
    String foo = getSomething("this.txt");
    return foo;
}

In this case I don't think getSomething should be the last point in the chain as it doesn't know why it was performing the operation it was. loadFoo however knows both the resource being accessed and what the intent was, so can report an exception message that should point someone troubleshooting immediately to the source of the problem and inform them what the program was trying to achieve. Having loadFoo() declare that it throws IOException doesn't make sense as the caller shouldn't need to know how loadFoo gets its data, it's just the kind of noise that programmers dislike Java for. So the answer in my opinion is because loadFoo() is best placed to give all the useful information needed to fix the problem, it should catch the checked exception, wrap it in a runtime exception, add a useful message and rethrow it. This saves callers from needing to handle exceptions that they can't usefully deal with, whilst still providing good troubleshooting information. And yet there's still a use for the checked exceptions as getSomething() was able to declare that it new an IOException was possible but that it wasn't in a position to give enough useful information.

So the final code I ended up with looked something like this:

String getSomething(string filename) throws IOException {
    // do some file IO
    return someData;
}

String loadFoo() {
    String filename = "this.txt";
    try {
        String foo = getSomething(filename);
        return foo;
    } catch (IOException ex) {
        throw new RuntimeException("Failed to read foo from '" + fileName + "'", ex);
    }
}

Inversion of control (IoC)

A colleague of mine mentioned IoC as a problem for checked exceptions. This is an interesting point and does complicate things.

References

05 December 2012

Subversion to git - the pain retold

I've spent a week reminding myself why svn sucks.

I've been using the freetts library for speech synth in the communication book program I've been working on, and have tripped over a bug in freetts running under openJdk. The freetts source code lives in a svn repository on sourceforge. The first step in troubleshooting is to build the library from source. In order to track any local experimentation / fixes I need to have some kind of local source control, and svn sucks too much to provide this. The obvious next step is to pull the sources down with git-svn (or svn2git as github recommends).

After a couple of aborted attempts I was reminded how the loosely defined structure of a svn repository and the over-generalization of tags & branches allows for a complete mess, which then is a pain to import cleanly.

"And they want to make snapshots of smaller subdirectories of the filesystem. After all, it's not so easy to remember that release 1.0 of a piece of software is a particular subdirectory of revision 4822."  --   Argh! Terrible "feature", if you're using this feature then you're doing source control wrong! (Quote taken from http://svnbook.red-bean.com/en/1.7/svn.branchmerge.tags.html )

I could just grab a tarball and start from there, however there is new code upstream since their last release (v1.2.2), and that means testing two branches, and possibly investigating diffs. In addition if I'm going to make the effort to import the history, I ought to do it well enough first time that others can build on it. It's much harder to correct a bad scm import once work is continued, especially in the distributed world of open source.

And so, for my sins, I set about importing the history, and hacking away at it with the excellent tools git provides to turn it into something that actually linked together correctly and didn't make me feel ill by including CVSROOT all over the place (yes, it's not the first migration this project's been through).

On the plus side, it is fantastic that the open source license gives a user of a library such as myself the right to go ahead and do something like this and to share the improvement with the world, regardless of whether it's something the original creators / maintainers would have done.




The layout of the FreeTTS svn repo is not consistent in directory structure, which means the svn import tools don't behave quite as one might expect. This is the inevitable downside to subversions poor choice of architecture around "everything's just a directory structure". (Bitter? Me? Never!)

Here's a taster of how inconsistent the layout is and what a challenge is ahead tidying it up:

tim@atom:~/repo/freetts.svn$ ls */*
branches/release:
FreeTTS

tags/freetts:
FreeTTS

tags/pre-rel1-1:
FreeTTS

tags/rel_1_0_5:
CVSROOT FreeTTS

tags/rel1_1_0:
FreeTTS

tags/rel1_1_2:
FreeTTS

tags/rel1_2_0:
CVSROOT FreeTTS

tags/rel1_2_1:
FreeTTS

tags/rel1_2_2:
acknowledgments.txt build.xml demo.xml index.html license.terms overview.html RELEASE_NOTES speech.properties tests
ANNOUNCE.txt demo docs lib mbrola README.txt rtp src tools

tags/rel_1_2_beta:
FreeTTS

tags/rel1_2beta2:
CVSROOT FreeTTS

tags/start:
FreeTTS

tags/sun:
FreeTTS

trunk/CVSROOT:
checkoutlist commitinfo config cvsignore cvswrappers editinfo loginfo modules notify rcsinfo syncmail taginfo verifymsg

trunk/FreeTTS:
acknowledgments.txt build.xml demo.xml index.html license.terms overview.html RELEASE_NOTES speech.properties tools
ANNOUNCE.txt demo docs lib mbrola README.txt rtp src unittests


It took all my git-fu powers to sort out this mess. Below is a time shortened sequence of how it was done, just in case I have the misfortune to need to do it again. I ended up abandoning all the ancient tags as they were going to be more effort than I liked to fix, and they could be added retrospectively if anyone really cared. It took me many attempts to get to the below, and this is what I've reconstructed from my fragmented history, hopefully it will provide enough clues should you wish to do similar.


FreeTTS project urls: Project front page http://freetts.sourceforge.net/ , project site http://sourceforge.net/projects/freetts/ , repo browser http://freetts.svn.sourceforge.net/viewvc/freetts/ , svn http access https://freetts.svn.sourceforge.net/svnroot/freetts/
At time of writing the current svn revision is 582.

The latest packaged version for ubuntu:
apt-cache show freettsPackage: freetts
Priority: optional
Section: universe/java
Installed-Size: 13532
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>Original-Maintainer: Bdale Garbee <bdale@gag.com>Architecture: all
Version: 1.2.2-3Depends: default-jre | java2-runtime
Filename: pool/universe/f/freetts/freetts_1.2.2-3_all.deb
Size: 9456904
MD5sum: 183bed09b1b8e2d8642f46b7538273f4
SHA1: 8df47df82124704b890f446a1bc958d33fd273d3
SHA256: 8920440eaa58c087cb268e8e2a64d44ac873fb44d49b34f180f587f9c69421a7
Description-en: speech synthesis system
FreeTTS is a speech synthesis system written entirely in the Java(TM)
programming language. It is based upon Flite, a small run-time speech
synthesis engine developed at Carnegie Mellon University. Flite in turn
is derived from the Festival Speech Synthesis System from the University
of Edinburgh and the FestVox project from Carnegie Mellon University.
Homepage: http://freetts.sourceforge.netDescription-md5: a346fe6dcc2c0164ec6b7c3891945e56
Bugs: https://bugs.launchpad.net/ubuntu/+filebugOrigin: Ubuntu


So here's the import more or less as it happened:

mkdir freetts.svn.git; cd freetts.svn.git
svn2git --verbose https://freetts.svn.sourceforge.net/svnroot/freetts/
git gc

cat .git/config
[core]
 repositoryformatversion = 0
 filemode = true
 bare = false
 logallrefupdates = true
[svn-remote "svn"]
 noMetadata = 1
 url = https://freetts.svn.sourceforge.net/svnroot/freetts fetch = trunk:refs/remotes/svn/trunk
 branches = branches/*:refs/remotes/svn/*
 tags = tags/*:refs/remotes/svn/tags/*
[branch "release"]
 remote = .
 merge = refs/remotes/svn/release


# get a copy without the svn references (which stop us seeing whether the rewritten history is free of old cruft)
cd ..
git clone freetts.svn.git/ freetts.git
cd freetts.git/
gitk --all &
# The following is done while keeping an eye on and refreshing (ctrl+f5) gitk to see the effects:
# Filter out the cvs rubbish so that git can match up commits that do have it with commits that don't
git filter-branch --tree-filter 'rm -rf CVSROOT' --prune-empty -- --all
# Remove the unnecessary top level folder (which inconsistently existed)
git filter-branch --prune-empty --subdirectory-filter FreeTTS/ -- --all
# Remove the backup refs filter-branch creates
rm -rf .git/refs/original/

# delete all the crappy svn "tags", just tag the latest
git tag -d `git tag`
Deleted tag 'freetts' (was 8d953b7)
Deleted tag 'pre-rel1-1' (was d1c597f)
Deleted tag 'rel1_1_0' (was 625abdd)
Deleted tag 'rel1_1_2' (was b51fb71)
Deleted tag 'rel1_2_0' (was 7a4fc18)
Deleted tag 'rel1_2_1' (was a126a4a)
Deleted tag 'rel1_2_2' (was b3a0dcf)
Deleted tag 'rel1_2_2@557' (was bf94dbe)
Deleted tag 'rel1_2beta2' (was c0d90e9)
Deleted tag 'rel_1_0_5' (was e95aff8)
Deleted tag 'rel_1_2_beta' (was 1723b2d)
Deleted tag 'start' (was c020efe)
Deleted tag 'sun' (was cfadbc8)

# correct commit found manually:
git tag v1.2.2 ae49425

and finally, push to github

git remote add origin .... (my repo details)
git push --mirror

You can find my repo at https://github.com/timabell/FreeTTS
and the intermediate copy here: https://github.com/timabell/FreeTTS-svn-mirror

All done

^_^



Here's the reason I didn't bother with tags in the end: I couldn't rewrite the tags as they had no author:

git filter-branch --tree-filter 'rm -rf CVSROOT' --prune-empty --tag-name-filter cat -- --tags
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f
tim@atom:~/repo/freetts.git$ rm -rf .git/refs/original/
tim@atom:~/repo/freetts.git$ git filter-branch --tree-filter 'rm -rf CVSROOT' --prune-empty --tag-name-filter cat -- --tags
Rewrite 8611e271692fc33e6160a2a217b9b3060dfbcd1d (1044/1044)
Ref 'refs/tags/freetts' was rewritten
WARNING: Ref 'refs/tags/pre-rel1-1' is unchanged
WARNING: Ref 'refs/tags/rel1_1_0' is unchanged
Ref 'refs/tags/rel1_1_2' was rewritten
Ref 'refs/tags/rel1_2_0' was rewritten
Ref 'refs/tags/rel1_2_1' was rewritten
Ref 'refs/tags/rel1_2_2' was rewritten
Ref 'refs/tags/rel1_2_2@557' was rewritten
Ref 'refs/tags/rel1_2beta2' was rewritten
Ref 'refs/tags/rel_1_0_5' was rewritten
Ref 'refs/tags/rel_1_2_beta' was rewritten
Ref 'refs/tags/start' was rewritten
Ref 'refs/tags/sun' was rewritten
freetts -> freetts (b3a4bbf8768ade6275c91ce0e76d933e30b3ddbf -> 48e84e3560e765db3b33479e2e9a76fe2ccf3550)
error: char79: malformed tagger field
fatal: invalid tag signature file
Could not create new tag object for freetts



git show rel_1_2_beta | head
tag rel_1_2_beta
Tagger: (no author) <(no author)@4963320b-1a4a-0410-81c8-f0a525965860>Date: Mon Dec 22 14:46:05 2003 +0000

This commit was manufactured by cvs2svn to create tag '\''rel_1_2_beta'\''.

commit 57ed00e981585aad590c9521d7c3a0bccf6284fa
Author: (no author) <(no author)@4963320b-1a4a-0410-81c8-f0a525965860>
Date: Mon Dec 22 14:46:05 2003 +0000

------

My advice if you are importing svn for a commercial project: Don't! Just export, and import into your new source control tool. Leave the svn repo read only for a while just in case you need that history, and after a year of never looking back, archive it off.

10 July 2012

AA Gold member benefits, the real cost

Breakdown cover maths

So, I'm getting rather fed up with the AA taking the michael every year with their renewals. Yes, I gather the RAC are just as bad but I think they need to realise their customers aren't stupid, know exactly what they are playing at, and can do the maths.

I want to highlight what I think is a particularly dirty trick, making something look like a free perk when it's anything but.

So here's some numbers:

This is for a single car policy covering Roadside, Home Start and Relay starting July 2012 paying annually for a year up front. (The monthly option is 10% more expensive, go figure). Numbers rounded to pounds.


  • Renewal through the post: £135
  • Matching RAC cover (checked online & by phone): £101
  • AA online price for new customers: £92  - (so much for 6 years loyalty, a £43 kick in the teeth)
  • AA phone price: £116
  • AA phone price without gold membership "benefits": £89



That means, the AA are pricing their gold benefits at £27 even though they look like they are free on the renewal letter! Some cheek.


I queried the details of this so called benefit and established the following:
  • "Accident Management" - means being towed by the AA after an accident (something you may be covered for under your car insurance policy)
  • European Breakdown Cover - only useful if you are going abroad (obviously), did you really want to be paying for it?
  • "Family Associates Cover for under 17s" - something about teenagers, I don't have any so not very useful to me
  • Key Insurance - this could be valuable, but £27/year sounds like very expensive insurance to me even though they are expensive items to replace.
  • Legal Advice - Included as standard! So not a gold benefit at all. Weasels.
  • Technical Advice - Included as standard! See above. Still weasels.

So it turns out that the supposed discount of £44.90 on the posted renewal was actually a £46 insult to my intelligence.


I'm no money saving expert, but that's outrageous.

Configuration confusion in visual studio

Here's a gotcha that got me.

It is not immediately obvious, but visual studio stores in it's sln file a set of project configuration selections for every combination of solution configuration and solution platform.


The gotcha is that by default Visual Studio (all versions 2008-2012 as far as I know) only show one half of that combination in the standard toolbar, so you can get in a situation where one of your developers is building something completely different to everyone else as somehow the platform has silently been changed.

I recommend you add Platform to your toolbar so that you can always see what you are about to build.




And if possible, remove any unused platform configurations from your solution entirely.

14 June 2012

automatic mysql backups

On a debian server with mediawiki installed and running with a local mysql.

root@myserver:~# apt-get install automysqlbackup

root@myserver:~# crontab -e

# m  h  dom mon dow   command
  5  4  *   *   *     automysqlbackup


root@myserver:~# automysqlbackup
root@myserver:~# cd /var/lib/automysqlbackup/
root@myserver:/var/lib/automysqlbackup# find .
.
./weekly
./weekly/wikidb
./weekly/information_schema
./daily
./daily/wikidb
./daily/wikidb/wikidb_2012-06-14_16h03m.Thursday.sql.gz
./daily/information_schema
./daily/information_schema/information_schema_2012-06-14_16h03m.Thursday.sql.gz
./monthly


Result! No longer need to write a custom cron script each time.


Project homepage: http://sourceforge.net/projects/automysqlbackup/

11 June 2012

Connecting to smb shares on a domain in gnome

The domain name has to be UPPERCASE otherwise authentication fails.

Majorly confusing.

Time lost: 3 hours.



Sigh