Exemplo n.º 1
0
        public ITree Build(
            IRepositoryData repository,
            IRemote remoteToUse,
            IBranchesKnowledge branchesKnowledge,
            IBranchPickingOptions branchPickingOptions,
            ITagPickingOptions tagPickingOptions)
        {
            ITree tree = new Tree();

            tree.SetCommits(repository.Commits);

            AddBranches(branchesKnowledge, repository.Commits, branchPickingOptions, tree);

            AddTags(repository.Tags, tagPickingOptions, tree);

            return(tree);
        }
Exemplo n.º 2
0
        private void AddBranches(
            IBranchesKnowledge branchesKnowledge,
            ICommitsData commitsData,
            IBranchPickingOptions branchPickingOptions,
            ITree tree)
        {
            // Branches in the writing order.
            IBranch[] branchesOrdered = branchesKnowledge.EnumerateBranchesInLogicalOrder().ToArray();

            IBranchPicker branchPicker = _branchPickerFactory.CreateBranchPicker(branchPickingOptions);

            // Filter them so that we get only those we want to write.
            IBranch[] branchesFiltered = branchesOrdered.Where(b => branchPicker.ShouldBePicked(b.Label)).ToArray();

            var commitsSet = new HashSet <ICommit>(commitsData);

            foreach (IBranch b in branchesFiltered)
            {
                ICommit tip = commitsData.GetByHash(b.Tip);

                var hashesInBranch = new List <IHash>(commitsSet.Count / 3);
                IEnumerable <ICommit> upTheTree = commitsData.EnumerateUpTheHistoryFrom(tip);
                foreach (ICommit commit in upTheTree)
                {
                    if (!commitsSet.Contains(commit))
                    {
                        break;
                    }

                    hashesInBranch.Add(commit.Hash);
                    commitsSet.Remove(commit);
                }

                hashesInBranch.Reverse();
                tree.AddBranch(b, hashesInBranch);
            }
        }
Exemplo n.º 3
0
        protected override void RunInternal()
        {
            // Get the immutable repository information.

            IRepositoryData repositoryData = _loader.LoadFrom(_repositoryDir.FullName);

            // Pick the remote to work on.
            IRemote remoteToUse = _remoteHelper.PickRemote(repositoryData, Options.RemoteToUse);

            // Create the tree.
            IBranchingStrategy strategy = _strategyProvider.GetStrategy(Options.LesserBranchesRegex);

            IBranch[]          allBranches       = repositoryData.Branches.GetFor(remoteToUse).ToArray();
            IBranchesKnowledge branchesKnowledge = strategy.CreateKnowledge(allBranches);

            // Options for building the tree.
            ITagPickingOptions tagPickingOptions = TagPickingOptions.Set(
                Options.TagPickingMode,
                Options.TagCount,
                Options.IncludeOrphanedTags);
            IBranchPickingOptions branchPickingOptions = BranchPickingOptions.Set(
                Options.IncludeBranchesRegices,
                Options.ExcludeBranchesRegices);

            ITree tree = _treeBuilder.Build(
                repositoryData,
                remoteToUse,
                branchesKnowledge,
                branchPickingOptions,
                tagPickingOptions);

            SimplifyTree(tree);

            string tempPath = _fileSystem.Path.GetTempFileName();

            tempPath = _fileSystem.Path.ChangeExtension(tempPath, "gv");

            // Rendering options.
            TreeRenderingOptions renderingOptions = TreeRenderingOptions.Default;

            renderingOptions.ForceTreatAsGitHub = Options.ForceTreatAsGitHub;

            // ReSharper disable once AssignNullToNotNullAttribute
            using (IFileStream fileStream = _fileSystem.File.OpenWrite(tempPath))
            {
                using (IStreamWriter textWriter = _textWriterFactory.CreateStreamWriter(fileStream))
                {
                    IGraphVizWriter graphVizWriter = _graphVizFactory.CreateGraphVizWriter(textWriter);

                    ITreeRenderer treeRenderer = _treeRendererFactory.CreateRenderer(graphVizWriter);
                    treeRenderer.Render(tree, remoteToUse, branchesKnowledge, renderingOptions);
                }
            }

            string targetPath = PrepareTargetPath();

            string graphVizCommand = _appPathProvider.GetProperAppPath(ExternalApp.GraphViz);
            string graphVizArgs    = $@"""{tempPath}"" -T{_outputFormat} -o""{targetPath}""";

            Log.Debug($"Starting GraphViz with arguments: [{graphVizArgs}].");
            int code = _processRunner.Execute(graphVizCommand, graphVizArgs);

            if (code != 0)
            {
                Log.Fatal("GraphViz execution failed.");
            }
            else
            {
                Log.Info("GraphViz execution succeeded.");
                Log.Info($"Saved to {targetPath}.");
            }
        }
Exemplo n.º 4
0
        public IBranchesKnowledge CreateKnowledge(IEnumerable <IBranch> branches)
        {
            IBranchesKnowledge branchesKnowledge = _knowledgeMaker(this, _workItemRegex, _colorsAndRegices, branches);

            return(branchesKnowledge);
        }
Exemplo n.º 5
0
        public void Render(
            ITree tree,
            IRemote usedRemote,
            IBranchesKnowledge branchesKnowledge,
            ITreeRenderingOptions options)
        {
            IRemoteWebUrlProvider remoteUrlProvider =
                _remoteWebUrlProviderFactory.CreateUrlProvider(usedRemote.Url, options.ForceTreatAsGitHub);

            WriteHeader();

            IBranch[] branchesWithNodes     = tree.Branches.Where(b => tree.EnumerateNodes(b).Any()).ToArray();
            IBranch[] currentBranchesSorted = OrderByFirstCommitDate(branchesWithNodes, tree).ToArray();

            IPairList <INode, INode> unwrittenMerges = new PairList <INode, INode>();
            IPairList <INode, INode> writtenMerges   = new PairList <INode, INode>();

            // Main branches.
            foreach (IBranch b in currentBranchesSorted)
            {
                _gvWriter.EmptyLine();
                _gvWriter.Comment($"Branch {b.Label}.");

                using (_gvWriter.StartSubGraph())
                {
                    _gvWriter.SetNodeAttributes(AttrSet.Empty.Group(b.Label));

                    Color drawColor = branchesKnowledge.GetSuggestedDrawingColorFor(b);
                    bool  isLesser  = branchesKnowledge.IsAWorkItemBranch(b);

                    IAttrSet nodeStyle = _style.GetBranchNodeStyle(drawColor, isLesser);
                    IAttrSet edgeStyle = _style.GetBranchEdgeStyle(drawColor, isLesser);

                    _gvWriter.SetNodeAttributes(nodeStyle);
                    _gvWriter.SetEdgeAttributes(edgeStyle);

                    INode[] nodes = tree.EnumerateNodes(b).ToArray();

                    for (int i = 0; i < nodes.Length; i++)
                    {
                        INode currentNode = nodes[i];

                        WriteNode(currentNode, remoteUrlProvider);

                        if (i == 0)
                        {
                            // Starting node.
                            INode parent    = currentNode.Parents.FirstOrDefault();
                            bool  hasParent = parent != null;
                            if (!hasParent)
                            {
                                _gvWriter.Comment("Starting line.");
                                string id = string.Format($"{currentNode.Commit.Treeish}_start");
                                // Write starting empty node.
                                using (_gvWriter.StartSubGraph())
                                {
                                    _gvWriter.RawAttributes(AttrSet.Empty.Rank(RankType.Source));

                                    _gvWriter.Node(id, AttrSet.Empty.Width(0).Height(0).PenWidth(0));
                                }

                                _gvWriter.Edge(id, currentNode.Commit, _style.EdgeBranchStartVirtual);
                                _gvWriter.EmptyLine();
                            }
                            else
                            {
                                // It is some other branch, and we draw that edge.
                                WriteEdge(parent, currentNode, remoteUrlProvider);
                                writtenMerges.Add(parent, currentNode);
                            }
                        }

                        bool  isLast   = i == nodes.Length - 1;
                        INode nextNode = isLast ? null : nodes[i + 1];

                        if (!isLast)
                        {
                            // Edge to the next node.
                            WriteEdge(currentNode, nextNode, remoteUrlProvider);
                        }
                        else
                        {
                            WriteBranchPointer(b, tree, isLesser, remoteUrlProvider);
                        }

                        INode[] otherChildren = currentNode.Children.Except(nextNode).ToArray();
                        foreach (INode child in otherChildren)
                        {
                            unwrittenMerges.Add(currentNode, child);
                        }
                    }
                }
            }

            IBranch[] branchesWithoutNodes = tree.Branches.Except(branchesWithNodes).ToArray();
            foreach (IBranch b in branchesWithoutNodes)
            {
                bool isLesser = branchesKnowledge.IsAWorkItemBranch(b);
                WriteBranchPointer(b, tree, isLesser, remoteUrlProvider);
            }

            // Tags.
            ITag[] tags = tree.Tags.ToArray();
            foreach (ITag t in tags)
            {
                _gvWriter.EmptyLine();

                INode  n  = tree.GetNode(t.Tip);
                string id = MakeNodeIdForPointerLabel(n, t);

                using (_gvWriter.StartSubGraph())
                {
                    _gvWriter.Comment($"Tag {t.Label}.");
                    _gvWriter.RawAttributes(AttrSet.Empty.Rank(RankType.Same));

                    string url = remoteUrlProvider?.GetTagLink(t);

                    _gvWriter.Node(id, _style.LabelTag.Label(t.Label).Url(url));

                    _gvWriter.Edge(n.Commit, id, _style.EdgeTagLabel);
                }
            }

            INode[] allLeftOvers = tree.Nodes.Where(n => tree.GetContainingBranch(n) == null).ToArray();
            if (allLeftOvers.Length > 0)
            {
                using (_gvWriter.StartSubGraph())
                {
                    _gvWriter.EmptyLine();
                    _gvWriter.Comment("Leftover nodes.");
                    _gvWriter.SetNodeAttributes(_style.NodeOrphaned);

                    foreach (INode currentNode in allLeftOvers)
                    {
                        WriteNode(currentNode, remoteUrlProvider);
                        // Remember children.
                        foreach (INode child in currentNode.Children)
                        {
                            unwrittenMerges.Add(currentNode, child);
                        }
                    }
                }
            }

            PairList <INode, INode> edgesToWrite = unwrittenMerges.Except(writtenMerges).ToPairList();

            if (edgesToWrite.Count > 0)
            {
                using (_gvWriter.StartSubGraph())
                {
                    _gvWriter.EmptyLine();
                    _gvWriter.Comment("Other edges.");
                    _gvWriter.SetEdgeAttributes(_style.EdgeOther);

                    foreach (Tuple <INode, INode> edge in edgesToWrite)
                    {
                        _gvWriter.Edge(edge.Item1.Commit, edge.Item2.Commit);
                    }
                }
            }

            WriteFooter();
        }