diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..3dcd6c5 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,26 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: .NET + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.0.x + - name: Build + run: dotnet fsi build.fsx -- -- build + - name: Test + run: dotnet fsi build.fsx -- -- test diff --git a/.travis.yml b/.travis.yml index d534405..d42c1ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,13 @@ language: csharp mono: latest -dotnet: 2.1.300 +dotnet: 7.0.202 env: VER=$(if [[ "${TRAVIS_TAG:0:1}" == "v" ]]; then echo ${TRAVIS_TAG:1}.${TRAVIS_BUILD_NUMBER}; else echo 1.0.0.${TRAVIS_BUILD_NUMBER}; fi;) -install: - - dotnet restore build.proj script: - - export FrameworkPathOverride=$(dirname $(which mono))/../lib/mono/4.5-api/ - - dotnet fake run build.fsx -- build test -ll Diag + - dotnet fsi build.fsx -- -- build test -ll Diag deploy: - provider: script - script: dotnet fake run build.fsx -- pack push -ll Diag + script: dotnet fsi build.fsx -- -- pack push -ll Diag skip_cleanup: true on: tags: true - condition: "${TRAVIS_TAG:0:1} = v" + condition: "${TRAVIS_TAG:0:1} = v" \ No newline at end of file diff --git a/build.cmd b/build.cmd index 3986414..4d1719c 100644 --- a/build.cmd +++ b/build.cmd @@ -1,3 +1,2 @@ @echo off -dotnet restore build.proj -dotnet fake run build.fsx -- build \ No newline at end of file +dotnet fsi build.fsx -- -- build \ No newline at end of file diff --git a/build.fsx b/build.fsx index 0e27744..5e7b77a 100644 --- a/build.fsx +++ b/build.fsx @@ -1,14 +1,9 @@ -#r "paket: - nuget Xake ~> 1.1 prerelease //" - -#if !FAKE -#load ".fake/build.fsx/intellisense.fsx" -#endif +#r "nuget: Xake, 2.0.0" open Xake open Xake.Tasks -let frameworks = ["netstandard2.0"; "net46"] +let frameworks = ["netstandard2.0" (*; "net46" *)] let libtargets = [ for t in frameworks do for e in ["dll"; "xml"] @@ -33,23 +28,19 @@ let getVersion () = recipe { let makePackageName = sprintf "Xake.%s.nupkg" -let dotnet arglist = recipe { - do! shell { +let dotnet arglist = + shell { cmd "dotnet" args arglist failonerror - } |> Recipe.Ignore -} + } |> Ignore do xakeScript { filelog "build.log" Verbosity.Diag // consolelog Verbosity.Normal rules [ - "main" => recipe { - do! need ["build"] - do! need ["test"] - } + "main" <<< ["build"; "test"] "build" <== libtargets "clean" => rm {dir "out"} @@ -59,37 +50,34 @@ do xakeScript { let! where = getVar("FILTER") - |> Recipe.map (function |Some clause -> ["--filter"; sprintf "Name~\"%s\"" clause] | None -> []) + |> map (function |Some clause -> ["--filter"; $"Name~\"{clause}\""] | None -> []) // in case of travis only run tests for standard runtime, eventually will add more - let! limitFwk = getEnv("TRAVIS") |> Recipe.map (function | Some _ -> ["-f:netcoreapp2.0"] | _ -> []) - + let! limitFwk = getEnv("TRAVIS") |> map (function | Some _ -> ["-f:netcoreapp2.0"] | _ -> []) do! dotnet <| ["test"; "src/tests"; "-c"; "Release"] @ where @ limitFwk } libtargets *..> recipe { - let! allFiles - = getFiles <| fileset { - basedir "src/core" - includes "Xake.fsproj" - includes "**/*.fs" - } + let! allFiles = getFiles <| fileset { + basedir "src/core" + includes "Xake.fsproj" + includes "**/*.fs" + } do! needFiles allFiles let! version = getVersion() for framework in frameworks do - do! dotnet - [ - "build" - "src/core" - "/p:Version=" + version - "--configuration"; "Release" - "--framework"; framework - "--output"; "../../out/" + framework - "/p:DocumentationFile=Xake.xml" - ] + do! dotnet [ + "build" + "src/core" + "/p:Version=" + version + "--configuration"; "Release" + "--framework"; framework + "--output"; "./out/" + framework + "/p:DocumentationFile=Xake.xml" + ] } ] @@ -102,14 +90,13 @@ do xakeScript { "out/Xake.(ver:*).nupkg" ..> recipe { let! ver = getRuleMatch("ver") - do! dotnet - [ - "pack"; "src/core" - "-c"; "Release" - "/p:Version=" + ver - "--output"; "../../out/" - "/p:DocumentationFile=Xake.xml" - ] + do! dotnet [ + "pack"; "src/core" + "-c"; "Release" + $"/p:Version={ver}" + "--output"; "out/" + "/p:DocumentationFile=Xake.xml" + ] } // push need pack to be explicitly called in advance @@ -117,13 +104,12 @@ do xakeScript { let! version = getVersion() let! nuget_key = getEnv("NUGET_KEY") - do! dotnet - [ - "nuget"; "push" - "out" makePackageName version - "--source"; "https://www.nuget.org/api/v2/package" - "--api-key"; nuget_key |> Option.defaultValue "" - ] + do! dotnet [ + "nuget"; "push" + "out" makePackageName version + "--source"; "https://www.nuget.org/api/v2/package" + "--api-key"; nuget_key |> Option.defaultValue "" + ] } ] } diff --git a/build.fsx.lock b/build.fsx.lock deleted file mode 100644 index 5497458..0000000 --- a/build.fsx.lock +++ /dev/null @@ -1,7 +0,0 @@ -STORAGE: NONE -RESTRICTION: == netstandard2.0 -NUGET - remote: https://api.nuget.org/v3/index.json - FSharp.Core (4.3.4) - Xake (1.1.0.413-alpha) - FSharp.Core (>= 4.3.4) diff --git a/build.proj b/build.proj deleted file mode 100644 index 5483b72..0000000 --- a/build.proj +++ /dev/null @@ -1,10 +0,0 @@ - - - - netstandard2.0 - - - - - - diff --git a/build.sh b/build.sh index f19bb05..359a510 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,2 @@ #!/bin/bash -dotnet restore build.proj -dotnet fake run build.fsx -- build \ No newline at end of file +dotnet fsi build.fsx -- -- \ No newline at end of file diff --git a/docs/overview.md b/docs/overview.md index 9abff59..339cdce 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -37,7 +37,7 @@ Xake script is just an F# script with some flavors. The most simple, but structured script looks as follows: ```fsharp -#r @".tools/Xake.Core.dll" // (1) +#r "nuget: Xake, 1.1.4.427-beta" // (1) open Xake // (2) @@ -154,6 +154,7 @@ There're several forms of rules including: * `rule ( => )` - creates a phony rule (the rule that does not create a file) * `rule ( <== [targets])` - creates a phony rule which demands specified targets +* `rule ( <<< [targets])` - the same as above, but the targets are requested one by one (non-parallel excution) * `rule ( ..> )` - rule for single file or group of files matching the specified wildcards pattern. The file and an optional matching groups can be accessed via getTargetFile and getRuleMatch methods * `rule ( ..?> )` - allows to use function instead of file name or wildcards diff --git a/docs/todo.md b/docs/todo.md index 68def05..f1cb4f5 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -2,13 +2,10 @@ * change the first page to a tutorial with script and usage examples - * switch development to mono under windows * idea: xake script as a task. Override/inherit variables. How to change variable on the fly is the original question. (we have got it out of the box, need more info) - * accept filemasks in 'need' parameters (WHY I added it here?, the use case is very unclear) * detect changes in build script (internal changes), e.g. new target added that was not in .xake database * dependencies tracking mode: automatically rebuild when dependency is changed, execute triggers allowing to start/stop the processes which lock/hold artifacts * in-memory artifact (string or stream). Say in Gulp file is processed in-memory - * can the rules be abstract over artifacts ### Refactorings @@ -25,10 +22,12 @@ * `rule "Viewer" -> fun folder -> action {need [folder <\\> "bin" <\\> folder <.> "exe"]...}` * Filelist is not handy as it requires to cast all the time * FileInfo is not good for the same reason: poorly composable and does not cover Directory well -* wildcards phony actions ## Done (top is recent) + * wildcards phony actions + * support tasks in line with recipes and asyncs + * rules should accept #seq not just the list * <<< for running tasks one by one. Current one runs in parallel only. * complete copyFiles method diff --git a/global.json b/global.json new file mode 100644 index 0000000..23e9da9 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "rollForward": "major", + "version": "7.0.0" + } +} \ No newline at end of file diff --git a/readme.md b/readme.md index be9cbd1..438b360 100644 --- a/readme.md +++ b/readme.md @@ -7,9 +7,8 @@ Xake is a build utility that uses the full power of the F# programming language. The simple script looks like: ```fsharp -#r "paket: - nuget Xake ~> 1.1 prerelease - nuget Xake.Dotnet ~> 1.1 prerelease //" +#r "nuget: Xake, 2.0.0" +#r "nuget: Xake.Dotnet, 1.1.4.7-beta" open Xake open Xake.Dotnet @@ -25,7 +24,9 @@ do xakeScript { This script compiles helloworld assembly from helloworld.cs file. -To run this script: +## Getting started + +Make sure dotnet SDK 7.0+ is installed. 1. Clone the project: @@ -36,8 +37,7 @@ To run this script: ``` cd samples - dotnet restore dotnet-fake.csproj - dotnet fake run gettingstarted.fsx + dotnet fsi gettingstarted.fsx ``` ## Further reading @@ -51,12 +51,28 @@ To run this script: Once you cloned the repository you are ready to compile and test the binaries: ``` -dotnet restore build.proj -dotnet fake run build.fsx -- build test +dotnet fsi build.fsx -- -- build test ``` ... or use `build.cmd` (`build.sh`) in the root folder +## Getting started for Mono on Linux/OSX + +> This is untested and mono nowadays is poorly explored territory for me. + +Make sure mono with F# is installed and root certificates are imported: + +``` +sudo apt-get install mono-complete +sudo mozroots --import --sync +``` + +TBD + +## Documentation + +See [documentation](docs/overview.md) for more details. + ## References * [documentation](https://github.com/xakebuild/Xake/wiki) diff --git a/samples/book/intro.fsx b/samples/book/intro.fsx index 6bd4156..8c06c72 100644 --- a/samples/book/intro.fsx +++ b/samples/book/intro.fsx @@ -1,6 +1,6 @@ -#r "paket: - nuget Xake ~> 1.1 prerelease - nuget Xake.Dotnet ~> 1.1 prerelease //" // (1) +#r "nuget: Xake, 1.1.4.427-beta" +#r "nuget: Xake.Dotnet, 1.1.4.7-beta" (1) + open Xake // (2) open Xake.Dotnet // (2.1) diff --git a/samples/catch_errors.fsx b/samples/catch_errors.fsx index 22f83ab..4f266a3 100644 --- a/samples/catch_errors.fsx +++ b/samples/catch_errors.fsx @@ -1,5 +1,4 @@ -#r "paket: nuget Xake ~> 1.1 prerelease //" - +#r "nuget: Xake, 2.0.0" open Xake do xakeScript { diff --git a/samples/features.fsx b/samples/features.fsx index b474bde..289249f 100644 --- a/samples/features.fsx +++ b/samples/features.fsx @@ -1,10 +1,5 @@ -#r "paket: - nuget Xake ~> 1.1 prerelease - nuget Xake.Dotnet ~> 1.1 prerelease //" - -#if !FAKE -#load ".fake/features.fsx/intellisense.fsx" -#endif +#r "nuget: Xake, 2.0.0" +#r "nuget: Xake.Dotnet, 1.1.4.7-beta" // This a sample Xake script to show off some features. // diff --git a/samples/gettingstarted.fsx b/samples/gettingstarted.fsx index 4a25411..6ac0bd5 100644 --- a/samples/gettingstarted.fsx +++ b/samples/gettingstarted.fsx @@ -1,6 +1,5 @@ -#r "paket: - nuget Xake ~> 1.1 prerelease - nuget Xake.Dotnet ~> 1.1 prerelease //" +#r "nuget: Xake, 2.0.0" +#r "nuget: Xake.Dotnet, 1.1.4.7-beta" open Xake open Xake.Dotnet diff --git a/samples/rmdir.fsx b/samples/rmdir.fsx index 938760c..439d819 100644 --- a/samples/rmdir.fsx +++ b/samples/rmdir.fsx @@ -1,4 +1,4 @@ -#r "paket: nuget Xake ~> 1.1 prerelease //" +#r "nuget: Xake, 1.1.4.427-beta" open Xake open Xake.Tasks diff --git a/src/core/Database.fs b/src/core/Database.fs index d36dca3..1e45c6b 100644 --- a/src/core/Database.fs +++ b/src/core/Database.fs @@ -59,7 +59,7 @@ module Storage = | FileDep _ -> 1 | EnvVar _ -> 2 | Var _ -> 3 - | AlwaysRerun _ -> 4 + | AlwaysRerun -> 4 | GetFiles _ -> 5) [| wrap (ArtifactDep, fun (ArtifactDep f | OtherwiseFail f) -> f) target wrap (FileDep, fun (FileDep(f, ts) | OtherwiseFail (f, ts)) -> (f, ts)) (pair file date) diff --git a/src/core/DependencyAnalysis.fs b/src/core/DependencyAnalysis.fs index 2f747b6..efc152e 100644 --- a/src/core/DependencyAnalysis.fs +++ b/src/core/DependencyAnalysis.fs @@ -25,7 +25,8 @@ let getExecTime ctx target = |> Option.fold (fun _ r -> r.Steps |> List.sumBy (fun s -> s.OwnTime)) 0 /// Gets single dependency state and reason of a change. -let getDepState getVar getFileList (getChangedDeps: Target -> ChangeReason list) = function +let getDepState getVar getFileList (getChangedDeps: Target -> ChangeReason list) x = + match x with | FileDep (a:File, wrtime) when not((File.exists a) && abs((File.getLastWriteTime a - wrtime).TotalMilliseconds) < TimeCompareToleranceMs) -> let dbgInfo = File.exists a |> function | false -> "file does not exists" diff --git a/src/core/ExecCore.fs b/src/core/ExecCore.fs index 2e50fe8..f83132d 100644 --- a/src/core/ExecCore.fs +++ b/src/core/ExecCore.fs @@ -5,11 +5,6 @@ module internal ExecCore = open System.Text.RegularExpressions open DependencyAnalysis - /// Default options - [] - let XakeOptions = ExecOptions.Default - - open WorkerPool open Storage /// Writes the message with formatting to a log @@ -74,9 +69,12 @@ module internal ExecCore = let targets = patterns |> List.map (generateName >> () projectRoot >> File.make >> FileTarget) rule, groups, targets) - |PhonyRule (name,_), PhonyAction phony when phony = name -> - // writeLog Verbose "Found phony pattern '%s'" name - Some (rule, [], [target]) + |PhonyRule (pattern,_), PhonyAction phony -> + // printfn $"Phony rule {phony}, pattern {pattern}" + // Some (rule, [], [target]) + phony + |> Path.matchGroups pattern "" + |> Option.map (fun groups -> rule,groups,[target]) | _ -> None @@ -187,7 +185,10 @@ module internal ExecCore = /// phony actions are detected by their name so if there's "clean" phony and file "clean" in `need` list if will choose first let makeTarget ctx name = let (Rules rules) = ctx.Rules - let isPhonyRule nm = function |PhonyRule (n,_) when n = nm -> true | _ -> false + let isPhonyRule nm = function + |PhonyRule (pattern,_) -> + nm |> Path.matchGroups pattern "" |> Option.isSome + | _ -> false in match rules |> List.exists (isPhonyRule name) with | true -> PhonyAction name @@ -206,21 +207,21 @@ module internal ExecCore = let rec showDepStatus ii reasons = reasons |> function - | ChangeReason.Other reason -> + | Other reason -> print "%sReason: %s" (indent ii) reason - | ChangeReason.Depends t -> + | Depends t -> print "%sDepends '%s' - changed target" (indent ii) t.ShortName - | ChangeReason.DependsMissingTarget t -> + | DependsMissingTarget t -> print "%sDepends on '%s' - missing target" (indent ii) t.ShortName - | ChangeReason.FilesChanged (file:: rest) -> + | FilesChanged (file:: rest) -> print "%sFile is changed '%s' %s" (indent ii) file (if List.isEmpty rest then "" else sprintf " and %d more file(s)" <| List.length rest) | reasons -> do print "%sSome reason %A" (indent ii) reasons () let rec displayNestedDeps ii = function - | ChangeReason.DependsMissingTarget t - | ChangeReason.Depends t -> + | DependsMissingTarget t + | Depends t -> showTargetStatus ii t | _ -> () and showTargetStatus ii target = @@ -276,10 +277,10 @@ module internal ExecCore = getDeps >> function | [] -> false, "" - | ChangeReason.Other reason::_ -> true, reason - | ChangeReason.Depends t ::_ -> true, "Depends on target " + t.ShortName - | ChangeReason.DependsMissingTarget t ::_ -> true, sprintf "Depends on target %s (missing)" t.ShortName - | ChangeReason.FilesChanged (file::_) ::_ -> true, "File(s) changed " + file + | Other reason::_ -> true, reason + | Depends t ::_ -> true, "Depends on target " + t.ShortName + | DependsMissingTarget t ::_ -> true, sprintf "Depends on target %s (missing)" t.ShortName + | FilesChanged (file::_) ::_ -> true, "File(s) changed " + file | reasons -> true, sprintf "Some reason %A" reasons >> function @@ -310,17 +311,25 @@ module internal ExecCore = /// Executes the build script let runScript options rules = let logger = CombineLogger (ConsoleLogger options.ConLogLevel) options.CustomLogger - let logger = match options.FileLog, options.FileLogLevel with | null,_ | "",_ - | _,Verbosity.Silent -> logger + | _, Silent -> logger | logFileName,level -> CombineLogger logger (FileLogger logFileName level) let (throttler, pool) = WorkerPool.create logger options.Threads - let db = Storage.openDb (options.ProjectRoot options.DbFileName) logger + let finalize () = + db.PostAndReply Storage.CloseWait + FlushLogs() + + System.Console.CancelKeyPress + |> Event.add (fun _ -> + logger.Log Error "Build interrupted by user" + finalize() + exit 1) + let ctx = { Ordinal = 0 TaskPool = pool; Throttler = throttler @@ -363,8 +372,7 @@ module internal ExecCore = ctx.Logger.Log Message "\n\n\tBuild failed after running for %A\n" (System.DateTime.Now - start) exit 2 finally - db.PostAndReply Storage.CloseWait - Logging.FlushLogs() + finalize() /// "need" implementation let need targets = diff --git a/src/core/ExecTypes.fs b/src/core/ExecTypes.fs index 5f87557..7f4c0ae 100644 --- a/src/core/ExecTypes.fs +++ b/src/core/ExecTypes.fs @@ -44,30 +44,28 @@ type ExecOptions = { /// Dump dependencies only Progress: bool -} with -static member Default = - { - ProjectRoot = System.IO.Directory.GetCurrentDirectory() - Threads = System.Environment.ProcessorCount - ConLogLevel = Normal - - CustomLogger = CustomLogger (fun _ -> false) ignore - FileLog = "build.log" - FileLogLevel = Chatty - Targets = [] - FailOnError = false - Vars = List.Empty - IgnoreCommandLine = false - Nologo = false - DbFileName = ".xake" - DryRun = false - DumpDeps = false - Progress = true +} with static member Default = { + ProjectRoot = System.IO.Directory.GetCurrentDirectory() + Threads = System.Environment.ProcessorCount + ConLogLevel = Normal + + CustomLogger = CustomLogger (fun _ -> false) ignore + FileLog = "build.log" + FileLogLevel = Chatty + Targets = [] + FailOnError = false + Vars = List.Empty + IgnoreCommandLine = false + Nologo = false + DbFileName = ".xake" + DryRun = false + DumpDeps = false + Progress = true } end -type internal ExecStatus = | Succeed | Skipped | JustFile -type private TaskPool = Agent> +type ExecStatus = | Succeed | Skipped | JustFile +type TaskPool = Agent> /// Script execution context type ExecContext = { diff --git a/src/core/Fileset.fs b/src/core/Fileset.fs index 9d481ba..d6ae187 100644 --- a/src/core/Fileset.fs +++ b/src/core/Fileset.fs @@ -249,7 +249,7 @@ module Fileset = Fileset (opts, pts @ [includes |> Path.parse |> Includes]) /// Adds excludes pattern to a fileset. - static member (--) (Fileset (opts,pts), excludes) = + static member (--) (Fileset (opts,pts), excludes): Fileset = Fileset (opts, pts @ [excludes |> Path.parse |> Excludes]) end diff --git a/src/core/Logging.fs b/src/core/Logging.fs index a8124df..61fa35b 100644 --- a/src/core/Logging.fs +++ b/src/core/Logging.fs @@ -124,9 +124,10 @@ module private ConsoleSink = let rec loop (progressMessage) = let wipeProgressMessage () = let len = progressMessage |> Option.fold (fun _ -> String.length) 0 - // printfn "cleft: %A len: %d" Console.CursorLeft len - match len - Console.CursorLeft with - | e when e > 0 -> System.Console.Write (String.replicate e " ") + Console.Out.Flush() + let cursorLeft = Console.CursorLeft + len - cursorLeft |> function + | e when e > 0 -> Console.Write (String.replicate e " ") | _ -> () let renderProgress = function | Some (outputString: string) -> @@ -141,9 +142,9 @@ module private ConsoleSink = Console.Write (sprintf "\r[%s] " level) Console.ForegroundColor <- textColor - System.Console.Write txt + Console.Write txt wipeProgressMessage() - System.Console.WriteLine() + Console.WriteLine() async { let! msg = mbox.Receive() @@ -152,16 +153,9 @@ module private ConsoleSink = match level |> levelToColor with | Some colors -> // in case of CRLF in the string make sure we washed out the progress message - let rec writeLines = function - | [] -> fun _ -> () - | (txt: string)::tail -> - function - | true -> - renderLineWithInfo colors (LevelToString level) txt - do writeLines tail false - | false -> System.Console.WriteLine txt; do writeLines tail false - - writeLines (text.Split('\n') |> List.ofArray) true + text.Split('\n') |> Seq.iteri (function + | 0 -> renderLineWithInfo colors (LevelToString level) + | _ -> System.Console.WriteLine) renderProgress progressMessage | _ -> () @@ -181,7 +175,8 @@ module private ConsoleSink = | Flush ch -> wipeProgressMessage() - Console.Write "\r" + do! Console.Out.FlushAsync() |> Async.AwaitTask + ch.Reply () return! loop None @@ -206,9 +201,7 @@ let private ConsoleLoggerBase (write: Level -> string -> unit) maxLevel = /// Simplistic console logger. let DumbConsoleLogger = - ConsoleLoggerBase ( - fun level -> (LevelToString level) |> sprintf "[%s] %s" >> System.Console.WriteLine - ) + ConsoleLoggerBase (fun l -> l |> LevelToString |> sprintf "[%s] %s" >> System.Console.WriteLine) /// Console logger with colors highlighting let ConsoleLogger = @@ -217,7 +210,7 @@ let ConsoleLogger = /// Ensures all logs finished pending output. let FlushLogs () = try - ConsoleSink.po.PostAndReply (ConsoleSink.Flush, 200) |> ignore + ConsoleSink.po.PostAndTryAsyncReply (ConsoleSink.Flush, 200) |> Async.RunSynchronously |> ignore with _ -> () /// Draws a progress bar to console log. @@ -233,9 +226,7 @@ let WriteConsoleProgress = let CombineLogger (log1 : ILogger) (log2 : ILogger) = { new ILogger with member __.Log level (fmt : Printf.StringFormat<'a, unit>) : 'a = - let write s = - log1.Log level "%s" s - log2.Log level "%s" s + let write s = log1.Log level "%s" s; log2.Log level "%s" s Printf.kprintf write fmt } /// @@ -254,11 +245,11 @@ let PrefixLogger (prefix:string) (log : ILogger) = /// /// let parseVerbosity = function - | "Silent" -> Verbosity.Silent - | "Quiet" -> Verbosity.Quiet - | "Normal" -> Verbosity.Normal - | "Loud" -> Verbosity.Loud - | "Chatty" -> Verbosity.Chatty - | "Diag" -> Verbosity.Diag + | "Silent" -> Silent + | "Quiet" -> Quiet + | "Normal" -> Normal + | "Loud" -> Loud + | "Chatty" -> Chatty + | "Diag" -> Diag | s -> failwithf "invalid verbosity: %s. Expected one of %s" s "Silent | Quiet | Normal | Loud | Chatty | Diag" diff --git a/src/core/Pickler.fs b/src/core/Pickler.fs index c6560d8..701c22a 100644 --- a/src/core/Pickler.fs +++ b/src/core/Pickler.fs @@ -84,7 +84,7 @@ module Pickler = /// let option pu = alt - (function | None _ -> 0 | Some _ -> 1) + (function | None -> 0 | Some _ -> 1) [| wrap ((fun () -> None), ignore) unit wrap (Some, Option.get) pu diff --git a/src/core/Program.fs b/src/core/Program.fs index 887d0bc..a9ebf89 100644 --- a/src/core/Program.fs +++ b/src/core/Program.fs @@ -21,7 +21,7 @@ module internal ParseArgs = begin | "-h" | "/h" | "--help" | "/help" | "/?" | "-?" -> printf """ Usage: - fsi