Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Category FAKE – F# Make

Friday, 25. February 2011


Machine.Fakes 0.1.0.0 released – Built with "FAKE – F# Make" 1.50.1.0

Filed under: F#,FAKE - F# Make,Tools — Steffen Forkmann at 14:09 Uhr

My friend Björn Rochel (@BjoernRochel) built a really cool generic model for using fakes and automocking on top of Machine.Specifications (or MSpec) called Machine.Fakes (or mfakes).

Today he released version 0.1.0.0 (get it from nuget.org) and I want to talk a bit about the build process. Björn and myself thought a tool called “Machine.Fakes” should of course be built with a tool called “FAKE – F# Make”. In order to do so I had to fix some stuff in Fake which resulted in the new Fake version 1.50.1.0.

Here are some things I fixed:

  • New task DeleteDirs allows to delete multiple directories.
  • New parameter for NuGet task which allows to specify dependencies.
  • Bundled with docu.exe compiled against .Net 4.0.
  • Fixed docu calls to run with full filenames.
  • Added targetplatform, target and log switches for ILMerge task.
  • Added Git.Information.getLastTag() which gets the last git tag by calling git describe.
  • Added Git.Information.getCurrentHash() which gets the last current sha1.
Machine.Fakes build setup

The build script for Machine.Fakes performs the following steps:

  1. It retrieves the version no. via GitHubs REST API
  2. It cleans all directories from old stuff
  3. It compiles the app and test projects
  4. It uses MSpec to test the application
  5. It merges StructureMap and StructureMap.AutoMocking into the app by using ILMerge
  6. It generates the XML documentation using the .NET 4.0 version of docu.exe
  7. It zips the app and the documentation files
  8. It builds and deploys a Nuget package with just Machine.Fakes
  9. It builds and deploys bundled Nuget packages in the following flavors:
    1. Machine.Fakes.FakeItEasy
    2. Machine.Fakes.RhinoMocks
    3. Machine.Fakes.Moq

Now you can start using this awesome project by calling:

install-package Machine.Fakes.{Flavor}

Tags: , , ,

Friday, 18. February 2011


FAKE 1.46.0.0 with MSpec and NuGet support released

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 8:49 Uhr

After a very interesting talk by Alexander Groß at the ADC2011 about MSpec I started to play around with it. I really like the concepts and especially the Selenium support.

Today I released a new “Fake – F# Make” version with initial support for machine.specifications (MSpec) and fixed some NuGet problems incl. support for automatic push to the http://nuget.org/ feed.

MSpec sample

Using MSpec in Fake is pretty straight forward and nearly the same like the NUnit or xUnit task:

NuGet sample

The following sample is taken from the NaturalSpec build and creates a NuGet package. It takes the AccessKey from the build params and pushes the new package to nuget.org. There are still some missing features but you can use them by manually editing the .nuspec file.

The corresponding .nuspec file looks like this:

Important links
Tags: , ,

Wednesday, 14. July 2010


"Fake – F# Make" 1.40.5.0 released – Bugfixes for CruiseControl.NET

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 9:15 Uhr

Today I released “FAKE – F# Make” version 1.40.5.0. This release fixes some issues with CruiseControl.NET compatibility and improves the MSBuild task.

Important links:

Changes for CruiseControl.NET

Daniel Nauck created a FAKE task for CC.Net. This task allows a much easier configuration of FAKE. Please download the latest CC.NET build if you want to use it.

Daniel also created a FAKE build project on his server which showed us some compatibility issues:

@Daniel: Thank you very much for helping me on this CruiseControl.NET stuff. I really appreciate this.

MSBuild task changes

The MSBuild task in FAKE gets a sequence of project files and compiles them in the given order. This might be slow if you have lots of dependent projects. Then MSBuild might analyze the dependencies over and over again. To fix this issue I currently see two possible solutions:

  1. Generate a temporary solution file and use this for compilation.
  2. Analyze the given projects and remove all dependent projects from the list.

FAKE 1.40.5.0 implements the second idea. If you have a better idea please contact me.

Tags: , , ,

Sunday, 11. July 2010


“Fake – F# Make” 1.33.0 released

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 15:11 Uhr

Yesterday I released “FAKE – F# Make” version 1.33.0. This release has lots of small bug fixes and a couple of new features.

Important links:

Git helpers -Fake.Git.dll

Git is a distributed revision control system with an emphasis on speed. Git was initially designed and developed by Linus Torvalds for Linux kernel development. Every Git working directory is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server.

[Wikipedia]

In the last couple of months I worked on small helper library for controlling Git. This library is now released as part of “FAKE – F# Make”. You can find the source code at http://github.com/forki/FAKE/tree/master/src/app/Fake.Git/.

Features:

  • Repository handling
    • init, clone
  • Submodules
    • init, clone, information about submodules
  • Branches
    • checkout, create, delete, merge, rebase, tag, pull, push, reset, commit, …
  • SHA1 calculation
Documentation generation with James Gregory’s docu tool

What’s a docu? A documentation generator for .Net that isn’t complicated, awkward, or difficult to use. Given an assembly and the XML that’s generated by Visual Studio, docu can produce an entire website of documentation with a single command.

[docu website]

Fake comes bundled with James Gregory’s documentations generator “docu”, which converts XML-Documentation comments into HTML files. All you need to do is downloading a template and calling the docu task inside your build script:

!+ (buildDir + "*.dll")
     |> Scan
     |> Docu (fun p ->
         {p with
             ToolPath = docuPath + "docu.exe"
             TemplatesPath = templatesSrcDir
             OutputPath = docsDir })

Since FAKE builds its own documentation with docu I started to add more (and hopefully better) XML doc comments. My plan is to describe more and more of the internal FAKE functions in the next releases. An updated HTML-document (generated via a docu task) can be found at http://www.navision-blog.de/fake/.

Side by side specification

For Test-driven development (TDD) it’s sometimes nice to have the specifications next to the implementation files since the specs are considered as documentation.

