Created
September 20, 2020 15:50
-
-
Save atsapura/6c1a7c7c00766f086fa2b9735c43b4f8 to your computer and use it in GitHub Desktop.
Count fsharp lines of code in your project!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.IO | |
type FSharpCodeLine = | |
| NamespaceDeclaration | |
| Open | |
| Comment | |
| Source | |
| Brace | |
type Report = | |
{ | |
TotalFiles: int | |
CodeLines: Map<FSharpCodeLine, int> | |
} | |
let braces = ['{'; '}'; '('; ')'; '['; ']'; '|'; '|'] |> System.Collections.Generic.HashSet | |
let getFsharpSourceFiles path = | |
let dir = DirectoryInfo(path) | |
dir.GetFiles("*.fs", SearchOption.AllDirectories) | |
let readAllLines (file: FileInfo) = | |
async { | |
use f = file.OpenText() | |
let! text = f.ReadToEndAsync() |> Async.AwaitTask | |
return | |
match text with | |
| null | "" -> [||] | |
| text -> | |
text.Split([|"\n"|], StringSplitOptions.RemoveEmptyEntries) | |
} | |
let codeLine str = | |
match str with | |
| null | "" -> None | |
| str when String.IsNullOrWhiteSpace str -> None | |
| str -> | |
let line = str.Trim() | |
if line.StartsWith("//") then Comment | |
elif line.StartsWith("namespace") then NamespaceDeclaration | |
elif line.StartsWith("open") then Open | |
elif String.forall braces.Contains line then Brace | |
else Source | |
|> Some | |
let countCodeLines file = | |
async { | |
let! lines = readAllLines file | |
let codeLines = lines |> Array.choose codeLine | |
return | |
codeLines | |
|> Array.countBy id | |
|> Map.ofSeq | |
} | |
let mergeMaps left right = | |
let add left k v = | |
match Map.tryFind k left with | |
| None -> left.Add(k,v) | |
| Some vl -> left.Add(k, v + vl) | |
Map.fold add left right | |
let countCodeLinesInFolder path = | |
async { | |
let files = getFsharpSourceFiles path | |
let! result = | |
files | |
|> Array.map countCodeLines | |
|> Async.Parallel | |
return | |
{ | |
CodeLines = result |> Array.fold mergeMaps Map.empty | |
TotalFiles = files.Length | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment