Tuesday, June 30, 2009

IronPython in Action

image Writing a book about IronPython presents a dilemma, do you write a book introducing Python to .NET developers, or do you write a book introducing .NET to Python developers? Striking the right balance between the two is always going to be difficult, but Michael Foord and Christian Muirhead have made a very compelling attempt. Of course I can’t speak for the Python hacker coming to the world of .NET for the first time, but for a .NET guy like me, the book is an excellent introduction to Python and how IronPython works with the rest of the .NET ecosystem.

It’s a very well written and crafted book, with an easy to read conversational style. I find many programming books quite hard work, but this one was a pleasure.

The compromise for me was a rather too high level introduction to Python itself, I would have preferred a deeper introduction to the details of Python and its standard libraries. But then I guess I could always go and buy a Python book, or check out the prodigious online resources for a more in-depth view. I’m not particularly interested in Winforms programming, so I didn’t really get much out of those parts of the book, but I guess the detail is understandable when you know that the authors day job is programming a large winforms system, Resolver One. Chapter 8 on metaprogramming and protocols was very interesting for a dynamic newbe like me, and chapter 15, on embedding the IronPython engine, also sparked off quite a few ideas.

I disagree with Craig Murphy’s comment on the back cover, “… and if you are new to programming, it’s for you too.” Michael and Christian go too deep too fast for a complete beginner. You would really need to have some background in either .NET or Python to get the most out of this book.

So am I excited about IronPython? A bit. I think I need to actually try some serious programming with it. For me its two obvious applications are as an embedded scripting language and for those tasks that don’t justify a fully compiled .NET application, such as automated deployments. I’m sure that you could be very successful building large applications with it, as indeed the authors have, but I don’t feel immediately compelled to drop C#.

I’m certainly not as excited about IronPython and the DLR as I am about functional languages such as F#. Functional programming really is a new paradigm. If you told me we would all be writing our applications with dynamic languages in ten years time, I’d be sceptical. But with functional languages, I’d be inclined to agree. Maybe we will see the emergence of a more polyglot programming ecosystem? In that world there’s certainly a place for IronPython.

Thursday, June 11, 2009

TFS Build: _PublishedWebsites for exe and dll projects

We’re using TFS on my current project. Yes, yes, I know.

It’s generally good practice to collect all the code under your team’s control in a single uber-solution as described in this Patterns and Practices PDF, Team Development with TFS Guide. If you then configure the TFS build server to build this solution, it’s default behaviour is to place the build output into a single folder, ‘Release’.

Any web application projects in your solution will also be output to a folder called _PublishedWebsites\<name of project>. This is very nice because it means that you can simply robocopy deploy the web application.

Unfortunately there’s no similar default behaviour for other project types such as WinForms, console or library. It would be very nice if we could have a _PublishedApplications\<name of project> sub folder with the output of any selected project(s). Fortunately it’s not that hard to do.

The way _PublishedWebsites works is pretty simple. If you look at the project file of your web application you’ll notice an import near the bottom:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

On my machine the MSBuildExtensionsPath property evaluates to C:\Program Files\MSBuild, if we open the Microsoft.WebApplication.targets file we can see that it’s a pretty simple MSBuild file that recognises when the build is not a desktop build, i.e. it’s a TFS build, and copies the output to:

$(OutDir)_PublishedWebsites\$(MSBuildProjectName)

I simply copied the Micrsoft.WebApplication.targets file, put it under source control with a relative path from my project files and changed _PublishedWebsites to _PublishedApplications and renamed the file CI.exe.targets. For each project that I want to output to _PublishedApplications, I simply added this import at the bottom of the project file:

<Import Project="<your relative path>\CI.exe.targets" />

You can edit CI.exe.targets (or whatever you want to call it) to do your bidding. In my case, the only change so far is to add a couple of lines to copy the App.config file:

<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)\bin" SkipUnchangedFiles="true" />

There’s a lot of stuff in Microsoft.WebApplication.targets that’s only relevant to web applications and can be stripped out for other project types, but I’ll leave that as an exercise for the reader.

There was also a discussion on StackOverflow, with some nice alternative suggestions of how you might want to do this. It’s worth checking out.