Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

Error retrieving information from external service.
Audioscrobbler/Last.fm

ClustrMap

Rake, YAML and Inherited Build Configuration

Posted in Build | Ruby at Saturday, 30 January 2010 15:03 W. Europe Standard Time

We’ve been using Rake for quite a while at work. Sometime last year I sat down and converted our ~30 KB NAnt build scripts to Rake, a light-weight Ruby build framework with low friction and no XML. Since then I have written a bunch of Rake tasks to support our builds (we use TeamCity).

I started a bit out of the blue, because frameworks like Albacore didn’t exist back then and other .NET-specific task collections didn’t fit our needs or simply were inconvenient to use.

Without prior Ruby experience it was also a great opportunity to learn Ruby and give the language and design concepts a spin. I have to admit, I like the fluent style of Ruby, it’s almost like the language tries to stay out of your way.

YAML

Soon after I started building the first Rake script I needed to configure the build for different environments. Like: in production, we have to use another database server. You want to externalize such information into a configuration file. Having database connection strings hard coded in your application’s App.config will make tailoring the application for deployment tedious and error-prone. I’ve been there, and I don’t recommend it!

I came across YAML which is an intuitive notation for configuration files (amongst others):

development:
  database:
    server: (local)
    name: Indigo

qa:
  database:
    server: DB
    name: Indigo_QA

production:
  database:
    server: DB
    name: Indigo_Production

Is that legible? I think so!

We use the configatron Ruby Gem to read such files and dereference configuration information in the build script.

configatron.configure_from_yaml 'properties.yml', :hash => 'production'

puts configatron.database.server
# => 'DB'

puts configatron.database.name
# => 'Indigo_Production'

YAML’s “Inheritance”

Another useful aspect of YAML is that it supports a simple form of inheritance by merging hashes.

qa: &customer_config
  database:
    server: DB
    name: Indigo_QA

production:
  <<: *customer_config
  database:
    name: Indigo_Production

Unfortunately this kind of inheritance has some subtleties as it wouldn’t work as you would expect. I read the snippet above like the production configuration inherits all values from qa and overwrites the database.name. Let's see:

configatron.configure_from_yaml 'properties.yml', :hash => 'production'

puts configatron.database.server.nil?
# => true
# Huh? That should be "DB".

puts configatron.database.name
# => 'Indigo_Production'

Actually, there is an article describing the problem with merging hashes in YAML files  that I found after our build broke in interesting ways after loading an incomplete configuration. The proposed solution is either to duplicate all configuration information between qa and production, or to use more anchors (&foo) and merge references (<<: *foo). I think both clutters a YAML file unnecessarily.

Custom Inheritance

After I identifying why composition doesn’t work as one would expect let’s see what we can do about it.

I went with solution based on a convention that inheritance should be defined using a default_to configuration entry.

qa:
  database:
    server: DB
    name: Indigo_QA

production:
  default_to: qa
  database:
    name: Indigo_Production

The default_to entry in the production section refers to another section that the configuration will be inherited from. You could also build inheritance chains like productionqadefault and additionally use ordinary transparent YAML hash merges.

Instead of initializing configatron from the YAML file, we’ll preprocess the deserialized YAML (basically, a Hash), evaluate the configuration inheritance chain and then pass the Hash to configatron:

yaml = Configuration.load_yaml 'properties.yml', :hash => 'production', :inherit => :default_to
configatron.configure_from_hash yaml

puts configatron.database.server.nil?
# => false

puts configatron.database.server
# => 'DB'

puts configatron.database.name
# => 'Indigo_Production'

The code for the Configuration class that accounts for evaluating the inheritance chain is up on GitHub.

Visual Studio Tip: Setting Indent Width and Tabs/Spaces Quickly Using Macros

Posted in .NET | Presentations | Visual Studio at Sunday, 24 January 2010 17:07 W. Europe Standard Time

Over the last years I’ve been contributing to several Open Source software projects, just to name the most recent:

All of the above projects follow their own style how to lay out the source code using indents. It seems like everybody has a different opinion you would have to cater for, for example:

  • Indenting is done with tabs
  • 4-space indents
  • 2-space indents

Often times these conventions are implicit, you have to read the source code to see the actual style the authors follow. It is encouraged to apply these guidelines to your patches ensure they will be accepted.

I often switch between developing for projects, so before writing a single line of code I have to hit Visual Studio’s Tools | Options | Text Editor Options dialog and change the indent settings to match the project’s conventions.

Visual Studio Text Editor Options

This has become very tedious, additionally, I often forget to adjust the indent settings before writing code. (Perhaps I forget it because it’s so annoying.)

