-
-
Save vasily-kirichenko/7321686 to your computer and use it in GitHub Desktop.
| type FileSetBuilder() = | |
| member x.Delay f = f | |
| member x.Run f = f() |> Scan | |
| member x.Yield (()) = { Include "" with Includes = [] } | |
| [<CustomOperation ("take", MaintainsVariableSpace = true)>] | |
| member x.Take (fs, pattern: string) = fs ++ pattern | |
| [<CustomOperation ("notTake", MaintainsVariableSpace = true)>] | |
| member x.NotTake (fs: FileIncludes, pattern: string) = fs -- pattern | |
| let files = FileSetBuilder() | |
| Target "Build" { | |
| files { | |
| take "**\bin\**\*Tests.dll" | |
| take "**\bin2\**\*Tests.dll" | |
| take "**\binaries\**\*" | |
| notTake "**\bin2\Special*\*" | |
| take "**\binaries2\**\*" | |
| } | |
| |> MSBuildDebug @".\out1" "Build" | |
| |> Log "AppBuild-Output: " | |
| } | |
| // old syntax | |
| Target "Build" <| fun _ -> | |
| !+ "**\bin\**\*Tests.dll" | |
| ++ "**\bin2\**\*Tests.dll" | |
| ++ "**\binaries\**\*" | |
| -- "**\bin2\Special*\*" | |
| ++ "**\binaries2\**\*" | |
| |> Scan | |
| |> MSBuildDebug @".\out1" "Build" | |
| |> Log "AppBuild-Output: " |
/// Include files
let Include x =
{ BaseDirectories = [DefaultBaseDir];
Includes = [x];
Excludes = []}
/// Includes a single pattern and scans the files
let inline (!!) x = Include x
It's already there....
How about we add this:
let Exclude y x = x -- y
let AndInclude y x = x ++ y
the you could write:
Include"**\bin\**\*Tests.dll"
|> AndInclude "**\bin2\**\*Tests.dll"
|> AndInclude "**\binaries\**\*"
|> AndInclude "**\binaries2\**\*
|> Exlude "**\bin2\Special*\*"
|> MSBuild ...
I think for normal F# code all the approaches are perfectly OK. !!, ++ and -- are even then best (I like operators :) )
But I remember how much confused was a tester from my team as he saw them for the first time.
So, I think we should not use cryptic unusual symbols at all. Your Include...AndInclude...Exclude are better but the piping operator is basically as weird as !! ++ -- for a non-F#-er.
However, if a build script is created and maintained by a F# dev(s) it's even more preferable to use the operators. But for the rest of the world we should offer a more 'normal' alternative.
So, I suggest to support all three ways: operators, function composition via |> and >> and CEs (I even wrote one for the NUnit task and it looks ok ;)
On could also add methods to the FileSet object and do it C# fluent style.
Like
Include("**\bin\**\*Tests.dll")
.And("**\bin2\**\*Tests.dll")
.And("**\binaries\**\*")
.And("**\binaries2\**\*)
.ButNot("**\bin2\Special*\*")
I for one would have the least surprise when obvious names are used with the builtin function composition options (like pipe operator). I feel quite safe with the scan/include/exclude syntax. It's nice to have a more 'obvious' syntax for the beginner as well as a more 'terse' syntax for the advanced users.
I'm rather sceptical about C# fluent style these days. However, as an option among others it could be ideal for using by C# devs.
I think the ++ and -- are ok for operators, as it's easy to associate them to include and exclude, but I really don't like !!, as it's very non-obvious. Any of the non-operator alternatives is fine