Skip to content

Instantly share code, notes, and snippets.

@b0urb4k1
Last active October 7, 2016 12:17
Show Gist options
  • Save b0urb4k1/b0a1c3c3193bdb89aa0c6a75bd8a8894 to your computer and use it in GitHub Desktop.
Save b0urb4k1/b0a1c3c3193bdb89aa0c6a75bd8a8894 to your computer and use it in GitHub Desktop.
open System.Text.RegularExpressions
open System.IO
open System.Collections.Generic
type Project =
{ name : string
; location : string
; guid : string
; dependencies : string list
}
type ProjectHandling = Finished of Project | Open of Project | Started of Project
let regexOptions =
RegexOptions.Compiled ||| RegexOptions.Singleline
let guidPattern =
".*?(?<guid>{[A-Z0-9-]*})"
let projectPattern =
@"Project.*=.""(?<name>.*?)"",.""(?<location>.*?)"",.""(?<guid>{.*?})"""
let guidRegex =
Regex(guidPattern, regexOptions)
let projectRegex =
Regex(projectPattern, regexOptions)
let projectEnd =
Regex("EndProject", regexOptions)
let (|Guid|_|) line =
let m = guidRegex.Match line
if m.Success
then Some m.Groups.["guid"].Value
else None
let (|Project|_|) line =
let m = projectRegex.Match line
if m.Success
then Some { name = m.Groups.["name"].Value
; location = m.Groups.["location"].Value
; guid = m.Groups.["guid"].Value
; dependencies = []
}
else None
let (|ProjectEnd|_|) line =
let m = projectEnd.Match line
if m.Success
then Some ()
else None
let addGuid project guid =
{ project with dependencies = List.append project.dependencies [guid] }
let addLine (project : Project option) line =
match project with
| Some pro ->
match line with
// | Project p -> Some <| Started p
| Guid guid -> Some <| (Open <| addGuid pro guid)
| ProjectEnd -> Some <| Finished pro
| _ -> Some <| Open pro
| None ->
match line with
| Project p -> Some <| Started p
| _ -> None
let debugPrint p =
match p with
| Some (Started pr) -> printf "Started %s\n" pr.name
| Some (Open pr) -> printf "Open %s\n" pr.name
| Some (Finished pr) -> printf "Finished %s\n" pr.name
| _ -> printf "???"
let projectAccumulator (openProject : Project option, projects : Project list) line =
let maybeProject = addLine openProject line
// print maybeProject
match maybeProject with
| Some (Started project) -> (Some <| project, projects)
| Some (Open project) -> (Some <| project, projects)
| Some (Finished project) -> (None, project :: projects)
| _ -> (None, projects)
let projectDependencies file =
let lines = File.ReadAllLines file |> Array.toList
let (openProject, projects) = List.fold projectAccumulator (None, []) lines
projects
let lookup (dictionary : IDictionary<'a, 'b>) key =
dictionary.[key]
let print (projectDictionary : IDictionary<string, string>) project =
printf "name: %s, location: %s\n" project.name project.location
if project.dependencies.Length > 0
then
printf "dependencies:\n"
List.map (printf "\t%s\n" << (lookup projectDictionary)) project.dependencies
|> ignore
else ()
let toDict projects =
let dictionary = Dictionary<string, string>()
projects |> List.map (fun p -> dictionary.Add(p.guid, p.location)) |> ignore
dictionary
let isCsProject project =
project.location.EndsWith(".csproj")
let hasCppDependency (projectDictionary : IDictionary<string, string>) project =
if List.isEmpty project.dependencies
then false
else List.exists ( fun (p:string) ->
projectDictionary.Item(p).EndsWith(".vcxproj")
) project.dependencies
let projects =
projectDependencies fsi.CommandLineArgs.[1]
|> List.rev
let projectDictionary = toDict projects
let allTrue (predicates : (Project -> bool) list) projects =
projects |>
List.filter (fun project ->
[ for predicate in predicates do
yield predicate project ]
|> List.forall id)
projects
|> allTrue [(hasCppDependency projectDictionary); isCsProject]
|> List.map (print projectDictionary)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment