Ralph Willgoss
Ralph Willgoss

Reputation: 12163

Fake Glob operator (!!) not expanding directory paths

I have a situation where in a Fake script I am trying to grab all the unit test dll's from a path using the Glob (!!) operator.

The issue is that on my machine the glob expansion doesn't work, on other similar Windows 10 machines at work, its fine and finds the dlls.

Below is an example:

let path = [function to generate path]
trace path [would look something like "c:\git\project\src\**\*UnitTest*"]
!! path.ToLower()
|> Seq.iter (fun file -> trace file ) [this would not output anything]

I've tried numerous things:

The versions of software I am using are:

No errors or exceptions are thrown.
Whats the best way to trouble shoot if its an F# or a Fake issue?
How could I work out what version of F# Fake is using?

Update
I've reinstalled F# 4.1 and performed a test using fsi.exe with the following command:

Microsoft (R) F# Interactive version 4.1
<snip>
#r @"packages/FAKE/tools/FakeLib.dll";;
open Fake;;
!! "**\*UnitTests.dll" |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll

!! "**\*UnitTests.dll".ToLower() |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll

All the test dlls were found, both with and without the call to ToLower().

When I remove the ToLower() from the script, it now works on my machine.

However, on other peoples machines removing ToLower() on the path causes them not to find any files.

So, is Fake using a different version of the fsi.exe?
I've opened a github issue to see if that sheds any light on it: https://github.com/fsharp/FAKE/issues/1772

Upvotes: 2

Views: 610

Answers (2)

Ralph Willgoss
Ralph Willgoss

Reputation: 12163

Using the following script, I was able to reproduce the issue and work out that the issue was due to how Windows 10 handles the original casing of the company name, in the path.

I confirmed this by changing company name to ** in the file path expression, the operator worked and found all the dlls.

I remember changing the capitalisation of the company name, from all caps to lower case. If I remove the ToLower() on the path, then the script works fine and finds all the dlls.

This hidden issue, combined with how FAKE does a case sensitive search, doesn't help either.

Powershell

packages\FAKE\tools\FAKE.exe glob.test.fsx

glob.test.fsx

#r @"packages/FAKE/tools/FakeLib.dll"
open Fake

let thePath = """C:\git\company/projectname/**/bin/Debug/*UnitTests.dll"""

sprintf "the path is %s" thePath |> trace 

!! thePath.ToLower() |> Seq.iter (fun f -> trace f)

I had a look at the process executing in ProcMon and did not see the original casing of the directory. The NTFS file system is still see this directory as its original casing (see comments below).

I re-image my machine every few months, so this will disappear soon but it was good to understand what was going on.

Thanks to all those that helped narrow the issue down.

Upvotes: 0

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131502

In F# as in all .NET languages, the backslash is used for escape sequences in strings.

You need to escape the backslash or use a verbatim string, eg :

let path = "c:\\git\\project\\src\\**\\*UnitTest*"

or

let path = @"c:\git\project\src\**\*UnitTest*"

Fake can work with forward slashes as well :

let path = "c:/git/project/src/**/*UnitTest*"

You'll have to use forward slashes anyway if you want your build script to run on Linux.

An even better option is to use relative paths. Your build script most likely is stored in your project folder. You can write

let path = "src/**/*UnitTest*"

Upvotes: 2

Related Questions