Inheritance: RepositoryContext
Exemplo n.º 1
0
        public static Context ParseArguments(List<string> commandLineArguments, IProviderManager providerManager)
        {
            var context = new Context(providerManager);

            if (commandLineArguments.Count == 0)
            {
                Log.ErrorAndThrowException<GitLinkException>("Invalid number of arguments");
            }

            var firstArgument = commandLineArguments.First();
            if (IsHelp(firstArgument))
            {
                context.IsHelp = true;
                return context;
            }

            if (commandLineArguments.Count < 3)
            {
                Log.ErrorAndThrowException<GitLinkException>("Invalid number of arguments");
            }

            context.SolutionDirectory = firstArgument;

            var namedArguments = commandLineArguments.Skip(1).ToList();
            for (var index = 0; index < namedArguments.Count; index++)
            {
                var name = namedArguments[index];

                // First check everything without values
                if (IsSwitch("debug", name))
                {
                    context.IsDebug = true;
                    continue;
                }

                // After this point, all arguments should have a value
                index++;
                var valueInfo = GetValue(namedArguments, index);
                var value = valueInfo.Key;
                index = index + (valueInfo.Value - 1);

                if (IsSwitch("l", name))
                {
                    context.LogFile = value;
                    continue;
                }

                if (IsSwitch("c", name))
                {
                    context.ConfigurationName = value;
                    continue;
                }

                if (IsSwitch("p", name))
                {
                    context.PlatformName = value;
                    continue;
                }

                if (IsSwitch("u", name))
                {
                    context.TargetUrl = value;
                    continue;
                }

                if (IsSwitch("b", name))
                {
                    context.TargetBranch = value;
                    continue;
                }

                if (IsSwitch("s", name))
                {
                    context.ShaHash = value;
                    continue;
                }

                if (IsSwitch("f", name))
                {
                    context.SolutionFile = value;
                    continue;
                }

                if (IsSwitch("ignore", name))
                {
                    context.IgnoredProjects.AddRange(value.Split(new []{ ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()));
                    continue;
                }

                Log.ErrorAndThrowException<GitLinkException>("Could not parse command line parameter '{0}'.", name);
            }

            if (!string.IsNullOrEmpty(context.TargetUrl))
            {
                context.Provider = providerManager.GetProvider(context.TargetUrl);
            }

            return context;
        }
Exemplo n.º 2
0
        public static int Link(Context context)
        {
            int? exitCode = null;

            var stopWatch = new Stopwatch();
            stopWatch.Start();

            context.ValidateContext();

            if (!string.IsNullOrEmpty(context.LogFile))
            {
                var fileLogListener = new FileLogListener(context.LogFile, 25 * 1024);
                fileLogListener.IsDebugEnabled = context.IsDebug;

                fileLogListener.IgnoreCatelLogging = true;
                LogManager.AddListener(fileLogListener);
            }

            if (!PdbStrHelper.IsPdbStrAvailable())
            {
                Log.Error("PdbStr is not found on the computer, please install 'Debugging Tools for Windows'");
                return -1;
            }

            try
            {
                var projects = new List<Project>();
                string[] solutionFiles;
                if (string.IsNullOrEmpty(context.SolutionFile))
                {
                    solutionFiles = Directory.GetFiles(context.SolutionDirectory, "*.sln", SearchOption.AllDirectories);
                }
                else
                {
                    var pathToSolutionFile = Path.Combine(context.SolutionDirectory, context.SolutionFile);
                    if (!File.Exists(pathToSolutionFile))
                    {
                        Log.Error("Could not find solution file: " + pathToSolutionFile);
                        return -1;
                    }

                    solutionFiles = new[] { pathToSolutionFile };
                }

                foreach (var solutionFile in solutionFiles)
                {
                    var solutionProjects = ProjectHelper.GetProjects(solutionFile, context.ConfigurationName, context.PlatformName);
                    projects.AddRange(solutionProjects);
                }

                var provider = context.Provider;
                if (provider == null)
                {
                    Log.ErrorAndThrowException<GitLinkException>("Cannot find a matching provider for '{0}'", context.TargetUrl);
                }

                Log.Info("Using provider '{0}'", provider.GetType().Name);

                var shaHash = context.Provider.GetShaHashOfCurrentBranch(context);

                Log.Info("Using commit sha '{0}' as version stamp", shaHash);

                var projectCount = projects.Count();
                var failedProjects = new List<Project>();
                Log.Info("Found '{0}' project(s)", projectCount);
                Log.Info(string.Empty);

                foreach (var project in projects)
                {
                    try
                    {
                        if (project.ShouldBeIgnored(context.IgnoredProjects))
                        {
                            Log.Info("Ignoring '{0}'", project.GetProjectName());
                            Log.Info(string.Empty);
                            continue;
                        }

                        if (context.IsDebug)
                        {
                            project.DumpProperties();
                        }

                        if (!LinkProject(context, project, shaHash))
                        {
                            failedProjects.Add(project);
                        }
                    }
                    catch (Exception)
                    {
                        failedProjects.Add(project);
                    }
                }

                Log.Info("All projects are done. {0} of {1} succeeded", projectCount - failedProjects.Count, projectCount);

                if (failedProjects.Count > 0)
                {
                    Log.Info(string.Empty);
                    Log.Info("The following projects have failed:");
                    Log.Indent();

                    foreach (var failedProject in failedProjects)
                    {
                        Log.Info("* {0}", context.GetRelativePath(failedProject.GetProjectName()));
                    }

                    Log.Unindent();
                }

                exitCode = (failedProjects.Count == 0) ? 0 : -1;
            }
            catch (GitLinkException ex)
            {
                Log.Error(ex, "An error occurred");
            }
            catch (Exception ex)
            {
                Log.Error(ex, "An unexpected error occurred");
            }

            stopWatch.Stop();

            Log.Info(string.Empty);
            Log.Info("Completed in '{0}'", stopWatch.Elapsed);

            return exitCode ?? -1;
        }
Exemplo n.º 3
0
        private static bool LinkProject(Context context, Project project, string shaHash)
        {
            Argument.IsNotNull(() => context);
            Argument.IsNotNull(() => project);

            try
            {
                var projectName = project.GetProjectName();

                Log.Info("Handling project '{0}'", projectName);

                Log.Indent();

                var compilables = project.GetCompilableItems().Select(x => x.GetFullFileName());

                var projectPdbFile = Path.GetFullPath(project.GetOutputPdbFile());
                var projectStcSrvFile = Path.GetFullPath(project.GetOutputSrcSrvFile());
                if (!File.Exists(projectPdbFile))
                {
                    Log.Warning("No pdb file found for '{0}', is project built in '{1}' mode with pdb files enabled? Expected file is '{2}'", projectName, context.ConfigurationName, projectPdbFile);
                    return false;
                }

                Log.Info("Verifying pdb file");

                var missingFiles = project.VerifyPdbFiles(compilables);
                foreach (var missingFile in missingFiles)
                {
                    Log.Warning("Missing file '{0}' or checksum '{1}' did not match", missingFile.Key, missingFile.Value);
                }

                var rawUrl = string.Format("{0}/{{0}}/%var2%", context.Provider.RawGitUrl);
                var paths = new Dictionary<string, string>();
                foreach (var compilable in compilables)
                {
                    var relativePathForUrl = compilable.Replace(context.SolutionDirectory, string.Empty).Replace("\\", "/");
                    while (relativePathForUrl.StartsWith("/"))
                    {
                        relativePathForUrl = relativePathForUrl.Substring(1, relativePathForUrl.Length - 1);
                    }

                    paths.Add(compilable, relativePathForUrl);
                }

                project.CreateSrcSrv(rawUrl, shaHash, paths);

                Log.Debug("Created source server link file, updating pdb file '{0}'", context.GetRelativePath(projectPdbFile));

                PdbStrHelper.Execute(projectPdbFile, projectStcSrvFile);
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "An error occurred while processing project '{0}'", project.GetProjectName());
                throw;
            }
            finally
            {
                Log.Unindent();
                Log.Info(string.Empty);
            }

            return true;
        }
