3 people like it.
Like the snippet!
Compute CC.Net build statistics
Written against CruiseControl.NET v1.5. Queries a CruiseControl.NET server for a project list and then computes min, max, average, and standard deviation of the build durations based on the statistics.csv CC.NET maintains.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
|
open System
open System.Collections.Generic
open System.IO
open ThoughtWorks.CruiseControl.Remote
type Result = { Name : string; Count : Int32; Average : float; StdDev : float; Min : float; Max : float; }
member x.Print() = printfn "%s,%d,%.2f,%.2f,%.2f,%.6f" x.Name x.Count x.Min x.Max x.Average x.StdDev
let ReadLines (fileName : string) = seq {
use reader = new StreamReader(fileName)
while not reader.EndOfStream do yield reader.ReadLine() }
let ComputeResults name values =
let count = values |> Seq.length
let average = values |> Seq.average
let variance = (values |> Seq.map (fun n -> (n - average) * (n - average)) |> Seq.sum) / float count
let stdDev = Math.Sqrt(variance)
{ Name = name; Count = count; Average = average; StdDev = stdDev; Min = Seq.min values; Max = Seq.max values }
let GetStatistics serverName projectName =
let fileName = String.Format(@"\\{0}\ccnet\{1}\ArtifactDirectory\statistics.csv", serverName, projectName)
ReadLines(fileName)
|> Seq.map (fun s -> s.Split(','))
|> Seq.map (fun v -> TimeSpan.TryParse(v.[1]))
|> Seq.filter (fun (r, span) -> r && span <> TimeSpan.Zero)
|> Seq.map (fun (r, span) -> span.TotalMinutes)
|> ComputeResults projectName
let client = new CruiseServerHttpClient("http://cruisecontrol")
printfn "Project,Count,Minimum,Maximum,Average,StdDev"
client.GetProjectStatus()
|> Seq.map (fun (p : ProjectStatus) -> GetStatistics p.ServerName p.Name)
|> Seq.sortBy (fun result -> result.Name)
|> Seq.iter (fun result -> result.Print())
|
namespace System
namespace System.Collections
namespace System.Collections.Generic
namespace System.IO
type Result =
{Name: string;
Count: Int32;
Average: float;
StdDev: float;
Min: float;
Max: float;}
member Print : unit -> unit
Full name: Script.Result
Result.Name: string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
Result.Count: Int32
type Int32 =
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 3 overloads
static val MaxValue : int
static val MinValue : int
static member Parse : s:string -> int + 3 overloads
static member TryParse : s:string * result:int -> bool + 1 overload
end
Full name: System.Int32
Result.Average: float
Multiple items
val float : value:'T -> float (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.float
--------------------
type float = Double
Full name: Microsoft.FSharp.Core.float
--------------------
type float<'Measure> = float
Full name: Microsoft.FSharp.Core.float<_>
Result.StdDev: float
Result.Min: float
Result.Max: float
val x : Result
member Result.Print : unit -> unit
Full name: Script.Result.Print
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val ReadLines : fileName:string -> seq<string>
Full name: Script.ReadLines
val fileName : string
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val reader : StreamReader
Multiple items
type StreamReader =
inherit TextReader
new : stream:Stream -> StreamReader + 9 overloads
member BaseStream : Stream
member Close : unit -> unit
member CurrentEncoding : Encoding
member DiscardBufferedData : unit -> unit
member EndOfStream : bool
member Peek : unit -> int
member Read : unit -> int + 1 overload
member ReadLine : unit -> string
member ReadToEnd : unit -> string
...
Full name: System.IO.StreamReader
--------------------
StreamReader(stream: Stream) : unit
StreamReader(path: string) : unit
StreamReader(stream: Stream, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(stream: Stream, encoding: Text.Encoding) : unit
StreamReader(path: string, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(path: string, encoding: Text.Encoding) : unit
StreamReader(stream: Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(path: string, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : unit
StreamReader(stream: Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
StreamReader(path: string, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : unit
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
property StreamReader.EndOfStream: bool
StreamReader.ReadLine() : string
val ComputeResults : name:string -> values:seq<float> -> Result
Full name: Script.ComputeResults
val name : string
val values : seq<float>
val count : int
module Seq
from Microsoft.FSharp.Collections
val length : source:seq<'T> -> int
Full name: Microsoft.FSharp.Collections.Seq.length
val average : float
val average : source:seq<'T> -> 'T (requires member ( + ) and member DivideByInt and member get_Zero)
Full name: Microsoft.FSharp.Collections.Seq.average
val variance : float
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val n : float
val sum : source:seq<'T> -> 'T (requires member ( + ) and member get_Zero)
Full name: Microsoft.FSharp.Collections.Seq.sum
val stdDev : float
type Math =
static val PI : float
static val E : float
static member Abs : value:sbyte -> sbyte + 6 overloads
static member Acos : d:float -> float
static member Asin : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member BigMul : a:int * b:int -> int64
static member Ceiling : d:decimal -> decimal + 1 overload
static member Cos : d:float -> float
...
Full name: System.Math
Math.Sqrt(d: float) : float
val min : source:seq<'T> -> 'T (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.min
val max : source:seq<'T> -> 'T (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.max
val GetStatistics : serverName:'a -> projectName:string -> Result
Full name: Script.GetStatistics
val serverName : 'a
val projectName : string
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
String.Format(format: string, [<ParamArray>] args: obj []) : string
String.Format(format: string, arg0: obj) : string
String.Format(provider: IFormatProvider, format: string, [<ParamArray>] args: obj []) : string
String.Format(format: string, arg0: obj, arg1: obj) : string
String.Format(format: string, arg0: obj, arg1: obj, arg2: obj) : string
val s : string
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
val v : string []
Multiple items
type TimeSpan =
struct
new : ticks:int64 -> TimeSpan + 3 overloads
member Add : ts:TimeSpan -> TimeSpan
member CompareTo : value:obj -> int + 1 overload
member Days : int
member Duration : unit -> TimeSpan
member Equals : value:obj -> bool + 1 overload
member GetHashCode : unit -> int
member Hours : int
member Milliseconds : int
member Minutes : int
...
end
Full name: System.TimeSpan
--------------------
TimeSpan()
TimeSpan(ticks: int64) : unit
TimeSpan(hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : unit
TimeSpan.TryParse(s: string, result: byref<TimeSpan>) : bool
TimeSpan.TryParse(input: string, formatProvider: IFormatProvider, result: byref<TimeSpan>) : bool
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.filter
val r : bool
val span : TimeSpan
field TimeSpan.Zero
property TimeSpan.TotalMinutes: float
val client : obj
Full name: Script.client
val p : Result
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Seq.sortBy
val result : Result
val iter : action:('T -> unit) -> source:seq<'T> -> unit
Full name: Microsoft.FSharp.Collections.Seq.iter
member Result.Print : unit -> unit
More information