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.)