示例#1
0
        private void UpdateSubmodules(GitCommit buildRepoCommit, GitTree buildRepoTree, bool rewriteGitModules)
        {
            // copy most items from the existing commit tree
            const string gitModulesPath = ".gitmodules";
            List<GitTreeItem> treeItems = buildRepoTree.Items
                .Where(x => (x.Type != "commit" && x.Type != "blob") || (x.Type == "blob" && (!rewriteGitModules || x.Path != gitModulesPath))).ToList();

            // add all the submodules
            treeItems.AddRange(m_submodules.Select(x => new GitTreeItem
            {
                Mode = "160000",
                Path = x.Key,
                Sha = x.Value.LatestCommitId,
                Type = "commit",
            }));

            if (rewriteGitModules)
            {
                // create the contents of the .gitmodules file
                string gitModules;
                using (StringWriter sw = new StringWriter { NewLine = "\n" })
                {
                    foreach (var pair in m_submodules.OrderBy(x => x.Key, StringComparer.Ordinal))
                    {
                        sw.WriteLine("[submodule \"{0}\"]", pair.Key);
                        sw.WriteLine("\tpath = {0}", pair.Key);
                        sw.WriteLine("\turl = {0}", pair.Value.Url);
                    }
                    gitModules = sw.ToString();
                }

                // create the blob
                GitBlob gitModulesBlob = CreateBlob(gitModules);
                treeItems.Add(new GitTreeItem
                {
                    Mode = "100644",
                    Path = gitModulesPath,
                    Sha = gitModulesBlob.Sha,
                    Type = "blob",
                });
            }

            const string commitMessage = "Update submodules to match Leeroy configuration.";
            GitCommit newCommit = CreateNewCommit(buildRepoCommit, null, treeItems, commitMessage);
            Log.Info("Created new commit for synced submodules: {0}; moving branch.", newCommit.Sha);

            // advance the branch pointer to the new commit
            if (TryAdvanceBranch(newCommit.Sha))
            {
                Log.Info("Build repo updated successfully to commit {0}.", newCommit.Sha);
                m_lastBuildCommitId = newCommit.Sha;
            }
        }
示例#2
0
        private string ReadGitModulesBlob(GitTree tree)
        {
            GitTreeItem gitModulesItem = tree.Items.FirstOrDefault(x => x.Type == "blob" && x.Path == ".gitmodules");
            if (gitModulesItem == null)
                return null;

            GitBlob gitModulesBlob = m_gitHubClient.GetBlob(gitModulesItem);
            return gitModulesBlob.GetContent();
        }
示例#3
0
        // Loads the desired list of submodules from the configuration file.
        private void SyncSubmodules(GitCommit buildRepoCommit, GitTree buildRepoTree)
        {
            ReadSubmodulesFromConfig();

            // find submodules that should be present in the build repo, but aren't
            bool updateSubmodules = false;
            foreach (KeyValuePair<string, Submodule> pair in m_submodules)
            {
                string path = pair.Key;
                Submodule submodule = pair.Value;

                GitTreeItem submoduleItem = buildRepoTree.Items.FirstOrDefault(x => x.Type == "commit" && x.Mode == "160000" && x.Path == path);
                if (submoduleItem != null)
                {
                    submodule.LatestCommitId = submoduleItem.Sha;
                }
                else
                {
                    submodule.LatestCommitId = m_gitHubClient.GetLatestCommitId(submodule.User, submodule.Repo, submodule.Branch);
                    if (submodule.LatestCommitId == null)
                        throw new WatcherException("Submodule '{0}' doesn't have a latest commit for branch '{1}'; will stop monitoring project.".FormatInvariant(pair.Key, submodule.Branch));
                    Log.Info("Submodule at path '{0}' is missing; it will be added.", pair.Key);
                    updateSubmodules = true;
                }
            }

            // find extra submodules that aren't in the configuration file
            List<string> extraSubmodulePaths = buildRepoTree.Items
                .Where(x => x.Type == "commit" && x.Mode == "160000" && !m_submodules.ContainsKey(x.Path))
                .Select(x => x.Path)
                .ToList();
            if (extraSubmodulePaths.Count != 0)
            {
                Log.Info("Extra submodule paths: {0}".FormatInvariant(string.Join(", ", extraSubmodulePaths)));
                updateSubmodules = true;
            }

            // determine if .gitmodules needs to be updated
            bool rewriteGitModules = false;
            string gitModulesBlob = ReadGitModulesBlob(buildRepoTree);
            using (StringReader reader = new StringReader(gitModulesBlob ?? ""))
            {
                var existingGitModules = ParseConfigFile(reader)
                    .Where(x => x.Key.StartsWith("submodule ", StringComparison.Ordinal))
                    .Select(x => new { Path = x.Value["path"], Url = x.Value["url"] })
                    .OrderBy(x => x.Path, StringComparer.Ordinal)
                    .ToList();
                var desiredGitModules = m_submodules.Select(x => new { Path = x.Key, x.Value.Url }).OrderBy(x => x.Path, StringComparer.Ordinal).ToList();

                if (!existingGitModules.SequenceEqual(desiredGitModules))
                {
                    Log.Info(".gitmodules needs to be updated.");
                    rewriteGitModules = true;
                }
            }

            if (updateSubmodules || rewriteGitModules)
                UpdateSubmodules(buildRepoCommit, buildRepoTree, rewriteGitModules);
        }
示例#4
0
        private void LoadSubmodules(GitTree buildRepoTree)
        {
            string gitModulesBlob = ReadGitModulesBlob(buildRepoTree);
            if (gitModulesBlob == null)
            {
                Log.Error("Tree {0} doesn't contain a .gitmodules file.", buildRepoTree.Sha);
                return;
            }

            using (StringReader reader = new StringReader(gitModulesBlob))
            {
                foreach (var submodule in ParseConfigFile(reader).Where(x => x.Key.StartsWith("submodule ", StringComparison.Ordinal)))
                {
                    // get submodule details
                    string path = submodule.Value["path"];
                    string url = submodule.Value["url"];
                    string server, user, repo;

                    if (!SplitRepoUrl(url, out server, out user, out repo))
                    {
                        Log.Error("{0} is not a valid Git URL".FormatInvariant(url));
                        continue;
                    }

                    // find submodule in repo, and add it to list of tracked submodules
                    GitTreeItem submoduleItem = buildRepoTree.Items.FirstOrDefault(x => x.Type == "commit" && x.Mode == "160000" && x.Path == path);
                    if (submoduleItem == null)
                    {
                        Log.Warn(".gitmodules contains [{0}] but there is no submodule at path '{1}'.", submodule.Key, path);
                    }
                    else
                    {
                        // use specified branch; else default to tracking the build repo's branch
                        string branch;
                        if (m_project.SubmoduleBranches == null || !m_project.SubmoduleBranches.TryGetValue(path, out branch))
                            branch = m_branch;

                        Log.Info("Adding new submodule: '{0}' = '{1}'.", path, url);
                        m_submodules.Add(path, new Submodule { Url = url, User = user, Repo = repo, Branch = branch, LatestCommitId = submoduleItem.Sha });
                    }
                }
            }
        }