Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 public string GetDescription(TaskTimeItem taskTimeItem, bool addCommentsToWorklog, Settings settings)
 {
     return(addCommentsToWorklog ? taskTimeItem.Description : "");
 }
Пример #4
0
        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);
        }
Пример #5
0
        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());
        }
Пример #6
0
        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);
        }