Home
Insert
Update snippet 'Run MsBuild 2015'
Title
Description
runs msbuild using 2015 msbuild and fails if there is an error. All errors reported came across on the output stream instead of the error stream.
Source code
open System open System.Diagnostics open System.IO let delimit s (items:string seq) = String.Join(s,items) let runProc filename args startDir = let timer = Stopwatch.StartNew() let procStartInfo = ProcessStartInfo( RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, FileName = filename, Arguments = args ) match startDir with | Some d -> procStartInfo.WorkingDirectory <- d | _ -> () let outputs = System.Collections.Generic.List<string>() let errors = System.Collections.Generic.List<string>() let outputHandler f (_sender:obj) (args:DataReceivedEventArgs) = f args.Data let p = new Process(StartInfo = procStartInfo) p.OutputDataReceived.AddHandler(DataReceivedEventHandler (outputHandler outputs.Add)) p.ErrorDataReceived.AddHandler(DataReceivedEventHandler (outputHandler errors.Add)) let started = try p.Start() with | ex -> ex.Data.Add("filename", filename) reraise() if not started then failwithf "Failed to start process %s" filename printfn "Started %s with pid %i" p.ProcessName p.Id p.BeginOutputReadLine() p.BeginErrorReadLine() p.WaitForExit() timer.Stop() printfn "Finished %s after %A milliseconds" filename timer.ElapsedMilliseconds let cleanOut l = l |> Seq.filter (fun o -> String.IsNullOrEmpty o |> not) cleanOut outputs,cleanOut errors let msbuild targetProject buildArgs = let targetFolder = Path.GetDirectoryName targetProject let msbuildPath = @"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" let errorCount outputs errors = let regex = System.Text.RegularExpressions.Regex(@"^\s*([1-9][0-9]*)\s+Error\(s\)$|Build FAILED.") [ outputs;errors] |> Seq.concat |> Seq.map regex.Match |> Seq.tryFind(fun m -> m.Success) let args = targetProject::buildArgs |> delimit " " let output,errors = runProc msbuildPath args (Some targetFolder) match errorCount output errors with | Some errorMatch -> //printfn "%A" output //printfn "%A" errors let regex = System.Text.RegularExpressions.Regex("Build error", Text.RegularExpressions.RegexOptions.IgnoreCase) printfn "%A" (output |> Seq.filter regex.IsMatch |> List.ofSeq) let errorText = let text = errorMatch.Groups.[1].Value if String.IsNullOrWhiteSpace(text) then errorMatch.Groups.[0].Value else text failwithf "ErrorsFound : %s" errorText | None -> () if output |> Seq.exists (fun c -> c = "Build FAILED.") then failwithf "Build failed" output,errors
Tags
process
msbuild
process
msbuild
Author
Link
Reference NuGet packages
If your snippet has external dependencies, enter the names of NuGet packages to reference, separated by a comma (
#r
directives are not required).
Update