Category: rubicant

Rubicant’s first real build

Posted by on September 13, 2009

So I’ve been using rubicant for a while personally, but never on anything beyond my own projects and not for anything big. After reading Ayende’s post about building Rhino Mocks with PSake, I wondered if rubicant could so something similar, so I decided to port his build script.

Of course, I didn’t have a generate assembly info method, so I basically took Oren’s and ported it as well (sorry Oren, I’ll take it out if you want). At the same time, I took the opportunity to remove the dependency on configatron from rubicant as well. It just seemed like overkill to require configatron when it really wasn’t buying me much.

In the end, I came up with this, which on the whole I don’t think looks too bad. I personally like it better, but I’ve been on a bit of a vendetta against PowerShell scripts since I wrote my first one some time ago. I don’t know why, but the friction it gave me over writing ruby scripts just always rubbed me the wrong way.

 

require 'fileutils'
require 'rake'
require 'rubicant'
include Rubicant

base_dir  = File.expand_path(".")
lib_dir = "#{base_dir}\\SharedLibs"
build_dir = "#{base_dir}\\build"
buildartifacts_dir = "#{build_dir}\\"
sln_file = "#{base_dir}\\Rhino.Mocks-vs2008.sln"
version = "3.6.0.0"
human_readable_version = "3.6"
tools_dir = "#{base_dir}\\Tools"
release_dir = "#{base_dir}\\Release"
upload_category = "Rhino-Mocks"
upload_script = "C:\\Builds\\Upload\\PublishBuild.build"
mbunit_dir = "#{tools_dir}\\MbUnit"

task :default => :release do
end

task :clean do
  rm_rf buildartifacts_dir
  rm_rf release_dir
end

task :init => :clean do

	generate_assembly_info({
		:path => "#{base_dir}\\Rhino.Mocks\\Properties",
		:title => "Rhino Mocks #{version}",
		:description => "Mocking Framework for .NET",
		:company => "Hibernating Rhinos",
		:product => "Rhino Mocks #{version}",
		:version => version,
		:cls_compliant => false,
		:copyright => "Hibernating Rhinos & Ayende Rahien 2004 - 2009"})

	generate_assembly_info({
		:path => "#{base_dir}\\Rhino.Mocks.Tests\\Properties",
		:title => "Rhino Mocks Tests #{version}",
		:description => "Mocking Framework for .NET",
		:company => "Hibernating Rhinos",
		:product => "Rhino Mocks Test #{version}",
		:version => version,
		:cls_compliant => false,
		:copyright => "Hibernating Rhinos & Ayende Rahien 2004 - 2009"})

	generate_assembly_info({
		:path => "#{base_dir}\\Rhino.Mocks.Tests.Model\\Properties",
		:title => "Rhino Mocks Tests #{version}",
		:description => "Mocking Framework for .NET",
		:company => "Hibernating Rhinos",
		:product => "Rhino Mocks Test Model #{version}",
		:version => version,
		:cls_compliant => false,
		:copyright => "Hibernating Rhinos & Ayende Rahien 2004 - 2009"})

	mkdir release_dir
	mkdir buildartifacts_dir

	cp_r "#{mbunit_dir}\\.", build_dir
end

task :compile => :init do
	MsBuildRunner.new(:properties => { :OutDir => buildartifacts_dir },
					  :project_file => sln_file).run
end

task :test => :compile do
	begin
		MbUnitRunner.new(:mbunit_dir => build_dir,
					 :test_files => ["Rhino.Mocks.Tests.dll"],
					 :report_type => 'Html').run
	rescue
		fail 'Error: Failed to execute tests'
	end
end

task :merge do
	begin
		rm_f "#{build_dir}\\Rhino.Mocks.Partial.dll"
		mv "#{build_dir}\\Rhino.Mocks.dll", "#{build_dir}\\Rhino.Mocks.Partial.dll"

		sh "#{tools_dir}\\IlMerge.exe " +
			"#{build_dir}\\Rhino.Mocks.Partial.dll " +
			"#{build_dir}\\Castle.DynamicProxy2.dll " +
			"#{build_dir}\\Castle.Core.dll " +
			"/out:#{build_dir}\\Rhino.Mocks.dll "+
			"/t:library "+
			"/keyfile:#{base_dir}\\ayende-open-source.snk " +
			"/internalize:#{base_dir}\\ilmerge.exclude"

	rescue
        fail 'Error: Failed to merge assemblies!'
	end

	puts "done merge"
end

task :release => [:test, :merge] do
	begin
		puts "Zipping files"
		sh "#{tools_dir}\\zip.exe -9 -A -j " +
			"#{release_dir}\\Rhino.Mocks-#{human_readable_version}-Build-#{ENV['ccnetnumericlabel']}.zip " +
			"#{build_dir}\\Rhino.Mocks.dll " +
			"#{build_dir}\\Rhino.Mocks.xml " +
			"license.txt " +
			"acknowledgements.txt"

	rescue
        fail 'Error: Failed to execute ZIP command'
	end
end

task :upload => :release do
	if (File.exists?(upload_script) )
		begin
			log = sh 'git log -n 1 --oneline'
			MsBuildRunner.new({:properties => { :Category => upload_category,
											   :Comment => log,
											   :File => "#{release_dir}\\Rhino.Mocks-#{human_readable_version}-Build-#{ENV['ccnetnumericlabel']}.zip" },
							   :project_file => upload_script }).run

		rescue
			fail "Error: Failed to publish build"
		end
	else
		puts "could not find upload script #{upload_script}, skipping upload"
	end
end

If you want to give this script a try (I’ve tried everything but the upload piece, which for obvious reasons I couldn’t test) just follow these steps:

  1. Get a copy of the rhino mocks source.
  2. Make sure you’ve got ruby installed.
  3. Make sure gem is up to date: “gem update –system”
  4. Add github to your gem sources: “gem sources -a http://gems.github.com
  5. Install rubicant: “gem install mendicantx-rubicant”
  6. Copy the above script into a file named rakefile.rb in the rhino mocks directory.
  7. Run it: “rake release”

God willing, this will work. I’ve tried it on a couple of fresh systems, but have no good way of knowing if it works beyond my machines. If you do on the offhand decide to try it, please let me know below!

rubicant – MsBuild Task added

Posted by on January 30, 2009

I just added an MsBuild task for rubicant tonight. I’m not very familiar with the command line options for MsBuild so some of these could probably be improved a bit, but until I know more I will leave them as they are.

The MsBuild Task is used to create tasks which will use MsBuild. This should help with people who need to build WPF applications (since MsBuild is the only way right now), or (fingers crossed) migrate from MsBuild.

The MsBuild Task is used as follows:

   1: MsBuildTask.new(:task_name => :dependencies) do |msb|
   2:   msb.no_autoresponse
   3:   msb.target
   4:   msb.logger
   5:   msb.distributed_logger
   6:   msb.console_logger_parameters
   7:   msb.validate
   8:   msb.verbosity
   9:   msb.no_console_logger
  10:   msb.max_cpu_count
  11:   msb.ignore_project_extensions
  12:   msb.file_logger
  13:   msb.distributed_file_logger
  14:   msb.node_reuse
  15:   msb.properties
  16:   msb.file_logger_parameters
  17:   msb.project_file
  18: end

Each of setters matches a command line option for MsBuild. For more information on what each one does, please view the documentation at http://msdn.microsoft.com/en-us/library/ms164311.aspx.

Values that can only be set (for example, /noautoresponse) can be set to true (set) or nil (unset).

Values, such as /property that take a list of option settings, must be passed a hash where the keys are the options and the values are the option values. For example, to set the output directory and Warning Level for a csproj compile, you could use:

   1: MsBuildTask.new(:compile) do |msb|
   2:   msb.properties = { :OutputDir => ".\\Output", :WarningLevel => 2 }
   3:   msb.project_file = ".\\Project1\\project.csproj"
   4: end

As of yet, I haven’t added an MsBuild helper to help create this function. I will probably get this done fairly shortly.

rubicant update – Easy installation via gem

Posted by on January 25, 2009

Since I already had rubicant building as a gem, it made sense to make it available as a gem. I have moved the project to github and it is now located at: http://github.com/mendicantx/rubicant/

In addition, you can also install rubicant via gem:

   1: gem sources -a http://gems.github.com
   2: sudo gem install mendicantx-rubicant

You should only ever have to run the gem sources command once. This adds github to your sources of remote gems. From what I understand, there’s a ton of great projects there.

Now you don’t have an excuse to try it out!