Skip to content

Instantly share code, notes, and snippets.

@ctaggart
Created June 17, 2013 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctaggart/5801490 to your computer and use it in GitHub Desktop.
Save ctaggart/5801490 to your computer and use it in GitHub Desktop.
creating a srcsrv for Autofac.pdb
open Microsoft.Cci.Pdb
open System
open System.IO
open System.Collections.Generic
open System.Text
let hashFormat (hash:byte[]) =
let sb = StringBuilder(hash.Length * 2)
for b in hash do
sb.AppendFormat("{0:x2}", b) |> ignore
sb.ToString()
let computeFileHashes dir =
use md5 = Security.Cryptography.MD5.Create()
let computeHash file =
use fs = File.OpenRead file
md5.ComputeHash fs
let hashMap = Dictionary<string, string>()
for f in Directory.EnumerateFiles(dir, "*.cs", SearchOption.AllDirectories) do
hashMap.[f |> computeHash |> hashFormat] <- f
hashMap
let getPdbHashes pdb =
use f = File.OpenRead pdb
// it would be cool if these were public and not internal in Microsoft.Cci.Pdb
let header = PdbFileHeader(f, BitAccess(0)) // header
let reader = PdbReader(f, header.pageSize)
let streams = MsfDirectory(reader, header, BitAccess(0)).streams // stream 0
// printfn "%d" streams.Length
// let i = ref 0
// streams |> Seq.iter (fun s ->
// printfn "%d %d %A" !i s.contentSize s.pages
// incr i
// )
let readBits i =
let bits = BitAccess(0)
streams.[i].Read(reader, bits)
bits
let names = PdbFile.LoadNameIndex(readBits 1) // stream 1
names
|> Seq.filter (fun (KeyValue(name, _)) -> name.ToLowerInvariant().StartsWith("/src/files/"))
|> Seq.map (fun (KeyValue(name, i)) -> (readBits i).Buffer.[72..87] |> hashFormat, name.ToLowerInvariant().Substring(11))
|> List.ofSeq
[<EntryPoint>]
let main argv =
let pdb = @"..\..\Autofac.3.0.2\Autofac.pdb"
let txt = @"..\..\Autofac.3.0.2\Autofac.pdb.srcsrv.txt"
let pdbBuildPath = @"d:\development\oss\autofac\" // original in pdb
let srcDir = @"C:\Projects\autofac2\"
let httpBase = "https://autofac.googlecode.com/hg-history"
let changeset = "78573601d8613ab838dff769b15e1d9a1c7171fe"
let fileHashes = computeFileHashes srcDir
let pdbHashes = getPdbHashes pdb
let map = SortedDictionary(StringComparer.OrdinalIgnoreCase)
for hash, name in pdbHashes do
if fileHashes.ContainsKey hash then
let path = fileHashes.[hash].Substring(srcDir.Length).Replace('\\','/')
map.Add(name, path)
else
let path = name.Substring(pdbBuildPath.Length).Replace('\\','/')
printfn "%s %s" hash name
map.Add(name, path)
// override printfn to write to a file
use sw = new StreamWriter(txt)
let printfn format = fprintfn sw format
printfn "SRCSRV: ini ------------------------------------------------"
printfn "VERSION=1"
printfn "SRCSRV: variables ------------------------------------------"
printfn "SRCSRVVERCTRL=https"
printfn "SRCSRVTRG=%s/%s/%%var2%%" httpBase changeset
printfn "SRCSRV: source files ---------------------------------------"
for (KeyValue(file, path)) in map do
printfn "%s*%s" file path
printfn "SRCSRV: end ------------------------------------------------"
0 // exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment