(filtered by tag 'ruby')

My Idea flies again!

Added: September 03, 2008

Tags: idea ruby

Project I am currently working on has rather sophisticated build system. I believe that huge project as this one is deserves it. It has many advantages and a few disadvantages. Problem is that it is optimized for Eclipse as all developers are using it.

Unfortunatelly, some features like:

  • dependencies between modules done through jar files
  • regeneration of Eclipse's project files by Ant (needed every time you update jar files)
  • dependenent jars copied to target/
  • fact that Eclipse does not distinguish between production and test sources
made my life with Idea miserable in the beginning. It used lot of memory, was slow and needed refresh of internal data often (very slow in Idea) and remote debugger was not able to switch to different module. I gave a chance to Eclipse (3 weeks) before returning to Idea with goal to overcome all these problems (plus those happening in Eclipse too like impossibility to refactor between projects) by custom scripts.

I started slowly, then I added more features. Because my goal was to fix problems in Eclipse/Idea integration, fix disadvantages in dependencies as well as to fix management of project I rejected an idea to create plugin as it would need learning huge Plugin SDK and it could not help me to solve all problems. I decided to go through command line scripts (not to mention I never liked to do project management related tasks through IDE). My scripts are done in Ruby.

I am able to clean all projects in directory by subsequent calling of 'ant clean' in all subdirectories:

def clean
    in_dirs_with 'build.xml' do
        system 'ant clean'
    end
end
I was really nicely surprised seeing how nice and readable those simple tasks could be. I added a few more:
def update
    in_dirs_with '.svn' do
        system 'svn up'
    end
end

def eclipse
    in_dirs_with '.classpath' do
        system 'ant eclipse'
    end
end

All magic is hidden in following method:
	def in_dirs_with(guard)
		Dir['*'].each do |dir|
			if File.exist?("#{dir}/#{guard}")
				puts "Processing #{dir}..."		
				Dir.chdir(dir) do
					raise Exception.new($?) unless yield
				end
			end
		end
	end
OK, less annoying things are handled, now I can get to fixing problems with Idea. I am not going to show any code for that, it is bigger, but I will describe what I have done:
  • script finds all generated .classpath and replaces jar dependencies with known sources (fixed refactoring and debugging problems)
  • script finds all .eml files (Idea keeps here information what .classpath belongs to module and what is missing in .classpath but Idea needs it). Script modifies it by stating which directories are tests and which directories to exclude from project.
With these two scripts my life is wonderful again (as it was before I joined this huge project with build system optimized for Eclipse). Idea responds immediately and I can refactor as no of my colleagues can :-) (well, they could use the one wiring modules together, because it modifies only .classpath, but they would need to install Ruby first).

Apart from that I have created small DSL that helps me to perform merges (merging multiple modules in Idea is rather annoying), but I needed it only twice. Example how merging file might look like follows:

Merger.new.
	from_revision(12305).
	from_branch('http://server/svn/branches/mybranch').
	to_branch('http://server/svn/branches/head').

	add_new('new_module').
	add_new('other_new_module').

	merge('changed_module1').
	merge('changed_module2')
end
If I tried to do it in Idea (similarly in Eclipse) I would need to state revisions and branches for every module that needs to be merged. Small script helped enormously with 10 modules I was merging last time. (Note: add_new is for adding module that was created in mybranch so it cannot be merged directly to head, at least I am not aware of directly working solution).

Doing these things is called yak shaving and considered problematic, but I have to say, my yak is shaved very well now and I guess time invested has been paid off for some time already.