public List <TaskTimeItem> GetRepositoryLog(Settings settings, string currentRepository, DateTime?date = null, CancellationToken cancellationToken = default(CancellationToken)) { date = date.GetValueOrDefault(DateTime.Now.Date); var workTasks = new List <TaskTimeItem>(); var issues = _jiraApi.GetIssuesByJQL(settings.JiraQuery, settings, date, cancellationToken); foreach (var issue in issues) { if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } var comments = issue.GetCommentsAsync(cancellationToken).Result?.ToList() ?? new List <Comment>(); var user = settings.JiraUserName; //user = "******"; var userComments = comments.Where(f => f.Author.Equals(user, StringComparison.InvariantCultureIgnoreCase)).ToList(); _log.Trace($"Получены комментарии по задаче {issue.Key} ({issue.Type?.Name}): {userComments.Count}."); if (userComments.Any()) { foreach (var comment in userComments.OrderBy(f => f.CreatedDate)) { var item = new TaskTimeItem(issue.Key.Value, issue.Summary, issue.Project, issue.Updated.GetValueOrDefault(date.Value), TimeSpan.Zero, 1, 1, "", CommitType.Task); workTasks.Add(item); } } else { var item = new TaskTimeItem(issue.Key.Value, issue.Summary, issue.Project, issue.Updated.GetValueOrDefault(date.Value), TimeSpan.Zero, 1, 1, "", CommitType.Task); workTasks.Add(item); } } return(workTasks); }
public List <TaskTimeItem> SpreadTime(List <TaskTimeItem> source, int minutes, int roundToMinutes, bool roundUp = false, bool appendTime = true) { List <TaskTimeItem> newList = new List <TaskTimeItem>(); //Нам нужно раскидать 480 минут в день. foreach (var taskGroup in source.GroupBy(f => f.Branch).OrderByDescending(f => f.Count())) { int currentTaskCommits = taskGroup.Count(); int currentTaskTime = (int)RoundTo(minutes / source.Count * currentTaskCommits, roundToMinutes, roundUp); var orderedTasks = taskGroup.OrderBy(f => f.StartTime).ToArray(); StringBuilder sb = new StringBuilder(); foreach (var taskDescription in orderedTasks.Select(f => f.Description).Distinct()) { sb.AppendLine($"- {taskDescription}"); } var timeSpent = appendTime ? TimeSpan.FromMinutes(taskGroup.Sum(f => f.TimeSpent.TotalMinutes)) + TimeSpan.FromMinutes(currentTaskTime) : TimeSpan.FromMinutes(currentTaskTime); var taskTimeItem = new TaskTimeItem( taskGroup.Key, sb.ToString(), taskGroup.First().Project, taskGroup.Min(f => f.StartTime), timeSpent, taskGroup.Sum(f => f.Commits), taskGroup.Sum(f => f.FilesAffected), taskGroup.First().ReleaseVersion, taskGroup.First().Type); newList.Add(taskTimeItem); } return(newList); }
public string GetDescription(TaskTimeItem taskTimeItem, bool addCommentsToWorklog, Settings settings) { return(addCommentsToWorklog ? taskTimeItem.Description : ""); }
public List <TaskTimeItem> GetRepositoryLog(Settings settings, string currentRepository, DateTime?date = null, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(currentRepository) || !Directory.Exists(currentRepository)) { _log.Error("Папка с репо не сушествует."); return(new List <TaskTimeItem>()); } date = date.GetValueOrDefault(DateTime.Now.Date); var workTasks = new List <TaskTimeItem>(); foreach (var repoDirectory in Directory.GetDirectories(currentRepository)) { if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } //var project = new DirectoryInfo(repoDirectory).Name; if (!Directory.Exists(Path.Combine(repoDirectory, ".hg"))) { continue; } var directoryInfo = new DirectoryInfo(repoDirectory); var repo = new Repository(repoDirectory); if (settings.PullBeforeProcess) { try { repo.Pull(); } catch (Exception ex) { _log?.Trace($" - Не получается сделать pull для репозитория: {directoryInfo.Name} - {ex.Message}"); } } var logCommand = new LogCommand { Date = date, Users = { settings.MercurialAuthorEmail }, AdditionalArguments = { "--encoding=utf-8" }, }; try { var log = repo.Log(logCommand); foreach (var changeset in log) { if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } var commitMessage = FixEncoding(changeset.CommitMessage); if (_commitSkipper.IsNeedToSkip(changeset.Branch, commitMessage)) { continue; } commitMessage = _technicalInfoSkipper.StripTechnicalInfo(commitMessage); var task = new TaskTimeItem(changeset.Branch, commitMessage, directoryInfo.Name, changeset.Timestamp, TimeSpan.Zero, 1, changeset.PathActions.Count, "", GetCommitType(changeset.Branch)); if (task.Type == CommitType.Release && task.Description.StartsWith("Merge with", StringComparison.CurrentCultureIgnoreCase)) { var description = task.Description; if (description.Contains("\n")) { description = description.Split('\n')[0]; } var branch = description.Replace("Merge with", "").Replace(" ", ""); var release = task.Branch.Replace("release", ""); task.Branch = branch; task.Description = $"Подготовка и публикация версии {task.Project} {release}."; task.ReleaseVersion = release; } workTasks.Add(task); _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}"); } } catch (Exception e) { MessageBox.Show($"Oops something went wrong in repo {repoDirectory}"); throw; } } if (!workTasks.Any()) { return(new List <TaskTimeItem>()); } return(workTasks); }
public List <TaskTimeItem> CalculateTaskTime(List <TaskTimeItem> commits, Settings settings, CancellationToken cancellationToken = default(CancellationToken)) { int minutesPerWorkDay = settings.MinuterPerWorkDay + GetRandomMinutes(settings); int workHours = (settings.MinuterPerWorkDay / 60); int totalCommitsCount = commits.Count; var taskCommits = commits.Where(f => f.Type == CommitType.Task).ToList(); var releaseCommits = commits.Where(f => f.Type == CommitType.Release).ToList(); if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } if (!commits.Any()) { return(new List <TaskTimeItem>()); } FixTooBigInterval(settings, workHours, totalCommitsCount); int remainMinutes = minutesPerWorkDay; var workTimeItems = new List <TaskTimeItem>(); var timeControlTask = GetTimeControlTask(settings.TimeControlTask); if (timeControlTask != null) { workTimeItems.Add(timeControlTask); remainMinutes -= (int)timeControlTask.TimeSpent.TotalMinutes; } if (releaseCommits.Any()) { var releaseTasks = _spreadHelper.SpreadTime(releaseCommits, 30, 1); workTimeItems.AddRange(releaseTasks); remainMinutes -= releaseTasks.Sum(f => (int)f.TimeSpent.TotalMinutes); } var workTasks = _spreadHelper.SpreadTime(taskCommits, remainMinutes, settings.RoundToMinutes); foreach (var workTask in workTasks) { TaskTimeItem existingItem = workTimeItems.FirstOrDefault(f => f.Branch == workTask.Branch); if (existingItem != null) { existingItem.MergeWith(workTask); continue; } workTimeItems.Add(workTask); } workTimeItems = workTimeItems.OrderByDescending(f => f.TimeSpent).ToList(); remainMinutes = minutesPerWorkDay - (int)workTimeItems.Sum(f => f.TimeSpent.TotalMinutes); if (remainMinutes != 0) { _log.Trace($"Погрешность распределения времени: {remainMinutes}. Добавляю к первой задаче."); } if ((workTimeItems.First().TimeSpent.TotalMinutes > Math.Abs(remainMinutes) && remainMinutes < 0) || remainMinutes > 0) { //если переборщили или не достаточно добавили до 8 часов - скореектируем остаток в первой задаче (она самая трудозатратная). workTimeItems.First().TimeSpent += TimeSpan.FromMinutes(remainMinutes); } PrintTotal(workTimeItems); return(workTimeItems.OrderByDescending(f => f.TimeSpent).ToList()); }
public List <TaskTimeItem> GetRepositoryLog(Settings settings, string currentRepository, DateTime?date = null, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(currentRepository) || !Directory.Exists(currentRepository)) { _log.Error("Папка с репо не сушествует."); return(new List <TaskTimeItem>()); } date = date.GetValueOrDefault(DateTime.Now.Date); var workTasks = new List <TaskTimeItem>(); foreach (var repoDirectory in Directory.GetDirectories(currentRepository, ".git", SearchOption.AllDirectories)) { if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } //var project = new DirectoryInfo(repoDirectory).Name; var repoRootDirectory = repoDirectory.Replace(".git", ""); var directoryInfo = new DirectoryInfo(repoRootDirectory); if (!directoryInfo.Exists) { continue; } var repo = new LibGit2Sharp.Repository(repoRootDirectory); if (settings.PullBeforeProcess) { try { // Credential information to fetch LibGit2Sharp.PullOptions options = new LibGit2Sharp.PullOptions(); options.FetchOptions = new FetchOptions(); // User information to create a merge commit var signature = new LibGit2Sharp.Signature(new Identity("MERGE_USER_NAME", "MERGE_USER_EMAIL"), DateTimeOffset.Now); // Pull Commands.Pull(repo, signature, options); } catch (Exception ex) { _log?.Trace($" - Не получается сделать pull для репозитория: {directoryInfo.Name} - {ex.Message}"); } } var allCommits = new List <Commit>(); var reflog = repo.Refs.Log(repo.Refs.Head); foreach (var reflogItem in reflog) { var dateMatch = date.Value.Date == reflogItem.Committer.When.Date; var committerEmail = reflogItem.Committer.Email; var userMatch = committerEmail.Equals(settings.MercurialAuthorEmail, StringComparison.CurrentCultureIgnoreCase) || committerEmail.Equals(settings.AlternativeEmail, StringComparison.CurrentCultureIgnoreCase); if (!dateMatch || !userMatch) { continue; } var commit = repo.Lookup <LibGit2Sharp.Commit>(reflogItem.To.Sha); if (commit != null && allCommits.All(f => f.Sha != commit.Sha)) { allCommits.Add(commit); } } foreach (Commit commit in allCommits) { if (cancellationToken.IsCancellationRequested) { return(new List <TaskTimeItem>()); } var userMatch = commit.Author.Email.Equals(settings.MercurialAuthorEmail, StringComparison.CurrentCultureIgnoreCase) || commit.Author.Email.Equals(settings.AlternativeEmail, StringComparison.CurrentCultureIgnoreCase); if (commit.Author.When.DateTime.Date != date.Value.Date || !userMatch) { continue; } var regex = new Regex("[a-zA-Z0-9]{1,5}-[0-9]{1,6}"); var branch = ListBranchesContainsCommit(repo, commit.Sha) .Select(f => f.FriendlyName) .FirstOrDefault(f => regex.IsMatch(f)); //.Where(f => f.Contains("-") && !f.Contains("/")).Distinct().FirstOrDefault(); if (branch == null) { continue; } branch = regex.Match(branch).Value; var commitMessage = commit.MessageShort; commitMessage = _technicalInfoSkipper.StripBranchPrefix(branch, commitMessage); if (_commitSkipper.IsNeedToSkip(branch, commitMessage)) { continue; } commitMessage = _technicalInfoSkipper.StripTechnicalInfo(commitMessage); var files = FilesToMerge(commit, repo); var task = new TaskTimeItem(branch, commitMessage, directoryInfo.Name, commit.Committer.When.DateTime, TimeSpan.Zero, 1, files.Length, //changeset.PathActions.Count, "", GetCommitType(branch)); workTasks.Add(task); _log?.Trace($" - Найден commit: {commit.Committer.When.DateTime} - {branch} - {commit.Author.Email} - {commitMessage}"); } } if (!workTasks.Any()) { return(new List <TaskTimeItem>()); } return(workTasks); }