Skip to content

Instantly share code, notes, and snippets.

@vasily-kirichenko
Last active December 27, 2015 11:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasily-kirichenko/7321686 to your computer and use it in GitHub Desktop.
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: "
@forki
Copy link

forki commented Nov 5, 2013

Actually I don't think it's that big problem. Usually we only have !! and one pattern sometimes one additional ++ or --

@ovatsus
Copy link

ovatsus commented Nov 5, 2013

Love that CE syntax, much nicer than the operators which I never remember which is what.

@forki
Copy link

forki commented Nov 5, 2013

How about something in the direction of:

Scan [
  "**\bin\**\*Tests.dll"
  "**\bin2\**\*Tests.dll"
  "**\binaries\**\*"
  "**\binaries2\**\*]
|> Exlude  "**\bin2\Special*\*"
|> MSBuild ...

@forki
Copy link

forki commented Nov 5, 2013

or even

Scan "**\bin\**\*Tests.dll"
|> Include "**\bin2\**\*Tests.dll"
|> Include "**\binaries\**\*"
|> Include "**\binaries2\**\*
|> Exlude  "**\bin2\Special*\*"
|> MSBuild ... 

@forki
Copy link

forki commented Nov 5, 2013

BTW: Did you see fsprojects/FAKE@5def167

The original "Scan" is not needed anymore. Filesets implement IEnumerable.
Therefor !! is the same as !+

@ovatsus
Copy link

ovatsus commented Nov 5, 2013

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

@forki
Copy link

forki commented Nov 5, 2013

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

@forki
Copy link

forki commented Nov 5, 2013

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

@vasily-kirichenko
Copy link
Author

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

@forki
Copy link

forki commented Nov 5, 2013

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*\*")

@ilkerde
Copy link

ilkerde commented Nov 5, 2013

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.

@vasily-kirichenko
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment