Introduction
Today (
Monday, April 26th, 2010 at 8:54 am? Approx. Transl. ) I once again tweeted that I am not a fan of build systems for projects based on XML. Yes, I understand why they are needed. Yes, they were good in their time. And yes, I still use them every day. But despite all this, I believe that there are more convenient ways to solve this problem. The most frequent answer to my tweet was the words: “Well, what’s the alternative?” One of the most important things life has taught me is that you shouldn’t complain about anything until you have nothing to offer in return. So here and now I will propose an alternative solution ...
Problem
Before we dive into the discussion, let me ask you a question ... what do the developers (
programmers, approx. Transl. ) Do best at? I'll answer for myself:
write code . In that case, why should we twist our brains by cramming multi-letters into monstrous XML files? Why can't we just write code? It is usually said that XML-based applications make it easier to make changes without recompiling, have more flexibility, and make it easier to write tools, because they are based on a format that everyone understands. But personally, I really do not think this tool is so valuable. For me, this is more likely just remnants of former hysteria about XML, which took place in the programming world a few years ago. Who has been working with such assembly systems for several years can confirm that at first they looked ridiculous and stupid.
People are so enthusiastic about glorifying XML that they forget to point out what we are losing by starting to write code in XML. For example, what about all those tools that our industry has spent so much time improving. We lose our usual editors, debuggers, libraries, and other tools only to take advantage of several minor advantages that XML has. Not every task can be described in XML. After all, XML files are simply a configuration system for code that runs in its background. In the end, we still return to writing scripts that run through the configuration in XML.
So what is the advantage of XML? Can we parse it easily? But how often do you write a parser for file collector? You simply write the XML config and feed it to NAnt. You yourself do not need to parse anything. No need to compile? Okay, the first argument is worth it, because we don’t want to build our build script before we build the project itself. Otherwise, we will have to write a build script for the build script for the build script ... etc. "Chicken, the egg of satisfaction" (
pleases the translation of the problem "Chicken <-> egg" performed by translate.google.com, approx. Transl. ). Well, this is only a limitation of some languages. What about a language that does not require compilation, which can be performed similarly to NAnt and MSBuild by passing the executable file a link to the interpreted file? You understand what I am doing. There are many languages ​​that work in this way, and several of them work on the .Net platform.
If you follow my blog, you’ve probably noticed that I’m a Ruby fan (
and I, comment transl. ). Despite the fact that I do not work professionally with him, I am in permanent admiration for the simplicity and beauty of this language. And although in the world of Ruby compilation is a rather rarely used procedure, but the need for the project's build process is as great as in our world of statically compiled languages. By the way, people, and you know that one of the common misconceptions about assembly in the .Net world is that assembly is needed only for compilation! Ufff! It felt better ... In languages ​​like C #, of course, compilation is done during assembly, but after that there is still a lot of work to be done. The collector often has to prepare and run unit tests, copy files, package a distribution kit and, possibly, ship it in a layout. A collector is a rock on which a complex process is repeated, time after time.
So, we have Ruby. More precisely, IronRuby 1.0 (at the time of writing the translation, version 1.1 is relevant). And we can use it to create a collector, which is easy and pleasant to use! So? Surely.
')
IronRuby installation overview
First, download the distribution from the official website
http://ironruby.net/ . There you can download distributions for both .Net 2.0 and .Net 4.0. The installation process should not depend on the particular choice.
Download the zip file ...
*** From the translator:
An automated installer is already available on the site that will do the necessary operations to set up the system; You can also download the source code of the interpreter and / or library for embedding into your application. Therefore, I omit the manual installation description as unnecessary.
After successful installation of the interpreter, you can run an interactive interpreter (the “ir” command) via the command line and get the opportunity to play around with Ruby.
puts "CodeThinked.com is awesome!!"
Run Rake
Rake is the tool we talked about above. It does not use XML. This is just a script written entirely in Ruby. If you write in interpreted languages, then theoretically you need not use XML to solve the assembly problem. You can
just write code . IronRuby comes with its own version of Rake, and to make sure that everything is set up correctly, you just need to type "rake" on the command line. After a few seconds, you should receive a message stating that no rake file was found. Now let's create a project and a simple rake file for it.
The first thing I do is create a directory for the project (let it be c: \ development \ RakeTest). In the specified directory, create a file Rakefile.rb. Next, open it in your favorite text editor (
for example, NotePad ++, approx. Transl. ) And place the following code into it:
require 'rake' task :default => [:congratulate_me] desc "Tells you that you are awesome" task :congratulate_me do puts "Congrats, you have rake running. Wasn't that easy?" end
After that, it remains to you in the command line to go to the directory with this file and type "rake". In response, you should get “Congrats, you have rake running. Wasn't that easy? ”
And it really is simple, isn't it? Now at your disposal a full-fledged collector. In the code above, you can see the connection of the Rake library, the default setting for launching the task “congratulate_me”, as well as the definition of the task itself along with its description. It looks like a simple nant script, but the Ezhkin cat, we wrote the code.
Now let's see what it will cost us to add additional tasks and merge them into one task, or run the assembly not from the default task, but from some other one. So, add a couple of tasks to the script:
task :congratulate_team do puts "Congrats to the team!" end task :congratulate_everyone => [:congratulate_me,:congratulate_team] do puts "Phew, that was a lot of congrats" end
You see how things got a bit more complicated. We have one task that just spits a string into the console, and there is another one that has an array following the name. This is an analogue of the NAnt functionality which allows assigning the dependence of this task on others. This allows you to run others before performing this task. Now, if we change the name of the default task to “congratulate_everyone” in Rakefile.rb, we will see that when the build script is run, the task congratulate_everyone is executed after the successful execution of the other two. And we, by the way, do not necessarily specify the default task. We can call a specific task by its name. This is done like this: “rake congratulate_team”.
We have already emulated many of the things that NAnt or MSBuild frameworks can do. This is because these frameworks simply allow us to combine several tasks in a sequence to perform a specific action. We also have a set of tasks in the script and the ability to perform them in a certain sequence. And we do not need any special configs. We can simply declare a variable in the script or read the data from where we want. In addition, we can connect to the script other ruby-files, thereby gaining access to the settings, code and tasks from different places. It seems we were able to do a lot of things that allow us to make XML, but for free.
There is only one problem left - to do the same that they can, isn’t it? After all, we ultimately want to have the opportunity to build studio solutions, run tests, reach the version control system, copy and zip files, shove files on FTP, etc. Maybe we missed something? So will we be able to catch up with MSBuild and NAnt? Good for asking.
We are friends Rake and .Net
You can ask questions: So where do I get all these tasks for the script? By chance, would I have to beat them hand to hand? Can this problem be solved already? And guess what I will answer you! Of course, this problem has already been solved for you. The cure for smut disease is called "
Albacore ". This is a small project on github. Do not rush to install it right now. I'll tell you now how to do it in two accounts.
IronRuby comes with a special tool “igem” (analogue of “gem” in MRI Ruby). This tool allows you to install additional IronRuby packages on your machine. This tool takes care of copying the package from the repository to the machine along with its dependencies. So one command "igem install albacore" in the console will be installed everything you need to work Albacore. You just need to add just one line to the rake file:
require 'albacore'
Now I am going to create a simple project of the .Net console application “RakeTestApp” and use his example to see how the assembly works through Albacore. I will begin by adding a config to the projects with the name, for example, “AutomatedRelease”, and then in each of the projects in the solution I will change the build working directory to “../build_output”. This way I can run a special msbuild task provided by Albacore at our disposal to process the .sln file and compile our solution.
First, I will create a task that will perform all the others one by one:
task :full => [:clean,:build_release,:run_tests]
Then I will create a task that will delete the working directory of the build_output, i.e. will perform a cleanup.
task :clean do FileUtils.rm_rf 'build_output' end
As you can see, we do not need any special tasks to simply delete the files. The necessary functionality is already implemented in standard Ruby libraries. Now I will create the first task inherited from the Albacore task. This task will compile the solution:
msbuild :build_release do |msb| msb.properties :configuration => :AutomatedRelease msb.targets :Build msb.solution = "RakeTestApp/RakeTestApp.sln" end
So, instead of “task” we used “msbuild” and called the task “build_release”. This task takes one parameter - the configuration. Here we set the configuration to “AutomatedRelease”, specify the desired target and the path to the descriptor of the solution that needs to be collected. We also have tests that need to be run during assembly. We can inherit the task from the NUnit Albacore task. It will look like this:
nunit :run_tests do |nunit| nunit.path_to_command = "tools/nunit/nunit-console.exe" nunit.assemblies "build_output/RakeTestAppTests.dll" end
Again, this task takes one argument, through which we can set some parameters for the task. Here we simply specify the executable file and the list of assemblies with tests (the separator is a comma).
Now all together
require 'rake' require 'albacore' task :default => [:full] task :full => [:clean,:build_release,:run_tests] task :clean do FileUtils.rm_rf 'build_output' end msbuild :build_release do |msb| msb.properties :configuration => :AutomatedRelease msb.targets :Build msb.solution = "RakeTestApp/RakeTestApp.sln" end nunit :run_tests do |nunit| nunit.path_to_command = "tools/nunit/nunit-console.exe" nunit.assemblies "build_output/RakeTestAppTests.dll" end
That's all! We created a simple build tool with IronRuby, Rake and Albacore. But this is only a small fraction of what Albacore can do. With this library, I can use ndepend, ncover, sftp, sql commands, archive directories with zip, call ssh, unzip and more. All these lego actions are performed with Albacore.
Conclusion
If you, as I feel tired of building through XML-configs, then I advise you to try IronRuby, Rake and Albacore. In the worst case scenario, it will be a small amount of time. But on the other hand, if it burns out, you will be free from the
Tatar-Mongolian Yoke of the oppression of XML-configs forever. Hope you enjoyed it!
Here is a link to
sortsy .