The excitement concerning
Ruby seems to grow on a daily basis. The
Ruby on Rails framework,
RubyGems, and
Rake add to this excitement.
Martin recently wrote a great article about
Using the Rake Build Language.
Mike Ward asked me to help out with
NanoContainer.net by creating a build file. This seemed like a perfect time to make use of Rake.
To get started I thought a Hello World Rake build would be appropriate.
task :helloWorld do
sh "echo HelloWorld"
end
Next I work on using Rake & csc to compile NanoContainer.net.
file "build/NanoContainer.dll" => :init do
cd "src/NanoContainer"
sh "csc /out:../build/NanoContainer.dll /target:library /recurse:*.cs /lib:../build /r:'PicoContainer.dll;Microsoft.JScript.dll;VJSharpCodeProvider.dll'"
cd "../.."
end
task :init do
buildDir = "src/build"
mkdir buildDir unless File.exists?(buildDir)
cp "lib/PicoContainer.dll", buildDir
cp "lib/Castle.DynamicProxy.dll", buildDir
cp "lib/NMock.dll", buildDir
cp "lib/NUnit.Framework.dll", buildDir
end
The "build/NanoContainer.dll" file task depends on the init task. This is expressed by:
file "build/NanoContainer.dll" => :init
The init task is used to create the build directory if it's not already been created and copy the dlls that are referenced by NanoContainer and NanoContainer.Tests. The actual sh "csc .." is fairly straight forward; however, if you need more details on csc the "csc -?" command is quite helpful.
The "build/NanoContainer.Tests.dll" file task is very similar:
file "build/NanoContainer.Tests.dll" => [:init, "build/NanoContainer.dll"] do
cd "src/NanoContainer.Tests"
sh "csc /out:../build/NanoContainer.Tests.dll /res:'TestScripts/test.cs,NanoContainer.Tests.TestScripts.test.cs' /res:'TestScripts/test.js,NanoContainer.Tests.TestScripts.test.js' /res:'TestScripts/test.java,NanoContainer.Tests.TestScripts.test.java' /res:'TestScripts/test.vb,NanoContainer.Tests.TestScripts.test.vb' /target:library /recurse:*.cs /lib:'../build' /r:'PicoContainer.dll;Microsoft.JScript.dll;VJSharpCodeProvider.dll;Castle.DynamicProxy.dll;NanoContainer.dll;NMock.dll;NUnit.Framework.dll'"
cd "../.."
end
After building NanoContainer and NanoContainer.Tests I'm ready to create a test task. NUnit provides good
documentation for using the NUnit Console application; however, in my test task using the NUnit is very straight forward and easy.
task :test => :compile do
testCompVsBinDebugDir = "src/TestComp/bin/Debug"
mkdir testCompVsBinDebugDir unless File.exists?(testCompVsBinDebugDir)
cp "src/Build/TestComp.dll", testCompVsBinDebugDir
nanoTestVsBinDir = "src/NanoContainer.Tests/bin"
mkdir nanoTestVsBinDir unless File.exists?(nanoTestVsBinDir)
nanoTestVsBinDebugDir = "src/NanoContainer.Tests/bin/Debug"
mkdir nanoTestVsBinDebugDir unless File.exists?(nanoTestVsBinDebugDir)
cp "src/Build/PicoContainer.dll", nanoTestVsBinDebugDir
cp "src/Build/Castle.DynamicProxy.dll", nanoTestVsBinDebugDir
cp "src/Build/NMock.dll", nanoTestVsBinDebugDir
cp "src/Build/NUnit.Framework.dll", nanoTestVsBinDebugDir
cp "src/Build/NanoContainer.dll", nanoTestVsBinDebugDir
cp "src/Build/NanoContainer.Tests.dll", nanoTestVsBinDebugDir
cd nanoTestVsBinDebugDir
sh "../../../../lib/nunit-console.exe NanoContainer.Tests.dll"
end
The majority of the test task is about moving dlls into the NanoContainer.Tests/bin/Debug folder. This is needed because NanoContainer.Tests contains a few tests that use relative paths for testing. Eventually the tests should be refactored to remove this dependency, but I wasn't interested in taking care of this right now. Using Rake it's quite easy to move things around and that was the simplest solution.
I haven't used Rake to it's fullest. Even while I write this I can see things that I need to refactor. Unfortunately, when creating this rakefile I couldn't find much out there to help me. As more examples emerge I fully expect to see a much larger Rake adoption.
Here's my full rakefile for building NanoContainer.net
buildDir = "src/build"
nanoDll = "build/NanoContainer.dll"
nanoTestsDll = "build/NanoContainer.Tests.dll"
testCompDll = "build/TestComp.dll"
testComp2Dll = "build/TestComp2.dll"
notStartableDll = "build/NotStartable.dll"
nanoTestVsBinDir = "src/NanoContainer.Tests/bin"
nanoTestVsBinDebugDir = "src/NanoContainer.Tests/bin/Debug"
testCompBinDir = "src/TestComp/bin"
testCompBinDebugDir = "src/TestComp/bin/Debug"
task :default => [:compileInit, :compile, :test]
task :all => [:clear, :removeBuildDir, :removeVsDirs, :default]
task :clear do sh "clear" end
task :removeBuildDir => :clear do rm_rf(buildDir) end
task :removeVsDirs => :clear do
rm_rf(nanoTestVsBinDir)
rm_rf(testCompBinDir)
end
directory buildDir
task :compileInit => [buildDir] do
copyToDir(%w(lib/NUnit.Framework.dll lib/PicoContainer.dll lib/Castle.DynamicProxy.dll),buildDir)
copyToDir(%w(lib/NMock.dll lib/NUnit.Framework.dll),buildDir)
end
file nanoDll => :compileInit do
cd "src/NanoContainer"
sh "csc /out:../build/NanoContainer.dll /target:library /recurse:*.cs /lib:../build /r:'PicoContainer.dll;Microsoft.JScript.dll;VJSharpCodeProvider.dll'"
cd "../.."
end
file nanoTestsDll => [:compileInit, nanoDll] do
cd "src/NanoContainer.Tests"
sh "csc /out:../build/NanoContainer.Tests.dll /res:'TestScripts/test.cs,NanoContainer.Tests.TestScripts.test.cs' /res:'TestScripts/test.js,NanoContainer.Tests.TestScripts.test.js' /res:'TestScripts/test.java,NanoContainer.Tests.TestScripts.test.java' /res:'TestScripts/test.vb,NanoContainer.Tests.TestScripts.test.vb' /target:library /recurse:*.cs /lib:'../build' /r:'PicoContainer.dll;Microsoft.JScript.dll;VJSharpCodeProvider.dll;Castle.DynamicProxy.dll;NanoContainer.dll;NMock.dll;NUnit.Framework.dll'"
cd "../.."
end
file testCompDll => :compileInit do
cd "src/TestComp"
sh "csc /out:../build/TestComp.dll /target:library /recurse:*.cs"
cd "../.."
end
file testComp2Dll => [:compileInit, testCompDll] do
cd "src/TestComp2"
sh "csc /out:../build/TestComp2.dll /target:library /recurse:*.cs /lib:'../build' /r:'PicoContainer.dll;TestComp.dll'"
cd "../.."
end
file notStartableDll => [:compileInit, testCompDll] do
cd "src/NotStartable"
sh "csc /out:../build/NotStartable.dll /target:library /recurse:*.cs /lib:'../build' /r:TestComp.dll"
cd "../.."
end
task :compile => [nanoDll,nanoTestsDll,testCompDll,testComp2Dll,notStartableDll]
directory testCompBinDir
directory testCompBinDebugDir
directory nanoTestVsBinDir
directory nanoTestVsBinDebugDir
task :testInit => [testCompBinDir,testCompBinDebugDir,nanoTestVsBinDir,nanoTestVsBinDebugDir] do
cp "src/Build/TestComp.dll", testCompBinDebugDir
copyToDir(%w(src/Build/NMock.dll src/Build/PicoContainer.dll src/Build/Castle.DynamicProxy.dll),nanoTestVsBinDebugDir)
copyToDir(%w(src/Build/NUnit.Framework.dll src/Build/NanoContainer.dll src/Build/NanoContainer.Tests.dll),nanoTestVsBinDebugDir)
end
task :test => [:compile,:testInit] do
cd nanoTestVsBinDebugDir
sh "../../../../lib/nunit-console.exe NanoContainer.Tests.dll"
end
def copyToDir(fileArray, outputDir)
fileArray.each { |file| cp file, outputDir }
end