Exemplo n.º 4
0
        public static Context ParseArguments(List<string> commandLineArguments, IProviderManager providerManager)
        {
            var context = new Context(providerManager);

            if (commandLineArguments.Count == 0)
            {
                context.IsHelp = true;
                return context;
            }

            var firstArgument = commandLineArguments.First();
            if (IsHelp(firstArgument))
            {
                context.IsHelp = true;
                return context;
            }

            if (commandLineArguments.Count < 3 && commandLineArguments.Count != 1)
            {
                throw Log.ErrorAndCreateException<GitLinkException>("Invalid number of arguments");
            }

            context.SolutionDirectory = firstArgument;

            var namedArguments = commandLineArguments.Skip(1).ToList();
            for (var index = 0; index < namedArguments.Count; index++)
            {
                var name = namedArguments[index];

                // First check everything without values
                if (IsSwitch("debug", name))
                {
                    context.IsDebug = true;
                    continue;
                }

                if (IsSwitch("errorsaswarnings", name))
                {
                    context.ErrorsAsWarnings = true;
                    continue;
                }

                if (IsSwitch("skipverify", name))
                {
                    context.SkipVerify = true;
                    continue;
                }

                // After this point, all arguments should have a value
                index++;
                var valueInfo = GetValue(namedArguments, index);
                var value = valueInfo.Key;
                index = index + (valueInfo.Value - 1);

                if (IsSwitch("l", name))
                {
                    context.LogFile = value;
                    continue;
                }

                if (IsSwitch("c", name))
                {
                    context.ConfigurationName = value;
                    continue;
                }

                if (IsSwitch("p", name))
                {
                    context.PlatformName = value;
                    continue;
                }

                if (IsSwitch("u", name))
                {
                    context.TargetUrl = value;
                    continue;
                }

                if (IsSwitch("b", name))
                {
                    context.TargetBranch = value;
                    continue;
                }

                if (IsSwitch("s", name))
                {
                    context.ShaHash = value;
                    continue;
                }

                if (IsSwitch("f", name))
                {
                    context.SolutionFile = value;
                    continue;
                }

                if (IsSwitch("d", name))
                {
                    context.PdbFilesDirectory = value;
                    continue;
                }

                if (IsSwitch("ignore", name))
                {
                    context.IgnoredProjects.AddRange(value.Split(new []{ ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()));
                    continue;
                }

                throw Log.ErrorAndCreateException<GitLinkException>("Could not parse command line parameter '{0}'.", name);
            }

            if (string.IsNullOrEmpty(context.TargetUrl))
            {
                Log.Info("No target url was specified, trying to determine the target url automatically");

                var gitDir = GitDirFinder.TreeWalkForGitDir(context.SolutionDirectory);
                if (gitDir != null)
                {
                    using (var repo = RepositoryLoader.GetRepo(gitDir))
                    {
                        var currentBranch = repo.Head;

                        if (string.IsNullOrEmpty(context.ShaHash))
                        {
                            context.ShaHash = currentBranch.Tip.Sha;
                        }

                        if (currentBranch.Remote == null || currentBranch.IsDetachedHead())
                        {
                            currentBranch = repo.GetBranchesContainingCommit(context.ShaHash).FirstOrDefault(b => b.Remote != null);
                        }

                        if (currentBranch != null && currentBranch.Remote != null)
                        {
                            var url = currentBranch.Remote.Url;
                            if (url.StartsWith("https://"))
                            {
                                context.TargetUrl = url.OptimizeUrl();

                                Log.Info("Automatically determine target url '{0}'", context.TargetUrl);
                            }
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(context.TargetUrl))
            {
                context.Provider = providerManager.GetProvider(context.TargetUrl);
            }

            return context;
        }
Exemplo n.º 5
0
        public static int Link(Context context)
        {
            int? exitCode = null;

            var stopWatch = new Stopwatch();
            stopWatch.Start();

            context.ValidateContext();

            if (!string.IsNullOrEmpty(context.LogFile))
            {
                var fileLogListener = new FileLogListener(context.LogFile, 25 * 1024);
                fileLogListener.IsDebugEnabled = context.IsDebug;

                fileLogListener.IgnoreCatelLogging = true;
                LogManager.AddListener(fileLogListener);
            }

            using (var temporaryFilesContext = new TemporaryFilesContext())
            {
                Log.Info("Extracting embedded pdbstr.exe");

                var pdbStrFile = temporaryFilesContext.GetFile("pdbstr.exe");
                ResourceHelper.ExtractEmbeddedResource("GitLink.Resources.Files.pdbstr.exe", pdbStrFile);

                try
                {
                    var projects = new List<Project>();
                    string[] solutionFiles;
                    if (string.IsNullOrEmpty(context.SolutionFile))
                    {
                        solutionFiles = Directory.GetFiles(context.SolutionDirectory, "*.sln", SearchOption.AllDirectories);
                    }
                    else
                    {
                        var pathToSolutionFile = Path.Combine(context.SolutionDirectory, context.SolutionFile);
                        if (!File.Exists(pathToSolutionFile))
                        {
                            Log.Error("Could not find solution file: {0}", pathToSolutionFile);
                            return -1;
                        }

                        solutionFiles = new[] { pathToSolutionFile };
                    }

                    foreach (var solutionFile in solutionFiles)
                    {
                        var solutionProjects = ProjectHelper.GetProjects(solutionFile, context.ConfigurationName, context.PlatformName);
                        projects.AddRange(solutionProjects);
                    }

                    var provider = context.Provider;
                    if (provider == null)
                    {
                        throw Log.ErrorAndCreateException<GitLinkException>("Cannot find a matching provider for '{0}'", context.TargetUrl);
                    }

                    Log.Info("Using provider '{0}'", provider.GetType().Name);

                    var shaHash = context.Provider.GetShaHashOfCurrentBranch(context, temporaryFilesContext);

                    Log.Info("Using commit sha '{0}' as version stamp", shaHash);

                    var projectCount = projects.Count();
                    var failedProjects = new List<Project>();
                    Log.Info("Found '{0}' project(s)", projectCount);
                    Log.Info(string.Empty);

                    foreach (var project in projects)
                    {
                        try
                        {
                            var projectName = project.GetProjectName();
                            if (ProjectHelper.ShouldBeIgnored(projectName, context.IncludedProjects, context.IgnoredProjects))
                            {
                                Log.Info("Ignoring '{0}'", project.GetProjectName());
                                Log.Info(string.Empty);
                                continue;
                            }

                            if (context.IsDebug)
                            {
                                project.DumpProperties();
                            }

                            if (!LinkProject(context, project, pdbStrFile, shaHash, context.PdbFilesDirectory))
                            {
                                failedProjects.Add(project);
                            }
                        }
                        catch (Exception)
                        {
                            failedProjects.Add(project);
                        }
                    }

                    Log.Info("All projects are done. {0} of {1} succeeded", projectCount - failedProjects.Count, projectCount);

                    if (failedProjects.Count > 0)
                    {
                        Log.Info(string.Empty);
                        Log.Info("The following projects have failed:");
                        Log.Indent();

                        foreach (var failedProject in failedProjects)
                        {
                            Log.Info("* {0}", context.GetRelativePath(failedProject.GetProjectName()));
                        }

                        Log.Unindent();
                    }

                    exitCode = (failedProjects.Count == 0) ? 0 : -1;
                }
                catch (GitLinkException ex)
                {
                    Log.Error(ex, "An error occurred");
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "An unexpected error occurred");
                }

                stopWatch.Stop();
            }

            Log.Info(string.Empty);
            Log.Info("Completed in '{0}'", stopWatch.Elapsed);

            exitCode = exitCode ?? -1;

            if (context.ErrorsAsWarnings && exitCode != 0)
            {
                Log.Info("One or more errors occurred, but treating it as warning instead");

                exitCode = 0;
            }

            return exitCode.Value;
        }
Exemplo n.º 6
0
        private static bool LinkProject(Context context, Project project, string pdbStrFile, string shaHash, string pathPdbDirectory = null)
        {
            Argument.IsNotNull(() => context);
            Argument.IsNotNull(() => project);

            try
            {
                var projectName = project.GetProjectName();

                Log.Info("Handling project '{0}'", projectName);

                Log.Indent();

                var compilables = project.GetCompilableItems().Select(x => x.GetFullFileName()).ToList();

                var outputPdbFile = project.GetOutputPdbFile();
                var projectPdbFile = pathPdbDirectory != null ? Path.Combine(pathPdbDirectory, Path.GetFileName(outputPdbFile)) : Path.GetFullPath(outputPdbFile);
                var projectSrcSrvFile = projectPdbFile + ".srcsrv";

                var srcSrvContext = new SrcSrvContext
                {
                    Revision = shaHash,
                    RawUrl = context.Provider.RawGitUrl,
                    DownloadWithPowershell = context.DownloadWithPowershell
                };

                if (!File.Exists(projectPdbFile))
                {
                    Log.Warning("No pdb file found for '{0}', is project built in '{1}' mode with pdb files enabled? Expected file is '{2}'", projectName, context.ConfigurationName, projectPdbFile);
                    return false;
                }

                if (!context.SkipVerify)
                {
                    Log.Info("Verifying pdb file");

                    var missingFiles = project.VerifyPdbFiles(compilables, projectPdbFile);
                    foreach (var missingFile in missingFiles)
                    {
                        Log.Warning("Missing file '{0}' or checksum '{1}' did not match", missingFile.Key, missingFile.Value);
                    }
                }

                if (!srcSrvContext.RawUrl.Contains("%var2%") && !srcSrvContext.RawUrl.Contains("{0}"))
                {
                    srcSrvContext.RawUrl = string.Format("{0}/{{0}}/%var2%", srcSrvContext.RawUrl);
                }

                foreach (var compilable in compilables)
                {
                    var relativePathForUrl = ReplaceSlashes(context.Provider, compilable.Replace(context.SolutionDirectory, string.Empty));
                    while (relativePathForUrl.StartsWith("/"))
                    {
                        relativePathForUrl = relativePathForUrl.Substring(1, relativePathForUrl.Length - 1);
                    }

                    srcSrvContext.Paths.Add(new Tuple<string, string>(compilable, relativePathForUrl));
                }

                // When using the VisualStudioTeamServicesProvider, add extra infomration to dictionary with VSTS-specific data
                if (context.Provider.GetType().Name.EqualsIgnoreCase("VisualStudioTeamServicesProvider"))
                {
                    srcSrvContext.VstsData["TFS_COLLECTION"] = context.Provider.CompanyUrl;
                    srcSrvContext.VstsData["TFS_TEAM_PROJECT"] = context.Provider.ProjectName;
                    srcSrvContext.VstsData["TFS_REPO"] = context.Provider.ProjectUrl;
                }

                project.CreateSrcSrv(projectSrcSrvFile, srcSrvContext);

                Log.Debug("Created source server link file, updating pdb file '{0}'", context.GetRelativePath(projectPdbFile));

                PdbStrHelper.Execute(pdbStrFile, projectPdbFile, projectSrcSrvFile);
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "An error occurred while processing project '{0}'", project.GetProjectName());
                throw;
            }
            finally
            {
                Log.Unindent();
                Log.Info(string.Empty);
            }

            return true;
        }