diff --git a/CONTRIBUTORS b/CONTRIBUTORS index de1b252..959fda1 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -16,4 +16,5 @@ Wesley Eledui Marek Fišera Shai Nahum Amadeusz Wieczorek -Adrien JUND \ No newline at end of file +Adrien JUND +Raymond Wu \ No newline at end of file diff --git a/README.md b/README.md index 6147ad1..b760232 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,15 @@ Native PDBs (from C++ projects) are supported by using -a option: All known C++ source files from your git depot will be indexed in the PDB. +### Indexing with SrcTool + +Srctool is capable of listing the raw source file information from a .pdb file. +If you are dealing with a huge git repository and only need to index source files from a Native PDB that are found in git (And not the entire git depot) use the -t option: + + GitLink.exe -t + +.NET PDBs (C#) are also supported. + ### More options There are many more parameters you can use. Display the usage doc with the following command line: diff --git a/src/GitLink/GitLink.csproj b/src/GitLink/GitLink.csproj index 9609148..7c09e97 100644 --- a/src/GitLink/GitLink.csproj +++ b/src/GitLink/GitLink.csproj @@ -22,6 +22,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/GitLink/Helpers/SrcToolHelper.cs b/src/GitLink/Helpers/SrcToolHelper.cs new file mode 100644 index 0000000..823ef50 --- /dev/null +++ b/src/GitLink/Helpers/SrcToolHelper.cs @@ -0,0 +1,67 @@ +// +// Copyright (c) 2014 - 2016 CatenaLogic. All rights reserved. +// + +namespace GitLink +{ + using System.Collections.Generic; + using System.Diagnostics; + using System.IO; + using Catel; + using Catel.Logging; + using GitTools.Git; + + internal static class SrcToolHelper + { + private static readonly ILog Log = LogManager.GetCurrentClassLogger(); + + internal static List GetSourceFiles(string srcToolFilePath, string projectPdbFile) + { + Argument.IsNotNullOrWhitespace(() => projectPdbFile); + List sources = new List(); + + var processStartInfo = new ProcessStartInfo(srcToolFilePath) + { + Arguments = string.Format("-r \"{0}\"", projectPdbFile), + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true, + }; + + using (var process = new Process()) + { + process.OutputDataReceived += (s, e) => + { + if (e.Data != null) + { + var sourceFile = e.Data.ToLower(); + + if (Linker.ValidExtension(sourceFile)) + { + var repositoryDirectory = GitDirFinder.TreeWalkForGitDir(Path.GetDirectoryName(sourceFile)); + + if (repositoryDirectory != null) + { + sources.Add(sourceFile); + } + } + } + }; + + process.EnableRaisingEvents = true; + process.StartInfo = processStartInfo; + process.Start(); + process.BeginOutputReadLine(); + process.WaitForExit(); + + var processExitCode = process.ExitCode; + if (processExitCode != 0) + { + throw Log.ErrorAndCreateException("SrcTool exited with unexpected error code '{0}'", processExitCode); + } + } + + return sources; + } + } +} diff --git a/src/GitLink/LinkOptions.cs b/src/GitLink/LinkOptions.cs index 5435dab..3974ef1 100644 --- a/src/GitLink/LinkOptions.cs +++ b/src/GitLink/LinkOptions.cs @@ -26,6 +26,8 @@ public struct LinkOptions public bool IndexAllDepotFiles { get; set; } + public bool IndexWithSrcTool { get; set; } + public string IntermediateOutputPath { get; set; } } } diff --git a/src/GitLink/Linker.cs b/src/GitLink/Linker.cs index 7b451f9..166dabe 100644 --- a/src/GitLink/Linker.cs +++ b/src/GitLink/Linker.cs @@ -30,7 +30,9 @@ public static class Linker private static readonly string FilenamePlaceholder = Uri.EscapeUriString("{filename}"); private static readonly string RevisionPlaceholder = Uri.EscapeUriString("{revision}"); private static readonly string PdbStrExePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "pdbstr.exe"); + private static readonly string SrcToolExePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "srctool.exe"); private static readonly string[] ExtensionsToIgnore = new string[] { ".g.cs" }; + private static readonly HashSet SourceExtensions = new HashSet(StringComparer.OrdinalIgnoreCase) { ".cs", ".cpp", ".c", ".cc", ".cxx", ".c++", ".h", ".hh", ".inl", ".hpp" }; private static IReadOnlyList _sourceFilesList = null; public static bool LinkDirectory(string pdbFolderPath, LinkOptions options = default(LinkOptions)) @@ -81,11 +83,18 @@ public static class Linker } else { - _sourceFilesList = GetSourceFilesFromPdb(pdbPath, !options.SkipVerify); + if (options.IndexWithSrcTool) + { + _sourceFilesList = SrcToolHelper.GetSourceFiles(SrcToolExePath, pdbPath); + } + else + { + _sourceFilesList = GetSourceFilesFromPdb(pdbPath, !options.SkipVerify); + } if (!_sourceFilesList.Any()) { - Log.Error($"No source files were found in the PDB: {pdbPath}. If your PDB is native you should use the -a option."); + Log.Error($"No source files were found in the PDB: {pdbPath}. If your PDB is native you could use the -a or -t option."); return false; } @@ -282,17 +291,7 @@ private static List GetSourceFilesFromDepot(string repositoryDirectory) { sourceFiles = from file in Directory.GetFiles(repo.Info.WorkingDirectory, "*.*", SearchOption.AllDirectories) where !repo.Ignore.IsPathIgnored(file) - let ext = Path.GetExtension(file) - where string.Equals(ext, ".cs", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".cpp", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".c", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".cc", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".cxx", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".c++", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".h", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".hh", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".inl", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".hpp", StringComparison.OrdinalIgnoreCase) + where ValidExtension(file) select file; } @@ -364,5 +363,12 @@ private static string ReplaceSlashes(IProvider provider, string relativePathForU return relativePathForUrl; } + + public static Boolean ValidExtension(string sourceFile) + { + var ext = Path.GetExtension(sourceFile); + + return SourceExtensions.Contains(ext); + } } } diff --git a/src/GitLink/Program.cs b/src/GitLink/Program.cs index 2110255..d6127ea 100644 --- a/src/GitLink/Program.cs +++ b/src/GitLink/Program.cs @@ -32,6 +32,7 @@ private static int Main(string[] args) string pdbPath = null; bool skipVerify = false; bool allDepotFiles = false; + bool useSrcTool = false; LinkMethod method = LinkMethod.Http; var arguments = ArgumentSyntax.Parse(args, syntax => { @@ -41,6 +42,7 @@ private static int Main(string[] args) syntax.DefineOption("baseDir", ref baseDir, "The path to the root of the git repo."); syntax.DefineOption("s|skipVerify", ref skipVerify, "Verify all source files are available in source control."); syntax.DefineOption("a|allDepotFiles", ref allDepotFiles, "Index all source files from depot. Add this option for native PDBs (C++)."); + syntax.DefineOption("t|useSrcTool", ref useSrcTool, "Index all source files using SrcTool. This option supports .NET/native PDBs (Cannot be used with allDepotFiles)."); syntax.DefineParameter("pdb", ref pdbPath, "The PDB to add source indexing to."); if (!string.IsNullOrEmpty(pdbPath) && !File.Exists(pdbPath) && !Directory.Exists(pdbPath)) @@ -68,6 +70,7 @@ private static int Main(string[] args) SkipVerify = skipVerify, Method = method, IndexAllDepotFiles = allDepotFiles, + IndexWithSrcTool = useSrcTool, }; if (File.Exists(pdbPath)) diff --git a/src/GitLink/srctool.exe b/src/GitLink/srctool.exe new file mode 100644 index 0000000..7d23abe Binary files /dev/null and b/src/GitLink/srctool.exe differ diff --git a/src/GitLink/winsdk.redist.txt b/src/GitLink/winsdk.redist.txt index ce31923..e7bb9a4 100644 --- a/src/GitLink/winsdk.redist.txt +++ b/src/GitLink/winsdk.redist.txt @@ -13,4 +13,10 @@ dbghelp.dll pdbstr.exe =================== -(1) You may redistribute pdbstr.exe version 6.12.2.633 \ No newline at end of file +(1) You may redistribute pdbstr.exe version 6.12.2.633 + +=================== +srctool.exe +=================== + +(1) You may redistribute srctool.exe version 6.12.2.633 \ No newline at end of file diff --git a/src/GitLinkTask/LinkPdbToGitRemote.cs b/src/GitLinkTask/LinkPdbToGitRemote.cs index 27e8724..031de21 100644 --- a/src/GitLinkTask/LinkPdbToGitRemote.cs +++ b/src/GitLinkTask/LinkPdbToGitRemote.cs @@ -26,6 +26,8 @@ public string Method public bool IndexAllDepotFiles { get; set; } + public bool IndexWithSrcTool { get; set; } + public string GitRemoteUrl { get; set; } public string GitCommitId { get; set; } @@ -48,6 +50,7 @@ public override bool Execute() CommitId = GitCommitId, GitWorkingDirectory = GitWorkingDirectory, IndexAllDepotFiles = IndexAllDepotFiles, + IndexWithSrcTool = IndexWithSrcTool, IntermediateOutputPath = Path.GetFullPath(AddTrailingSlash(IntermediateOutputPath)), }; bool success = Linker.Link(PdbFile.GetMetadata("FullPath"), options); diff --git a/src/GitLinkTask/build/GitLink.targets b/src/GitLinkTask/build/GitLink.targets index ecadc7e..06aef42 100644 --- a/src/GitLinkTask/build/GitLink.targets +++ b/src/GitLinkTask/build/GitLink.targets @@ -14,6 +14,7 @@ Method="$(GitLinkMethod)" SkipVerify="$(GitLinkSkipVerify)" IndexAllDepotFiles="$(GitLinkIndexAllDepotFiles)" + IndexWithSrcTool="$(GitLinkIndexWithSrcTool)" GitRemoteUrl="$(GitLinkGitRemoteUrl)" GitWorkingDirectory="$(GitWorkingDirectory)" GitCommitId="$(GitCommitId)"