To scratch that itch I sat down and wrote some Visual Studio macros that apply the most commonly used settings:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module Fonts
    Sub TwoSpaces()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 2
        textEditor.Item("InsertTabs").Value = False
    End Sub

    Sub FourSpaces()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 4
        textEditor.Item("InsertTabs").Value = False
    End Sub

    Sub OneTab()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 4
        textEditor.Item("InsertTabs").Value = True
    End Sub

    Public Sub NormalFonts()
        SetFontSize(10)
    End Sub

    Public Sub LargeFonts()
        SetFontSize(14)
    End Sub

    Sub SetFontSize(ByVal size As Int32)
        Dim textEditor As Properties

        textEditor = DTE.Properties("FontsAndColors", "TextEditor")
        textEditor.Item("FontSize").Value = size
    End Sub
End Module

These macros are associated with toolbar buttons:

Visual Studio Toolbar Buttons

The first two buttons are associated to the LargeFonts and NormalFonts macros that set the editor font size. I like to invoke these when doing presentations. No more fiddling with Tools | Options to ensure your audience is able to read the code on the wall.

The last three buttons should be self-explaining, they’re to quickly set tabbed, two-space and four-space indents, respectively.

Using the Microsoft Solver Foundation Add-In for Excel

Posted in .NET | Debugging | Office at Sunday, 17 January 2010 15:52 W. Europe Standard Time

After listening to the Hanselminutes episode on Microsoft Solver Foundation (MSF) I decided it’s time to give it a shot today. Solver Foundation seems to be a solution to a set of constrained problems I sometimes face:

  • Sharing costs and calculating minimal money transfers after trips with my friends, where each friend spent some money.
  • Giving out questions to attendees of our User Group “Boot Camps”: Speakers prepare ~20 questions, ranging from easy to moderate levels. We assign each attendee an easy question and one to chew a bit upon. Further, every question should be given out to two attendees, so in case someone doesn’t make it to the meeting we’re still able to cover the question.

Something I don’t remember Scott Hanselman and his guest talking about is that Solver Foundation comes with an Excel Add-In that is supposed to make creating models easy easier, no code needed. Along with the “Solver Foundation for Excel Primer” document that is installed along with the binaries I figured Excel would be a good way to start looking into Solver Foundation.

After the MSI ran, I started Excel but didn’t find the Solver Foundation tab that’s advertised in the primer. The COM Add-Ins dialog said something about that the Add-In could not be loaded. Nice! Luckily the Event Viewer was more helpful in terms of error messages where I found this beauty of an exception:

Microsoft.VisualStudio.Tools.Applications.Runtime.CannotCreateCustomizationDomainException:
Customization could not be loaded because the application domain could not be created.
---> System.IO.FileLoadException: Could not load file or assembly 'MicrosoftSolverFoundationForExcel, Version=1.0.6.4890, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

My first guess was that an old MSF assembly was referenced and I decided to go with an assembly binding redirect for excel.exe. Didn’t help. The next step was to get into the innards of VSTO deployment. What I found in the MicrosoftSolverFoundationForExcel.vsto and MicrosoftSolverFoundationForExcel.dll.manifest files wasn’t surpising: Several references to old versions of MSF. None of which were deployed by the MSI installer, so Excel trying to load such dependencies failed.

<assemblyIdentity name="MicrosoftSolverFoundationForExcel" version="1.0.8.6048"…
<assemblyIdentity name="MicrosoftSolverFoundationForExcel" version="1.0.6.4890"…

I updated both references to the match the installed version 2.0.2.8632, just to find myself faced with another error saying that the manifest’s digital signature is broken.

Now was time to contact my friend Lars Keller who is an expert in VSTO development. Lars told me that I would have to re-sign the .vsto and .manifest files to make the signature reflect my changes. The Office Development with Visual Studio blog has the full details.

  1. I had to create a certificate that can be used for code signing:
    makecert -r -pe -n "CN=Your Name" -b 01/01/2010 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.3 -ss My
  2. Export the certificate as a PFX file using certmgr.msc
  3. Create a backup copy of the MSF Excel Add-In .manifest and .vsto files
  4. Open a Visual Studio Command prompt and navigate to the manifest's location
  5. Make edits to the manifest file correcting the assembly versions of MicrosoftSolverFoundationForExcel to 2.0.2.8632
  6. Update the digital signatures for both the manifest and the VSTO file:
    mage.exe -update MicrosoftSolverFoundationForExcel.dll.manifest -CertFile <your-cert.pfx> -Password <cert-export-password>
    mage.exe -update MicrosoftSolverFoundationForExcel.vsto -appmanifest MicrosoftSolverFoundationForExcel.dll.manifest -CertFile <your-cert.pfx> -Password <cert-export-password>
  7. Restart Excel, the Solver Foundation tab should be on the ribbon

(Tested with Office 2010 beta.)

Rezept: Victoriaseebarsch auf dem Gemüsebett

Posted in Recipes (German) at Tuesday, 30 June 2009 21:32 W. Europe Daylight Time
  • das Filet eines halben Victoriaseebarschs (ungefähr 450 g)
  • 1 unbehandelte Zitrone
  • 1 rote Paprika
  • 1 1/2 kleine Zucchini
  • 5 Schalotten
  • 5 kleine aromatische Tomaten
  • ein paar Blätter Basilikum und Zitronenmelisse
  • 2 Zweige Rosmarin
  • 1 Knoblauchzehe
  • 100 g Butter
  • 3 EL Olivenöl
  • 50 ml trockener Weißwein
  • Salz, Pfeffer

Die Paprika bei großer Hitze ungefähr 10 Minuten im Ofen rösten. Nach dem Herausnehmen etwas erkalten lassen, die Schale abziehen und die Kerne entfernen. Die Paprika in Streifen schneiden.

Inwzischen die Schale der Zitrone mit einem höllisch scharfen Messer hauchdünn abschneiden. Die Zesten anschließend sehr fein hacken und zusammen mit ebenfalls kleingehackter Zitronenmelisse und 1 TL Zitronensaft unter 50 g weiche Butter rühren.

Den Fisch in 4 Stücke schneiden, mit Zitronensaft beträufeln und wieder kalt stellen.

Knoblauch, Zucchini und die Schalotten in dünne Scheiben schneiden, die Tomaten halbieren und den Strunk entfernen. Das Olivenöl in einer ofenfesten Pfanne erhitzen und anschließend Knoblauch, Zucchini, Schalotten und Tomaten zusammen mit dem Rosmarin anbraten. Mit einem Schuss Weißwein und ein paar Spritzern Zitronensaft ablöschen,  salzen und pfeffern. Grob gehacktes Basilikum und die Paprikastreifen darübergeben und beiseite stellen.

Die restliche Butter mit etwas Zitronensaft in einer zweiten Pfanne zerlassen. Den Fisch einseitig salzen und langsam halb durchbraten. Anschließend jedes Stück Fisch mit einem Blatt Zitronenmelisse belegen. Den Fisch vorsichtig auf das Gemüsebett in der anderen Pfanne umheben und die Zitronensaftbutter darübergeben. Diese Pfanne mit Aluminiumfolie dicht abschließen und bei 80°C 20 Minuten im Ofen garziehen lassen.

Mit Spaghetti al dente servieren.

Rewriting Git History: Relocating Subversion URLs

Posted in .NET | Git at Thursday, 25 June 2009 20:59 W. Europe Daylight Time

Git LogoToday we changed the URL of our Subversion server at work to a new domain. Subversion and TortoiseSVN offer a separate relocate command for that, which basically updates the local working copy metadata.

Not so for Git. Git keeps SVN metadata in two places: the commit log messages themselves which hold a git-svn-id entry for all commits that have been pushed to SVN, and in the .git/config file.

commit e82751b4872142679ba61e26fc0c57e97c698e8f
Author: agross 
Date:   Thu Jun 25 16:44:55 2009 +0000

    Adding FxCop to the code quality task

    git-svn-id: https://your.svn-server/svn/Crimson/trunk@67 8ed4a44c-bfb4-4748-a28a-fad9255c4788
[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
[svn-remote "svn"]
	url = https://your.svn-server/svn/Crimson/trunk
	fetch = :refs/remotes/git-svn

To update the SVN URL it’s required to update the Git configuration file (an easy edit) and also to rewrite the commit log messages, updating the values of git-svn-id to reflect the new SVN server URL. The latter can be achieved with the git-filter-branch command which allows you to dissect the project history in interesting ways.

Having several local Git repositories to update, I went for the scripted solution. I found this article on how to change the SVN repository URL and added some scripting goodness to it (aside from fixing the syntactic errors). It worked pretty good for my ~10 repositories.

  • You pass two arguments:
    • The old SVN URL, i.e. http://old.server
    • The new SVN URL, i.e. https://new.server
    • The old URL will be matched against git-svn-id entries with a regular expression, and the matched parts get replaced with the new URL.
  • Rewrite the commit log messages, thus updating git-svn-id
  • Create a backup copy of .git/config
  • Replace the old SVN URL in .git/config
  • Delete all metadata Git has aquired about SVN
  • Rebase against SVN, recreating the SVN metadata
#!/bin/sh

# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]  
then
  echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
  exit $E_NO_ARGS
fi  

# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`

filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all

sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config

rm -rf .git/svn
git svn rebase