-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.fs
89 lines (62 loc) · 2.98 KB
/
Program.fs
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Checks SVN commit and rejects if any file has tabs
open System
open System.IO
open System.Diagnostics
open System.Text.RegularExpressions
open FSharpx.Strings
open FSharpx.Regex
type SvnChange =
| Update
| NoChange
type Change = { SvnCode : SvnChange; FileName : string}
let (|Match|_|) pattern input =
let m = Regex.Match(input, pattern) in
if m.Success then Some (List.tail [ for g in m.Groups -> g.Value ]) else None
let launchProcess args =
let processStartInfo = new ProcessStartInfo(
FileName = "svnlook.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
Arguments = args )
let proc = Process.Start(processStartInfo)
let output = proc.StandardOutput.ReadToEnd()
proc.WaitForExit()
output
let tab = (=) '\t'
let leadingWhiteSpaceHas predicate (str:string) = Seq.takeWhile Char.IsWhiteSpace str |> Seq.exists predicate
let getFileContents transaction repoPath filePath = launchProcess <| sprintf "cat -t %s %s %s" transaction repoPath filePath
let createChangeRecord line:Change =
match line with
| Match "^[AU].\s\s(.+)$" result -> { SvnCode = Update; FileName = result.Head }
| _ -> { SvnCode = NoChange; FileName = "" }
let printFileName fileName = eprintfn "%s" fileName
[<EntryPoint>]
let main args =
if Array.length args <> 3 then
eprintfn "Usage: repoPath transactionId extensions"
eprintfn "Extensions should be in the form of \".ext1;.ext2;.ext3;...\""
1
else
let repoPath = args.[0]
let transaction = args.[1]
let extensions = args.[2]
let results = launchProcess <| sprintf "changed -t %s %s" transaction repoPath
let filePaths = toLines results
let hasChange (t:Change) = t.SvnCode <> NoChange
let isValidFile (t:Change) = extensions |> splitBy (fun i -> i = ';') |> Seq.exists (fun ext -> t.FileName.EndsWith(ext))
let hasTabs change = getFileContents transaction repoPath change.FileName |> leadingWhiteSpaceHas tab
let applyTo a list = List.map (fun f -> f a) list
let forAll list a = applyTo a list |> List.reduce (&&)
let found = filePaths
|> Seq.map createChangeRecord
|> Seq.filter (forAll [isValidFile; hasTabs; hasTabs])
|> Seq.map (fun i -> i.FileName)
|> Seq.toList
if not <| Seq.isEmpty found then
eprintfn "%s" "Change set has files with tabs:\r\n"
found |> Seq.iter printFileName
1
else
0