/// <summary>
        /// Executes the task by converting history files into entries in a git project's History.md.
        /// </summary>
        /// <returns><see langword="true"/> if the task successfully executed; otherwise, <see langword="false"/>.</returns>
        public override bool Execute()
        {
            // Start building the string to write to History.md.
            StringBuilder newHistory = new StringBuilder();

            // Connect to the git repo.
            using (Repository repo = new Repository(ProjectFolder))
            {
                // Store the history files to prepare for walking back through history to get their creation dates.
                Dictionary <string, HistoryFileEntry> historyFiles = new Dictionary <string, HistoryFileEntry>();

                // Get the tree from the latest commit in HEAD for the history folder.
                TreeEntry latestHistory = repo.Head.Tip[HistoryFolderRelativePath];

                if (null == latestHistory)
                {
                    this.Log.LogError("Could not find the project's history folder.");
                    return(false);
                }

                if (TreeEntryTargetType.Tree != latestHistory.TargetType)
                {
                    this.Log.LogError("The project's history folder must be a directory.");
                    return(false);
                }

                foreach (TreeEntry childHistoryEntry in ((Tree)latestHistory.Target))
                {
                    // Only consider files and skip the special file.
                    if (TreeEntryTargetType.Blob != childHistoryEntry.TargetType ||
                        childHistoryEntry.Name == SpecialHistoryFileName)
                    {
                        continue;
                    }

                    // Assume that missing files were processed in a previous run.
                    if (!File.Exists(Path.Combine(ProjectFolder, childHistoryEntry.Path)))
                    {
                        Log.LogMessage("Skipping deleted history entry: {0}", childHistoryEntry.Path);
                        continue;
                    }

                    HistoryFileEntry historyFile = new HistoryFileEntry
                    {
                        // Store the contents of the file so it can be added to the StringBuilder once we know how to sort them.
                        CurrentBlob = (Blob)childHistoryEntry.Target,
                        // Store the path so that the file can be deleted from git and the filesystem once we're done.
                        Path = childHistoryEntry.Path,
                    };

                    historyFiles.Add(childHistoryEntry.Path, historyFile);
                }

                if (historyFiles.Count == 0)
                {
                    Log.LogMessage("No history entries found");
                    return(true);
                }

                // Walk through history, looking for added/renamed files.
                // Only look at each commit's first parent to try to stick to the merge commits.
                // Keep track of the number of files that were found to try to avoid going back to the beginning of time.

                int              foundFiles     = 0;
                Commit           commit         = repo.Head.Tip;
                Commit           previousCommit = commit.Parents.FirstOrDefault();
                string[]         targetPaths    = new string[] { HistoryFolderRelativePath };
                HistoryFileEntry value;

                while (previousCommit != null && foundFiles < historyFiles.Count)
                {
                    TreeChanges treeChanges = repo.Diff.Compare <TreeChanges>(previousCommit.Tree, commit.Tree, targetPaths);
                    foreach (TreeEntryChanges treeEntryChange in treeChanges.Added)
                    {
                        if (historyFiles.TryGetValue(treeEntryChange.Path, out value) && !value.CreationTime.HasValue)
                        {
                            value.CreationTime = commit.Committer.When.LocalDateTime;
                            ++foundFiles;
                        }
                    }
                    foreach (TreeEntryChanges treeEntryChange in treeChanges.Renamed)
                    {
                        if (historyFiles.TryGetValue(treeEntryChange.Path, out value) && !value.CreationTime.HasValue)
                        {
                            value.CreationTime = commit.Committer.When.LocalDateTime;
                            ++foundFiles;
                        }
                    }

                    commit         = previousCommit;
                    previousCommit = commit.Parents.FirstOrDefault();
                }

                // Sort in descending order based on CreationTime.
                List <HistoryFileEntry> sortedHistoryFiles = historyFiles.Values.ToList();
                sortedHistoryFiles.Sort((x, y) =>
                {
                    return(DateTime.Compare(y.CreationTime.HasValue ? y.CreationTime.Value : DateTime.Now, x.CreationTime.HasValue ? x.CreationTime.Value : DateTime.Now));
                });

                // Add the contents of each history entry, then delete it.
                foreach (HistoryFileEntry historyFile in sortedHistoryFiles)
                {
                    newHistory.AppendLine(historyFile.CurrentBlob.GetContentText().Trim());
                    newHistory.AppendLine();

                    Log.LogMessage("Processed history entry: {0}", historyFile.Path);
                    repo.Remove(historyFile.Path, true);
                }
            }

            // Add the new entries to the top.
            newHistory.Append(File.ReadAllText(HistoryFile));
            File.WriteAllText(HistoryFile, newHistory.ToString());

            // A different part of the build process stages History.md and does the commit and push.
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Executes the task by converting history files into entries in a git project's History.md.
        /// </summary>
        /// <returns><see langword="true"/> if the task successfully executed; otherwise, <see langword="false"/>.</returns>
        public override bool Execute()
        {
            // Start building the string to write to History.md.
            StringBuilder newHistory = new StringBuilder();

            // Connect to the git repo.
            using (Repository repo = new Repository(ProjectFolder))
            {
                // Store the history files to prepare for walking back through history to get their creation dates.
                Dictionary<string, HistoryFileEntry> historyFiles = new Dictionary<string, HistoryFileEntry>();

                // Get the tree from the latest commit in HEAD for the history folder.
                TreeEntry latestHistory = repo.Head.Tip[HistoryFolderRelativePath];

                if (null == latestHistory)
                {
                    this.Log.LogError("Could not find the project's history folder.");
                    return false;
                }

                if (TreeEntryTargetType.Tree != latestHistory.TargetType)
                {
                    this.Log.LogError("The project's history folder must be a directory.");
                    return false;
                }

                foreach (TreeEntry childHistoryEntry in ((Tree)latestHistory.Target))
                {
                    // Only consider files and skip the special file.
                    if (TreeEntryTargetType.Blob != childHistoryEntry.TargetType ||
                        childHistoryEntry.Name == SpecialHistoryFileName)
                    {
                        continue;
                    }

                    // Assume that missing files were processed in a previous run.
                    if (!File.Exists(Path.Combine(ProjectFolder, childHistoryEntry.Path)))
                    {
                        Log.LogMessage("Skipping deleted history entry: {0}", childHistoryEntry.Path);
                        continue;
                    }

                    HistoryFileEntry historyFile = new HistoryFileEntry
                    {
                        // Store the contents of the file so it can be added to the StringBuilder once we know how to sort them.
                        CurrentBlob = (Blob)childHistoryEntry.Target,
                        // Store the path so that the file can be deleted from git and the filesystem once we're done.
                        Path = childHistoryEntry.Path,
                    };

                    historyFiles.Add(childHistoryEntry.Path, historyFile);
                }

                if (historyFiles.Count == 0)
                {
                    Log.LogMessage("No history entries found");
                    return true;
                }

                // Walk through history, looking for added/renamed files.
                // Only look at each commit's first parent to try to stick to the merge commits.
                // Keep track of the number of files that were found to try to avoid going back to the beginning of time.

                int foundFiles = 0;
                Commit commit = repo.Head.Tip;
                Commit previousCommit = commit.Parents.FirstOrDefault();
                string[] targetPaths = new string[] { HistoryFolderRelativePath };
                HistoryFileEntry value;

                while (previousCommit != null && foundFiles < historyFiles.Count)
                {
                    TreeChanges treeChanges = repo.Diff.Compare<TreeChanges>(previousCommit.Tree, commit.Tree, targetPaths);
                    foreach (TreeEntryChanges treeEntryChange in treeChanges.Added)
                    {
                        if (historyFiles.TryGetValue(treeEntryChange.Path, out value) && !value.CreationTime.HasValue)
                        {
                            value.CreationTime = commit.Committer.When.LocalDateTime;
                            ++foundFiles;
                        }
                    }
                    foreach (TreeEntryChanges treeEntryChange in treeChanges.Renamed)
                    {
                        if (historyFiles.TryGetValue(treeEntryChange.Path, out value) && !value.CreationTime.HasValue)
                        {
                            value.CreationTime = commit.Committer.When.LocalDateTime;
                            ++foundFiles;
                        }
                    }

                    commit = previousCommit;
                    previousCommit = commit.Parents.FirstOrDefault();
                }

                // Sort in descending order based on CreationTime.
                List<HistoryFileEntry> sortedHistoryFiles = historyFiles.Values.ToList();
                sortedHistoryFiles.Sort((x, y) =>
                {
                    return DateTime.Compare(y.CreationTime.HasValue ? y.CreationTime.Value : DateTime.Now, x.CreationTime.HasValue ? x.CreationTime.Value : DateTime.Now);
                });

                // Add the contents of each history entry, then delete it.
                foreach (HistoryFileEntry historyFile in sortedHistoryFiles)
                {
                    newHistory.AppendLine(historyFile.CurrentBlob.GetContentText().Trim());
                    newHistory.AppendLine();

                    Log.LogMessage("Processed history entry: {0}", historyFile.Path);
                    repo.Remove(historyFile.Path, true);
                }
            }

            // Add the new entries to the top.
            newHistory.Append(File.ReadAllText(HistoryFile));
            File.WriteAllText(HistoryFile, newHistory.ToString());

            // A different part of the build process stages History.md and does the commit and push.
            return true;
        }