By using a tool like VSCommands it is possible to group the implementation with the specs (see also http://gist.github.com/457248).

This “side by side specification” makes TDD a lot easier but of course we don’t want to deploy the specification classes and the test data.

Side by side specification ==> After "RemoveTestFromProject"

FAKE has a new feature which automatically removes all specification files and test framework references according to a given convention:

Target "BuildApp" (fun _ –>
      !+ @"src\app\**\*.csproj"
         |> Scan
         |> Seq.map (
             RemoveTestsFromProject
                 AllNUnitReferences      // a default references convention
                 AllSpecAndTestDataFiles // a default file convention
                 )
         |> MSBuildRelease buildDir "Build"
         |> Log "AppBuild-Output: "
)

The conventions are simple functions and can be customized e.g.:

/// All Spec.cs or Spec.fs files and all files containing TestData
let AllSpecAndTestDataFiles elementName (s:string) =
     s.EndsWith "Specs.cs" ||
       s.EndsWith "Specs.fs" ||
       (elementName = "Content" && s.Contains "TestData")
Miscellaneous
  • SQL Server helpers are moved to Fake.SQL.dll
    • Additional functions for attaching and detaching databases.
  • FileHelper.CopyCached function was added
    • Copies the files from a cache folder. If the files are not cached or the original files have a different write time the cache will be refreshed.
  • EnvironmentHelper.environVarOrDefault added
    • Retrieves the environment variable or a given default.
  • Fixed Issue 3: toRelativePath calculates paths with ..\..\ if needed
  • Added a build time report to the build output.
  • XPathReplace and XMLPoke tasks added.
    • Replaces text in an XML file at the location specified by an XPath expression.
  • ILMerge task added
  • Windows Installer XML (WiX) task added
Tags: , , , , , , , ,

Wednesday, 12. May 2010


“FAKE – F# Make” 1.20.0 released

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 12:26 Uhr

Today I released a new bugfix release for “FAKE – F# Make”. We fixed some path and logging issues and as a new feature we introduced the @@ operator which allows to combine paths.

Tags: , ,

Friday, 7. May 2010


Using a MailboxProcessor to speedup “FAKE – F# MAKE”

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 11:37 Uhr

Earlier today I released “FAKE – F# Make” version 1.10.0. This new release contains a lot path issue fixes for Mono and a new architecture for logging and tracing.

A guy named Joel Mueller had an awesome idea and sent me some patches. He noticed that TraceHelper.fs writes all messages synchronously to the console and/or a XML output file, which means the actual build operations must wait on the writing of hundreds of trace messages, slowing down the actual build.

His idea was to use a MailboxProcessor to buffer up the trace messages and write them out asynchronously, so that the actual build can proceed at full speed.

type Message =

    { Text      : string

      Color     : ConsoleColor

      Newline   : bool

      Important : bool}

 

/// ….

 

let buffer = MailboxProcessor.Start (fun inbox ->

    let rec loop () =

        async {

            let! (msg:Message) = inbox.Receive()

            match traceMode with

            | Console -> logMessageToConsole msg

            | Xml     -> appendXML msg.Text

 

            return! loop ()}

 

    loop ())     

Now all internal logging and tracing functions can post their their messages to the inbox of the MailboxProcessor:

/// Logs the specified string (via message buffer)

let logMessage important newLine message =

    match traceMode with

    | Console ->

        { Text = message;

          Important = important;

          Newline = newLine;

          Color = ConsoleColor.White }

          |> buffer.Post

    | Xml     ->

        { defaultMessage with

            Text = sprintf "<message><![CDATA[%s]]></message>"

                     message }

          |> buffer.Post

This idea reduces the build time of FAKE’s self build from 3 min. to 2 min. Which is really amazing, since I didn’t have to change anything in the build script. This version is compatible to the last released version.

Please download “FAKE – F# Make” version 1.10.0 and tell me what you think.

Tags: , , ,

Tuesday, 13. April 2010


“FAKE – F# Make” and NaturalSpec released

Filed under: F#,FAKE - F# Make,Visual Studio — Steffen Forkmann at 8:06 Uhr

Yesterday Microsoft released the RTM versions of Visual Studio 2010, .NET Framework 4.0 and F# 2.0.0.0 and so it is time to announce the first official releases of “Fake – F# Make” and NaturalSpec. Both projects are now compatible with Visual Studio 2010 RC and RTM and the corresponding F# versions.

Fake – F# Make version 1.0.0

"FAKE – F# Make" is a build automation system, which is intended to provide a much better tooling support than XML-based build languages like MSBuild or NAnt. Due to its integration in F#, all benefits of the .NET Framework and functional programming can be used, including the extensive class library, powerful debuggers and integrated development environments like Visual Studio 2008, Visual Studio 2010 or SharpDevelop, which provide syntax highlighting and code completion.

Like F# itself the new build language was designed to be succinct, typed, declarative, extensible and easy to use.

NaturalSpec version 1.0.0

NaturalSpec is a UnitTest framework based on NUnit and completely written in F# – but you don’t have to learn F# to use it. The idea is that you can write your spec mostly in a natural language like in the following sample:

[<Scenario>]

let “When removing an element from a list it should not contain the element“() =

  Given [1;2;3;4;5]                 // "Arrange" test context

    |> When removing 3              // "Act"

    |> It shouldn’t contain 3       // "Assert"

    |> It should contain 4          // another assertion

    |> It should have (Length 4)    // Assertion for length

    |> It shouldn’t have Duplicates // it contains duplicates ?

    |> Verify                       // Verify scenario

If you have any questions about the projects feel free to contact me.

Tags: , , ,

Sunday, 14. February 2010


“FAKE – F# Make” 0.29 released – Ready for F# February 2010 CTP and .NET 4.0 RC

Filed under: English posts,F#,FAKE - F# Make — Steffen Forkmann at 16:56 Uhr

Last week I released version 0.29 of my build automation tool “FAKE – F# Make”. The new version comes along with a couple of changes which I will now describe.

F# February 2010 CTP and .NET 4.0 RC

“FAKE – F# Make” should be completely compatible with both, the F# February 2010 CTP and the F# version which is included in Visual Studio 2010 RC.

FAKE self build and binaries on teamcity.codebetter.com

Since “FAKE – F# Make” is a build automation tool, it was always used for it’s own build process. Now this build process could be moved to an open CI server at teamcity.codebetter.com. If you login as a guest you can download the latest “FAKE – F# Make” binaries from there.

FAKE on build servers without F#

With the new F# CTP there is no longer a need for installing F# on the build agents. In fact FAKE itself was built on build agents which don’t have a F# installation.

If you want to create such build scripts you have to do the following:

  1. Download the standalone zip file of the F# CTP
  2. Put the bin subfolder into your project tree
  3. Modify the FSIPath value in the FAKE.exe.config file to match your FSharp bin folder
    1. If you copy the contents the F# bin folder into ./tools/FSharp/ it should just work.

If you have F# projects you also need to modify your .fsproj files like this:

<PropertyGroup>
   ….
  <FscToolPath>..\..\..\tools\FSharp\</FscToolPath>
</PropertyGroup>
…
<Import Project="..\..\..\tools\FSharp\Microsoft.FSharp.Targets" />

This modifications should take care that MSBuild will use the F# compiler from your tools paths.

Generate your documentations with “docu”

“What’s a docu? A documentation generator for .Net that isn’t complicated, awkward, or difficult to use. Given an assembly and the XML that’s generated by Visual Studio, docu can produce an entire website of documentation with a single command.” [docu Homepage]

“FAKE – F# Make” 0.29 is bundled with this new documentation tool which can easily convert your xml-Documentation into some nice html pages. You can use the tool with the new Docu task like this:

Target? GenerateDocumentation <-

    fun _ ->

        Docu (fun p ->

            {p with

               ToolPath = @".\tools\FAKE\docu.exe"

               TemplatesPath = @".\tools\FAKE\templates"

               OutputPath = docDir })

            (buildDir + "MyAssembly.dll")

You will also need the docu templates, which you can download from the product homepage. I’m planning to bundle some basic templates with the next version of FAKE.

What’s next?

At the moment I’m working on ILMerge task for FAKE. I hope to release this with the next version. There are also some open issues with the Mono support but since teamcity.codebetter.com is getting a mono build agent I hope to make some progress here too.

If you have any questions or ideas for new features please contact me.

Tags: , ,

Monday, 8. February 2010


New syntactic sugar for “FAKE – F# Make” – Getting rid of magic strings

Filed under: English posts,F#,FAKE - F# Make — Steffen Forkmann at 17:58 Uhr

The new version 0.27 of “FAKE – F# Make” comes with new syntactic sugar for build targets and build dependencies. Don’t be afraid the old version is still supported – all scripts should still work with the new version.

The problem

Consider the following target definition:

let buildDir = "./build/"

 

Target "Clean" (fun _ ->

  CleanDir buildDir

)

 

Target "Default" (fun _ ->

  trace "Hello World from FAKE"

)

 

"Default" <== ["Clean"]

 

run "Default"

As you can see we are having a lot of “magic strings” for the target names and the dependency definitions. This was always a small shortcoming in FAKE, since this doesn’t allow refactoring and may result in runtime errors.

One of my goals for “FAKE – F# Make” is to remove these strings in future versions. Unfortunately this is not that easy, because it causes a lot of internal issues. In particular logging to the build server is much harder if you don’t have a target name.

The first step

As posted in a bitbucket comment by cipher we could use the “dynamic lookup operator” to remove some of the magic strings without breaking any internal code.

As a result we can rewrite the above sample as:

let buildDir = "./build/"

 

Target? Clean <-

    fun _ -> CleanDir buildDir

 

Target? Default <-

    fun _ -> trace "Hello World from FAKE"

 

For? Default <- Dependency? Clean

 

Run? Default

All magic strings suddenly disappeared. I think this syntax looks really nice, but unfortunately the strings are not really gone, since the token Default is only checked at runtime.

The idea for future versions

Since the new syntax is really just syntactic sugar I’m always interested in a better solution. Currently I’m working on a syntax using monads. The result could look like this:

let buildDir = "./build/"

 

let Clean = target { CleanDir buildDir }

let Default =

  target {

    trace "Hello World from FAKE"

    trace "Another line"

  }

 

Default <== [Clean]

Run Default

This way the magic string are really gone, but my current problem is retrieving the target name from the let-binding name. Please leave a comment if you have an idea to solve this issue.

Tags: , ,

Sunday, 18. October 2009


xUnit.net support in “FAKE – F# Make” 0.14

Filed under: F#,FAKE - F# Make — Steffen Forkmann at 18:09 Uhr

Yesterday I released “FAKE – F# Make” version 0.14 with xUnit.net support. The usage is very easy and similar to the usage of NUnit:

Target "xUnitTest" (fun () -> 

  let testAssemblies =

    !+ (testDir + @"\Test.*.dll")

      |> Scan

 

  xUnit

    (fun p ->

       {p with

           ShadowCopy = false;

           HtmlPrefix = testDir})

    testAssemblies 

)

This sample works perfectly with TeamCity and creates a html-page per test project in addition:

TeamCity output

HMTL output

If you want to publish the xUnit.net test results in CruiseControl.NET just modify the build script a little:

Target "xUnitTest" (fun () -> 

  let testAssemblies =

    !+ (testDir + @"\Test.*.dll")

      |> Scan

 

  xUnit

    (fun p ->

       {p with

           ShadowCopy = false;

           HtmlPrefix = testDir;

           XmlPrefix = testDir })

    testAssemblies 

)

Now follow the steps in the CrusieControl.NET documentation. You will need to download the xUnitSummary.xsl file and save it to your webdashboard directory. If everything works correctly you should see something like this:

CruisControl.NET output

Tags: , , , , ,