06 January 2007

Fighting the invisible require_dependency!

(Warning: Skip this sentimental / philosophical introduction if you want practical information!)


Back in 1998, at my first job, I was working on client/server applications built with a framework made in France called NatStar. It's probably dead by now as I could not find any link in English! It was quite a blurg with crystal clear method names such as THINGS_GET_DB_ (sic) and I really feel sorry for the poor folks who have to maintain the existing programs. The only documentation available was the User Manual: 7 or 10 huge books!!! I remember spending ages skimming through these horribles books ...

We are in 2007 - less than a decade later! - and I feel lost if I don't have an Internet connection while I am programming, so do you, I guess ;-)
Every time, you run into a new problem, the new reflex is to google it and 80% of the time, you get an answer or at least a clue which help you to solve the problem!
I am not going to comment about the time you spend half procrastinating half reading forum archives instead of actually using your brain! No, I want to blog with you about what to do when google replies "Your search - "very complex problem" - did not match any documents."

Remembering you are a smart person, you'll probably find the solution in number_of_penguins+y*myloadfactor-mymanager_using_waterfall day(s). This could be the end of the story and it probably is in the majority of the cases - we are humans after all - but a minority thinks in a different way. BIG WOW: I am impressed by this minority.


Indeed, they make the choice to "loose" their personal / professional time just to share their solution with the World! Even if they might have narcissistic motivations (hello world, look how smart ass I am!), this kind of altruistic behavior is giving me a bit of faith in Humanity. After all, if all these people are doing it for FREE, there might be a chance to do something about the serious social and environments issues WE have (+ our grand-grand-n-grandchildren).


My point is, try to remember that money is just paper & ink (notes), metal (coins) and especially electrons (databases). Economy can't compete with the act of Giving. Sometimes, when I read newspapers talking about GNP growth (war || destructions => growth), I try to remember our collective madness and I feel quite sad. There is an expression in Spanish I hate: "Es lo que hay" (This is what we have and we have to live with it). NO.


"More than enough rope to hang yourself"

...was the talk Josh Susser was going to give at the RailsConf 2006 . His point was "the pitfalls of excessive cleverness in Ruby coding. Think of it as an antidote to all the talks you've seen about how to go nuts with metaprogramming". I agree with him, a good programmer is a programmer that writes code readable by everyone not only for the smart ass...

Yesterday, I spent hours trying to understand the following error message:

/test/unit/../test_helper.rb:19:
undefined method `use_transactional_fixtures=' for Test::Unit::TestCase:Class (NoMethodError)
This error message is completely useless!

A few people have come across the problem , a bug has been opened into the rails trac system but no solution ...

What did I do? Just a plain and simple refactoring, I had renamed the user model class used by the Login generator .
It happens that I had forgotten to rename the first line of lib/ with contained a require_dependency "myusermodelclass"
The import was failing but no exception thrown, the consequence was that the test_helper was not loaded properly, hence the error message because the use_transactional_fixtures is the first line loaded in test_helper ...

So if you have the same problem, my advice is to check all your require and require_dependency.

The good new is that I am using Rails 1.16 and it seems that the problem will be solved in Rails 1.2 by a patch .

I think that the method require_dependency could have better defined:

dependencies.rb
Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
Maybe I am not an expert in ruby but I think that dynamic code is dangerous in general because it's harder to debug, hence loosing quite a lot of productivity. Nothing worths more than a nice exception stack!

This makes me think about the lack of refactoring tools for ruby, I can't imagine the same thing with java and Eclipse. Hopefully, we'll have our IDEs for ruby in 2007!

28 December 2006

Continuous Integration Workflow

Warning: Article in construction!!!

Requirements

Before reading my prose, I am going to give you some homework, you are going to print the Martin Fowler 's paper Continuous Integration and read it thoroughly.

A bit of history!

Skip this part if you want real meat, it's just rhetoric!

My obsession / passion / addiction for x-unit frameworks comes from back in 2001, I was feeling a bit depressed by the low quality of code and the amount of bugs generated by my team
Then I came across the books written by Fred, Kent and Martin and that was like a revelation ... Lots of bla bla missing!

At the end of his article, Martin affirms that "... Continuous Integration has become a mainstream technique ....". To be realistic, I'd rather say will become a mainstream technique. I have worked in France, UK and Spain and I have the feeling we are not there yet! Give us a few years, Martin!

How was it before Continuous Integration?

Ah ah! Too many bad memories here ;-) Just a lot of time wasted and a source of conflicts within the team creating a bad moooooood ...
I am willing to draw a comic, Dilbert's style to illustrate my thoughts ...

Continuous Integration Workflow

This diagram is an attempt of making a picture from Martin Fowler and James Shore's words ...

Note : A Repository is a Source Control Management Repository. In the Subversion jargon, a Repository holds the source code of a project in a folder called trunk.

Development Steps:

  1. Update repository. To make sure sure you are always working the ''latest'' source code, start with getting the latest version of the project by updating your local repository.

  2. Lock existing files. (Optional step) Optimistic Locking VS Pessimist Locking, this debate can go on for ages ;-) I tend to consider the merges as a waste of time and try to avoid it as much as I can. More than a physical lock, which seems a bit extreme, I'd recommend that developers need to be aware about the W4 (Who's Working on What and When!). It is called Communication by normal people ;-)

  3. Create new files you need. This step is quite obvious, I put it as a reminder for step for step 6 (add the new files to svn) because this is a common mistake to forget to add the new files to the SCM.

  4. Development. using a Test Driven Development, Behavior Driven Development or a more traditional approach with a good test coverage. Make sure you run all the tests of the project, you never know - your first class code might have broken something - this is called regression.

  5. Update repository. How many times have I forgotten that step! The other folks in the team have been busy since you started working and you need to make sure you have the latest version. After the update, run all the tests another time, if there is a problem, it's probably in your code! This should encourage you to integrate more frequently.

  6. Add the new files to SCM. Jay Fields wrote a rake task which does the work with subversion.
  7. Check the build status. Before committing, you should check the build status and wait for 10 minutes if there is an integration running. Cool tools such as Cruise Control help a lot regarding that matter but we don't have that in the Rails world yet (remember the title of the article), hence we'll do it "manually".

Integration Steps

  • A. Commit files. Run to the integration box and start the integration process.
  • B. Tests run on Integration machine.
  • C. Rollback your changes. If the code can't be compiled or test the fail, you must ensure that the integration repository contains safe code, hence you need to rollback your changes and go back to your box to solve the problem. Sometimes, you can't reproduce the problem on your box and you'll need to play with the integration box: check the environments variables, dependencies, etc ...
  • The End. That's it, the integration is a success: play a noise, change the color of your nabaztag! Unlock the files you were working with. The Continuous Integration application should have updated the Integration logs (journal) and send an e-mail to team so they can think about updating their local box (the sooner, the better!).




Note: You will have guessed that I am not a native English speaker. Even if I am doing my best to write in a good English, I guess the result is far from being perfect ... Hence, I won't mind you people tell me about the typos ;-) Thanks in advance!


As a matter of fact, I am not pretending to be a Continuous Integration guru and I'd be happy to learn and debate, please send me a lot of comments!


Implementing Continuous Integration in a Rails project

Just an awful bunch of links for now. I have to say I don't know yet the best method!!! But I will write another post as soon as I have more experience ...

Cruise Control is a wonderful opensource tool for java projects, developed by Thoughtworks.
Damage Control, an cruise control for ruby but this a project currently not under active development, http://damagecontrol.codehaus.org/Continuous+Integration+Server+Feature+Matrix

In the Rails world, DHH has developed us a plug-in which integrates with subversion and campfire: the Continuous Builder plug-in.
Jay Fields, a thoughtworker describes his experience in his blog: http://jayfields.blogspot.com/2006/07/ruby-continuous-integration.html
http://www.ryandaigle.com/articles/2006/05/24/continuous-integration-w-rails

Cerberus, http://cerberus.rubyforge.org/index.html

20 December 2006

DBDesigner 4 on Ubuntu

Simple problem: I wanted to install the excellent (and free) DBDesigner from fabFORCE.net on my Ubuntu 6.10 ( the Edgy Eft) .


Always the same answer, a quick googling gave some results:

  • a Blogger giving clear instructions about DBDesigner 4 on Ubuntu
  • WDokuWiki with a lot of things messed by different people (!). I love Wikis and I have been using them a lot since 2002 but you can't do anything against chaos ;-)
  • The Ubuntu forum , always the best source of information!


Half a hour later, despite all my funky tweaks (tweet tweet), I still can't connect to my existing databases and use the fabulous reverse-engineering feature !!!

Then - oh Happy Day - I came across a post by kno712 (thank you).


5 Cups of Ubuntu

Join Date: Jul 2006
Beans: 45
Re: A small guide to install DBDesigner4

Quote:
Originally Posted by Dzo View Post
I have exactly the same issue. Looking like its just the way the application is though, have a look at the screenshots on the website!

It's a shame because its seriously putting me off using it!

Try installing the windows version with wine. Fonts are much better (IMO the website shows better fonts as well). Plus, you can connect to your databases without problems.


Here we go! I am already using wine-0.9.27 to work with an evaluation version of Dreamweaver 8 and this is an easy tool to use.


Update following Enigma Curry's commen:

Dialog boxes will pop under the main program window such that you'll have to minimize the main window to even see them. This seems to be a bug in wine... If this bother you as much as me, you'll reboot with windozzzz (sic) if you need to do a lot of work with DBdesigner !


Just to help, I have written a quick script:



# Go to a standard temp directory to download DBDesigner
cd /tmp
wget http://downloads.mysql.com/DBDesigner4/DBDesigner4.0.5.6_Setup.exe

# to install wine-0.9.27 if you haven't it
sudo apt-get -Y wine

# to install DBDesigner
wine DBDesigner4.0.5.6_Setup.exe

# To run DBDesigner
cd ~/.wine/drive_c/Program Files/fabFORCE
wine DBDesigner4.exe

One last thing is, compare the quality of the GUI and the fonts:






No doubt, the wine version ROCKS!

Morality: better stick to the simplest solution (I LOVE wine) and don't try to pretend you are a Linux professional !