Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 3cb9c25705
Fetching contributors…

Cannot retrieve contributors at this time

304 lines (248 sloc) 11.471 kb
#requires -version 2
<#
.DESCRIPTION
Github source indexer will index PDB files with HTTP source file references to a Github repository.
- Adapted from http://sourcepack.codeplex.com
.PARAMETER symbolsFolder
The path of the directory to recursively search for pdb files to index.
.PARAMETER userId
The github user ID.
.PARAMETER repository
The github repository name containing the matching source files.
.PARAMETER branch
The github branch name, the version of the files in the branch must match the source versions the pdb file was created with.
.PARAMETER sourcesRoot
The root of the source folder - i.e the beginning of the original file paths to be stripped out (obtained using "srctool -r Library.pdb").
Will default to the longest common file path if not provided. The remainder will be appended to the appropriate Github url for source retrieval.
.PARAMETER dbgToolsPath
Path to the Debugging Tools for Windows (the srcsrv subfolder) - if not specifed the script tries to find it.
If you don't have the Debugging Tools for Windows in PATH variable you need to provide this argument.
.PARAMETER gitHubUrl
Path to the Github server (defaults to "http://github.com") - override for in-house enterprise github installations.
.PARAMETER ignore
Ignore a source path that contains any of the strings in this array, e.g. -ignore somedir, "some other dir"
.PARAMETER ignoreUnknown
By default this script terminates when it encounters source from a path other than the source root.
Pass this switch to instead ignore all paths other than the source root.
.PARAMETER serverIsRaw
If the server serves raw the /raw directory name should not be concatenated to the source urls.
Pass this switch to omit the /raw directory, e.g. -gitHubUrl https://raw.github.com -serverIsRaw
.EXAMPLE
.\github-sourceindexer.ps1 -symbolsFolder "C:\git\DirectoryContainingPdbFilesToIndex" -userId "GithubUsername" -repository "GithubRepositoryName" -branch "master" -sourcesRoot "c:\git\OriginalCompiledProjectPath" -verbose
Description
-----------
This command will index all pdb files located in the C:\git\DirectoryContainingPdbFilesToIndex directory and subdirectories,
adding to the source stream a reference to the master branch of the GithubRepositoryName repository for the github user GithubUsername.
For example source indexes added like http://github.com/GithubUsername/GithubRepositoryName/raw/master/ExampleLibrary/LibraryClass.cs
where /ExampleLibrary/LibraryClass.cs is the remainder after removing c:\git\OriginalCompiledProjectPath\ from the beginning of the original compile path.
#>
param(
## Folder that will be recursively searched for PDB files.
[Parameter(Mandatory = $true)]
[Alias("symbols")]
[string] $symbolsFolder,
## github user ID
[Parameter(Mandatory = $true)]
[string] $userId,
## github repository name
[Parameter(Mandatory = $true)]
[string] $repository,
## github branch name
[Parameter(Mandatory = $true)]
[string] $branch,
## A root path for the source files
[string] $sourcesRoot,
## Debugging Tools for Windows installation path
[string] $dbgToolsPath,
## Github URL
[string] $gitHubUrl,
## Ignore a source path that contains any of the strings in this array
[string[]] $ignore,
## Ignore paths other than the source root
[switch] $ignoreUnknown,
## Server serves raw: don't concatenate /raw in the path
[switch] $serverIsRaw
)
function CorrectPathBackslash {
param([string] $path)
if (![String]::IsNullOrEmpty($path)) {
if (!$path.EndsWith("\")) {
$path += "\"
}
}
return $path
}
###############################################################
function FindLongestCommonPath {
param([string] $path1,
[string] $path2)
$path1Parts = $path1 -split "\\"
$path2Parts = $path2 -split "\\"
$result = @()
for ($i = 0; ($i -lt $path1Parts.Length) -and ($i -lt $path2Parts.Length); $i++) {
if ($path1Parts[$i] -eq $path2Parts[$i]) {
$result += $path1Parts[$i]
}
}
return [String]::Join("\", $result)
}
###############################################################
function CheckDebuggingToolsPath {
param([string] $dbgToolsPath)
$dbgToolsPath = CorrectPathBackslash $dbgToolsPath
# check whether the dbgToolsPath variable is set
# it links to srctool.exe application
if (![String]::IsNullOrEmpty($dbgToolsPath)) {
if (![System.IO.File]::Exists($dbgToolsPath + "srctool.exe")) {
Write-Debug "Debugging Tools not found at the given location - trying \srcsrv subdirectory..."
# Let's try maybe also srcsrv
$dbgToolsPath += "srcsrv\"
if (![System.IO.File]::Exists($dbgToolsPath + "srctool.exe")) {
throw "The Debugging Tools for Windows could not be found at the provided location."
}
}
# OK, we are fine - the srctool exists
Write-Verbose "Debugging Tools for Windows found at $dbgToolsPath."
} else {
Write-Verbose "Debugging Tools path not provided - trying to guess it..."
# Let's try to execute the srctool and check the error
if ($(Get-Command "srctool.exe" 2>$null) -eq $null) {
# srctool.exe can't be found - let's try cdb
$cdbg = Get-Command "cdb.exe" 2>$null
if ($cdbg -eq $null) {
$errormsg = "The Debugging Tools for Windows could not be found. Please make sure " + `
"that they are installed and reference them using -dbgToolsPath switch."
throw $errormsg
}
# cdbg found srctool.exe should be then in the srcsrv subdirectory
$dbgToolsPath = $([System.IO.Path]::GetDirectoryName($dbg.Defintion)) + "\srcsrv\"
if (![System.IO.File]::Exists($dbgToolsPath + "srctool.exe")) {
$errormsg = "The Debugging Tools for Windows could not be found. Please make sure " + `
"that they are installed and reference them using -dbgToolsPath switch."
throw $errormsg
}
# OK, we are fine - the srctool exists
Write-Verbose "The Debugging Tools For Windows found at $dbgToolsPath."
}
}
return $dbgToolsPath
}
###############################################################
function WriteStreamHeader {
param ([string] $streamPath)
Write-Verbose "Preparing stream header section..."
Add-Content -value "SRCSRV: ini ------------------------------------------------" -path $streamPath
Add-Content -value "VERSION=1" -path $streamPath
Add-Content -value "INDEXVERSION=2" -path $streamPath
Add-Content -value "VERCTL=Archive" -path $streamPath
Add-Content -value ("DATETIME=" + ([System.DateTime]::Now)) -path $streamPath
}
###############################################################
function WriteStreamVariables {
param([string] $streamPath)
Write-Verbose "Preparing stream variables section..."
Add-Content -value "SRCSRV: variables ------------------------------------------" -path $streamPath
Add-Content -value "SRCSRVVERCTRL=http" -path $streamPath
Add-Content -value "HTTP_ALIAS=$gitHubUrl" -path $streamPath
Add-Content -value "HTTP_EXTRACT_TARGET=%HTTP_ALIAS%/%var2%/%var3%$raw/%var4%/%var5%" -path $streamPath
Add-Content -value "SRCSRVTRG=%http_extract_target%" -path $streamPath
Add-Content -value "SRCSRVCMD=" -path $streamPath
}
###############################################################
function WriteStreamSources {
param([string] $streamPath,
[string] $pdbPath)
Write-Verbose "Preparing stream source files section..."
$sources = & ($dbgToolsPath + 'srctool.exe') -r $pdbPath 2>$null
if ($sources -eq $null) {
write-warning "No steppable code in pdb file $pdbPath, skipping";
"failed";
return;
}
Add-Content -value "SRCSRV: source files ---------------------------------------" -path $streamPath
if ([String]::IsNullOrEmpty($sourcesRoot)) {
# That's a little bit hard - we need to guess the source root.
# By default we compare all source paths stored in the PDB file
# and extract the least common path, eg. for paths:
# C:\test\test1\test2\src\Program.cs
# C:\test\test1\test2\src\Test.Domain\Domain.cs
# we will assume that the source code archive was created from
# the C:\test\test1\test2\src\ path - so be careful here!
$sourcesRoot = $null
foreach ($src in $sources) {
if ($sourcesRoot -eq $null) {
$sourcesRoot = [System.IO.Path]::GetDirectoryName($src)
continue
}
$sourcesRoot = FindLongestCommonPath $src $sourcesRoot
}
$warning = "Sources root not provided, assuming: '$sourcesRoot'. If it's not correct please run the script " + `
"with correct value set for -sourcesRoot parameter."
Write-Warning $warning
}
$sourcesRoot = CorrectPathBackslash $sourcesRoot
$outputFileName = [System.IO.Path]::GetFileNameWithoutExtension($sourceArchivePath)
#other source files
foreach ($src in $sources) {
#if the source path $src contains a string in the $ignore array, skip it
[bool] $skip = $false;
foreach ($istr in $ignore) {
$skip = ( ($istr) -and ($src.IndexOf($istr, [System.StringComparison]::OrdinalIgnoreCase) -ge 0) );
if ($skip) {
break;
}
}
if ($skip) {
continue;
}
if (!$src.StartsWith($sourcesRoot, [System.StringComparison]::CurrentCultureIgnoreCase)) {
if ($ignoreUnknown) {
continue;
} else {
throw "Script error. The source path ($src) was invalid";
}
}
$srcStrip = $src.Remove(0, $sourcesRoot.Length).Replace("\", "/")
#Add-Content -value "HTTP_ALIAS=http://github.com/%var2%/%var3%$raw/%var4%/%var5%" -path $streamPath
Add-Content -value "$src*$userId*$repository*$branch*$srcStrip" -path $streamPath
Write-Verbose "Indexing source to $gitHubUrl/$userId/$repository$raw/$branch/$srcStrip"
}
}
###############################################################
# START
###############################################################
if ([String]::IsNullOrEmpty($gitHubUrl)) {
$gitHubUrl = "http://github.com";
}
# If the server serves raw then /raw does not need to be concatenated
if ($serverIsRaw) {
$raw = "";
} else {
$raw = "/raw";
}
# Check the debugging tools path
$dbgToolsPath = CheckDebuggingToolsPath $dbgToolsPath
$pdbs = Get-ChildItem $symbolsFolder -Filter *.pdb -Recurse
foreach ($pdb in $pdbs) {
Write-Verbose "Indexing $($pdb.FullName) ..."
$streamContent = [System.IO.Path]::GetTempFileName()
try {
# fill the PDB stream file
WriteStreamHeader $streamContent
WriteStreamVariables $streamContent
$success = WriteStreamSources $streamContent $pdb.FullName
if($success -eq "failed") {
continue
}
Add-Content -value "SRCSRV: end ------------------------------------------------" -path $streamContent
# Save stream to the pdb file
$pdbstrPath = "{0}pdbstr.exe" -f $dbgToolsPath
$pdbFullName = $pdb.FullName
# write stream info to the pdb file
Write-Verbose "Saving the generated stream into the PDB file..."
. $pdbstrPath -w -s:srcsrv "-p:$pdbFullName" "-i:$streamContent"
Write-Verbose "Done."
} finally {
Remove-Item $streamContent
}
}
Jump to Line
Something went wrong with that request. Please try again.