Monday, January 26, 2015

Generating standalone binaries for Mono project (like a boss)

I see a lot of distrust in msbuild and especially xbuild scripts. Many developers prefer writing bash or worse, batch scripts which build the project. But why to add complexity if you have necessary tools at your disposal?

If you're writing some app that you want to distribute, you really need a standalone binary. For Mono, it can be easily generated by mkbundle utility. You really want to automate this stuff. So, what is the easiest way to do it? Make a new step in build scripts.

In xbuild scripts, just as in msbuild, there is an Exec task, which allows you to run an arbitrary application. So, in Mono it would look something like this:
  <Target Name='AfterBuild'>
  <Exec Command="mkbundle bin/$(Configuration)/PowerCertmgr.exe -o power-certmgr" 
        Condition="'$(OS)' == 'Unix'" />
  </Target>

We want to run this script only if OS is Unix-like. Why? Well, I'm working in Linux and I don't really care about Windows :) One should check if it runs on non-Unix systems, and in case of problems provide alternative implementations.

Even though xbuild scripts are underdeveloped compared to msbuild scripts, they can easily handle work like that. I really hope this approach will be more popular.

Saturday, January 17, 2015

Rewriting Mono's certmgr

While trying to run ASP.NET 5 on Mono, I was using certmgr from Mono security tools to import some certificates for NuGet. I was dissatisfied with this tool due to the following reasons:

  • I was unable to list existing certificates, as you need to supply the store name. You have to specify one of the 5 possible store names (My, AddressBook, CA, Trust, Disallowed). Do I need to say there's NO MENTION of these names in certmgr documentation? I was unable to find that list somewhere in the web either. The most reliable way is to get it from the code.
  • It crashes almost every time when incorrect parameters are supplied. Not that it's fatal; it's just aesthetically unpleasant for me to see something like
    Unhandled Exception:
    System.IndexOutOfRangeException: Array index is out of range.
      at Mono.Tools.CertificateManager.Main (System.String[] args) [0x00000] in :0 
    [ERROR] FATAL UNHANDLED EXCEPTION: System.IndexOutOfRangeException: Array index is out of range.
      at Mono.Tools.CertificateManager.Main (System.String[] args) [0x00000] in :0
    
    
  • Code is rather sloppy, with suboptimal variable naming, unused variables, etc. My favorite part is extremely strict certificate validation:
    static bool CertificateValidation (SSCX.X509Certificate certificate, int[] certificateErrors)
    {
        // the main reason to download it is that it's not trusted
        return true;
        // OTOH we ask user confirmation before adding certificates into the stores
    }
    
I think that's enough reasons to fork it. Why not send a pull request? First of all, I think it's wrong to bundle the tool with Mono. It's an independent tool, it should be possible to update it without touching the Mono core.

So my plan is as follows:

  • Refactor certmgr to run standalone (done)
  • Set up continuous integration (done)
  • Fix existing bugs (in progress)
  • Write unit/integration tests
  • Make tool more user-friendly (e.g. display certificates from all stores by default?)
  • Implement some new features?

That's where could use some input from other people. If you have some ideas or want to contribute code - please open issues/requests on project's page on GitHub.

Wednesday, January 7, 2015

Challenge

At the start of the new year, I decided to take a challenge of building some relatively complex open-source project - a forum engine. My primary goal is to expand my knowledge, but I really hope that the said engine will be useful to somebody.
I don't anticipate any big interest, as there's nothing really sexy about this project - no node.js, Ruby or whatever is considered sexy now. There is also no high demand for forum engines, as far as I see. However I want this project to embody things that matter to me, like a good coding standard (I like the one of .NET Core), simple self-documented code and really simple architecture. As of now, project is in 'early alpha', I'm still developing the core and shaping the architecture of the project. But, if you happen to have some nice idea, or maybe you've spotted a bug in the code - you're really welcome to contribute by creating issue or pull request.