Beispiel #1
0
        public static async Task <Readme> GetReadme(GitHubClient client, string url)
        {
            SubmoduleInfo info = ParseURL(url);

            var readme = await client.Repository.Content.GetReadme(info.Name, info.Owner);

            return(readme);
        }
            public SubmoduleNode(Tree tree, SubmoduleInfo submoduleInfo, bool isCurrent, string localPath, string superPath)
                : base(tree)
            {
                Info      = submoduleInfo;
                IsCurrent = isCurrent;
                LocalPath = localPath;
                SuperPath = superPath;

                // Extract submodule name and branch
                // e.g. Info.Text = "Externals/conemu-inside [no branch]"
                // Note that the branch portion won't be there if the user hasn't yet init'd + updated the submodule.
                var pathAndBranch = Info.Text.Split(new char[] { ' ' }, 2);

                Trace.Assert(pathAndBranch.Length >= 1);
                SubmoduleName = pathAndBranch[0].SubstringAfterLast('/'); // Remove path
                BranchText    = pathAndBranch.Length == 2 ? " " + pathAndBranch[1] : "";
            }
Beispiel #3
0
        public static SubmoduleInfo ParseURL(string url)
        {
            string str = url;

            if (url.EndsWith(".git"))
            {
                str = url.Substring(0, url.Length - 4);
            }

            var strings = str.Split('/');

            SubmoduleInfo info = new SubmoduleInfo();

            if (strings.Length >= 3)
            {
                info.Name  = strings[strings.Length - 1].Trim();
                info.Owner = strings[strings.Length - 2].Trim();
            }

            return(info);
        }
Beispiel #4
0
        private void UpdateSubmodulesList()
        {
            _previousUpdateTime = DateTime.Now;

            // Cancel any previous async activities:
            _submodulesStatusCTS.Cancel();
            _submodulesStatusCTS.Dispose();
            _submodulesStatusCTS = new CancellationTokenSource();

            RemoveSubmoduleButtons();
            toolStripButtonLevelUp.DropDownItems.Add(_loading.Text);

            // Start gathering new submodule information asynchronously.  This makes a significant difference in UI
            // responsiveness if there are numerous submodules (e.g. > 100).
            var cancelToken = _submodulesStatusCTS.Token;
            string thisModuleDir = Module.WorkingDir;
            // First task: Gather list of submodules on a background thread.
            var updateTask = Task.Factory.StartNew(() =>
            {
                // Don't access Module directly because it's not thread-safe.  Use a thread-local version:
                GitModule threadModule = new GitModule(thisModuleDir);
                SubmoduleInfoResult result = new SubmoduleInfoResult();

                // Add all submodules inside the current repository:
                foreach (var submodule in threadModule.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName))
                {
                    cancelToken.ThrowIfCancellationRequested();
                    var name = submodule;
                    string path = threadModule.GetSubmoduleFullPath(submodule);
                    if (Settings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                        name = name + " " + GetModuleBranch(path);

                    var smi = new SubmoduleInfo { Text = name, Path = path };
                    result.OurSubmodules.Add(smi);
                    GetSubmoduleStatusAsync(smi, cancelToken);
                }

                if (threadModule.SuperprojectModule != null)
                {
                    GitModule supersuperproject = threadModule.FindTopProjectModule();
                    if (threadModule.SuperprojectModule.WorkingDir != supersuperproject.WorkingDir)
                    {
                        var name = Path.GetFileName(Path.GetDirectoryName(supersuperproject.WorkingDir));
                        string path = supersuperproject.WorkingDir;
                        if (Settings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                            name = name + " " + GetModuleBranch(path);

                        result.TopProject = new SubmoduleInfo { Text = name, Path = supersuperproject.WorkingDir };
                        GetSubmoduleStatusAsync(result.TopProject, cancelToken);
                    }

                    {
                        string name;
                        GitModule parentModule = threadModule.SuperprojectModule;
                        string localpath = "";
                        if (threadModule.SuperprojectModule.WorkingDir != supersuperproject.WorkingDir)
                        {
                            parentModule = supersuperproject;
                            localpath = threadModule.SuperprojectModule.WorkingDir.Substring(supersuperproject.WorkingDir.Length);
                            localpath = PathUtil.GetDirectoryName(localpath.ToPosixPath());
                            name = localpath;
                        }
                        else
                            name = Path.GetFileName(Path.GetDirectoryName(supersuperproject.WorkingDir));
                        string path = threadModule.SuperprojectModule.WorkingDir;
                        if (Settings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                            name = name + " " + GetModuleBranch(path);

                        result.Superproject = new SubmoduleInfo { Text = name, Path = threadModule.SuperprojectModule.WorkingDir };
                        GetSubmoduleStatusAsync(result.Superproject, cancelToken);
                    }

                    var submodules = supersuperproject.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName);
                    if (submodules.Any())
                    {
                        string localpath = threadModule.WorkingDir.Substring(supersuperproject.WorkingDir.Length);
                        localpath = PathUtil.GetDirectoryName(localpath.ToPosixPath());

                        foreach (var submodule in submodules)
                        {
                            cancelToken.ThrowIfCancellationRequested();
                            var name = submodule;
                            string path = supersuperproject.GetSubmoduleFullPath(submodule);
                            if (Settings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                                name = name + " " + GetModuleBranch(path);
                            bool bold = false;
                            if (submodule == localpath)
                            {
                                result.CurrentSubmoduleName = threadModule.GetCurrentSubmoduleLocalPath();
                                bold = true;
                            }
                            var smi = new SubmoduleInfo { Text = name, Path = path, Bold = bold };
                            result.SuperSubmodules.Add(smi);
                            GetSubmoduleStatusAsync(smi, cancelToken);
                        }
                    }
                }
                return result;
            }, cancelToken);

            // Second task: Populate toolbar menu on UI thread.  Note further tasks are created by
            // CreateSubmoduleMenuItem to update images with submodule status.
            updateTask.ContinueWith((task) =>
            {
                if (task.Result == null)
                    return;

                RemoveSubmoduleButtons();
                var newItems = new List<ToolStripItem>();

                task.Result.OurSubmodules.ForEach(submodule => newItems.Add(CreateSubmoduleMenuItem(submodule)));
                if (task.Result.OurSubmodules.Count == 0)
                    newItems.Add(new ToolStripMenuItem(_noSubmodulesPresent.Text));

                if (task.Result.Superproject != null)
                {
                    newItems.Add(new ToolStripSeparator());
                    if (task.Result.TopProject != null)
                        newItems.Add(CreateSubmoduleMenuItem(task.Result.TopProject, _topProjectModuleFormat.Text));
                    newItems.Add(CreateSubmoduleMenuItem(task.Result.Superproject, _superprojectModuleFormat.Text));
                    task.Result.SuperSubmodules.ForEach(submodule => newItems.Add(CreateSubmoduleMenuItem(submodule)));
                }

                newItems.Add(new ToolStripSeparator());

                var mi = new ToolStripMenuItem(updateAllSubmodulesToolStripMenuItem.Text);
                mi.Click += UpdateAllSubmodulesToolStripMenuItemClick;
                newItems.Add(mi);

                if (task.Result.CurrentSubmoduleName != null)
                {
                    var usmi = new ToolStripMenuItem(_updateCurrentSubmodule.Text);
                    usmi.Tag = task.Result.CurrentSubmoduleName;
                    usmi.Click += UpdateSubmoduleToolStripMenuItemClick;
                    newItems.Add(usmi);
                }

                // Using AddRange is critical: if you used Add to add menu items one at a
                // time, performance would be extremely slow with many submodules (> 100).
                toolStripButtonLevelUp.DropDownItems.AddRange(newItems.ToArray());

                _previousUpdateTime = DateTime.Now;
            },
                cancelToken,
                TaskContinuationOptions.OnlyOnRanToCompletion,
                TaskScheduler.FromCurrentSynchronizationContext());
        }
Beispiel #5
0
        private static void GetSubmoduleStatusAsync(SubmoduleInfo info, CancellationToken cancelToken)
        {
            Task.Factory.StartNew(() =>
            {
                var submodule = new GitModule(info.Path);
                var supermodule = submodule.SuperprojectModule;
                var submoduleName = submodule.GetCurrentSubmoduleLocalPath();

                info.Status = null;

                if (String.IsNullOrEmpty(submoduleName) || supermodule == null)
                    return;

                var submoduleStatus = GitCommandHelpers.GetCurrentSubmoduleChanges(supermodule, submoduleName);
                if (submoduleStatus != null && submoduleStatus.Commit != submoduleStatus.OldCommit)
                {
                    submoduleStatus.CheckSubmoduleStatus(submoduleStatus.GetSubmodule(supermodule));
                }
                if (submoduleStatus != null)
                {
                    info.Status = submoduleStatus.Status;
                    info.IsDirty = submoduleStatus.IsDirty;
                    info.Text += submoduleStatus.AddedAndRemovedString();
                }
            }, cancelToken, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
        }
Beispiel #6
0
        private static Image GetItemImage(SubmoduleInfo info)
        {
            if (info.Status == null)
                return Resources.IconFolderSubmodule;
            if (info.Status == SubmoduleStatus.FastForward)
                return info.IsDirty ? Resources.IconSubmoduleRevisionUpDirty : Resources.IconSubmoduleRevisionUp;
            if (info.Status == SubmoduleStatus.Rewind)
                return info.IsDirty ? Resources.IconSubmoduleRevisionDownDirty : Resources.IconSubmoduleRevisionDown;
            if (info.Status == SubmoduleStatus.NewerTime)
                return info.IsDirty ? Resources.IconSubmoduleRevisionSemiUpDirty : Resources.IconSubmoduleRevisionSemiUp;
            if (info.Status == SubmoduleStatus.OlderTime)
                return info.IsDirty ? Resources.IconSubmoduleRevisionSemiDownDirty : Resources.IconSubmoduleRevisionSemiDown;

            return info.IsDirty ? Resources.IconSubmoduleDirty : Resources.Modified;
        }
Beispiel #7
0
 private ToolStripMenuItem CreateSubmoduleMenuItem(SubmoduleInfo info)
 {
     return CreateSubmoduleMenuItem(info, "{0}");
 }
Beispiel #8
0
 private ToolStripMenuItem CreateSubmoduleMenuItem(SubmoduleInfo info, string textFormat)
 {
     var spmenu = new ToolStripMenuItem(string.Format(textFormat, info.Text));
     spmenu.Click += SubmoduleToolStripButtonClick;
     spmenu.Width = 200;
     spmenu.Tag = info.Path;
     if (info.Bold)
         spmenu.Font = new Font(spmenu.Font, FontStyle.Bold);
     spmenu.Image = GetItemImage(info);
     return spmenu;
 }
            private void AddNodesToTree(
                ref Nodes nodes,
                List <SubmoduleNode> submoduleNodes,
                GitModule threadModule,
                SubmoduleInfo topProject)
            {
                if (!UseFolderTree)
                {
                    nodes.AddNodes(submoduleNodes);
                    return;
                }

                // Create tree of SubmoduleFolderNode for each path directory and add input SubmoduleNodes as leaves.

                // Example of (SuperPath + LocalPath).ToPosixPath() for all nodes:
                //
                // C:/code/gitextensions2/Externals/conemu-inside
                // C:/code/gitextensions2/Externals/Git.hub
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/conemu-inside
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/Git.hub
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/ICSharpCode.TextEditor
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/Externals/NBug
                // C:/code/gitextensions2/Externals/ICSharpCode.TextEditor/gitextensions/GitExtensionsDoc
                // C:/code/gitextensions2/Externals/NBug
                // C:/code/gitextensions2/GitExtensionsDoc
                //
                // What we want to do is first remove the topModule portion, "C:/code/gitextensions2/", and
                // then build our tree by breaking up each path into parts, separated by '/'.
                //
                // Note that when we break up the paths, some parts are just directories, the others are submodule nodes:
                //
                // Externals / ICSharpCode.TextEditor / gitextensions / Externals / Git.hub
                //  folder          submodule             submodule      folder     submodule
                //
                // Input 'nodes' is an array of SubmoduleNodes for all the submodules; now we need to create SubmoduleFolderNodes
                // and insert everything into a tree.

                var topModule = threadModule.GetTopModule();

                // Build a mapping of top-module-relative path to node
                var pathToNodes = new Dictionary <string, Node>();

                // Add existing SubmoduleNodes
                foreach (var node in submoduleNodes)
                {
                    pathToNodes[GetNodeRelativePath(topModule, node)] = node;
                }

                // Create and add missing SubmoduleFolderNodes
                foreach (var node in submoduleNodes)
                {
                    var parts = GetNodeRelativePath(topModule, node).Split('/');
                    for (int i = 0; i < parts.Length - 1; ++i)
                    {
                        var path = string.Join("/", parts.Take(i + 1));
                        if (!pathToNodes.ContainsKey(path))
                        {
                            pathToNodes[path] = new SubmoduleFolderNode(this, parts[i]);
                        }
                    }
                }

                // Now build the tree
                var rootNode    = new DummyNode();
                var nodesInTree = new HashSet <Node>();

                foreach (var node in submoduleNodes)
                {
                    Node parentNode = rootNode;
                    var  parts      = GetNodeRelativePath(topModule, node).Split('/');
                    for (int i = 0; i < parts.Length; ++i)
                    {
                        var path      = string.Join("/", parts.Take(i + 1));
                        var nodeToAdd = pathToNodes[path];

                        // If node is not already in the tree, add it
                        if (!nodesInTree.Contains(nodeToAdd))
                        {
                            parentNode.Nodes.AddNode(nodeToAdd);
                            nodesInTree.Add(nodeToAdd);
                        }

                        parentNode = nodeToAdd;
                    }
                }

                // Add top-module node, and move children of root to it
                var topModuleNode = new SubmoduleNode(this, topProject, topProject.Bold, "", topProject.Path);

                topModuleNode.Nodes.AddNodes(rootNode.Nodes);
                nodes.AddNode(topModuleNode);
            }