From 64723248a570670d7d4ef1709232752d6c13da8b Mon Sep 17 00:00:00 2001 From: Danil Kislov Date: Fri, 13 Sep 2019 10:33:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=BC=D0=B8=D0=BD=D0=B8=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=D0=B8=20=D0=BF=D0=BE=20=D0=96=D0=B8=D1=80=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .semver.txt | 2 +- src/JiraTimeBot/DI/ContainerBuilder.cs | 2 + src/JiraTimeBot/JiraIntegration/JiraApi.cs | 12 +++- .../JiraIntegration/JiraCommitEmulator.cs | 2 + .../JiraIntegration/JiraHistory.cs | 65 +++++++++++++++++++ src/JiraTimeBot/JiraTimeBot.csproj | 1 + src/JiraTimeBot/Job.cs | 14 +++- .../Mercurial/IAllMercurialProviders.cs | 1 + src/JiraTimeBot/Mercurial/MercurialLog.cs | 4 +- src/JiraTimeBot/Properties/AssemblyInfo.cs | 62 +++++++++--------- .../TaskTime/Objects/TaskTimeItem.cs | 4 +- .../TaskTime/TaskTimeByCommitsCalculator.cs | 1 + src/JiraTimeBot/TaskTime/TaskTimeSpread.cs | 7 +- 13 files changed, 135 insertions(+), 42 deletions(-) create mode 100644 src/JiraTimeBot/JiraIntegration/JiraHistory.cs diff --git a/.semver.txt b/.semver.txt index e1d2f8b..7b8d6b7 100644 --- a/.semver.txt +++ b/.semver.txt @@ -1 +1 @@ -1.0.64 +1.0.65 diff --git a/src/JiraTimeBot/DI/ContainerBuilder.cs b/src/JiraTimeBot/DI/ContainerBuilder.cs index bf27074..3686d0b 100644 --- a/src/JiraTimeBot/DI/ContainerBuilder.cs +++ b/src/JiraTimeBot/DI/ContainerBuilder.cs @@ -56,6 +56,8 @@ namespace JiraTimeBot.DI _builder.RegisterType().AsSelf().As(); _builder.RegisterType().AsSelf().AsImplementedInterfaces(); + + _builder.RegisterType().AsSelf().As(); _builder.Register(c => new Job(c.Resolve(), c.Resolve(), c.Resolve())).AsSelf(); diff --git a/src/JiraTimeBot/JiraIntegration/JiraApi.cs b/src/JiraTimeBot/JiraIntegration/JiraApi.cs index 6e41b71..e279e1f 100644 --- a/src/JiraTimeBot/JiraIntegration/JiraApi.cs +++ b/src/JiraTimeBot/JiraIntegration/JiraApi.cs @@ -9,7 +9,15 @@ using JiraTimeBot.TaskTime.Objects; namespace JiraTimeBot.JiraIntegration { - public class JiraApi + public interface IJiraApi + { + List GetIssuesByJQL(string jql, Settings settings, DateTime? date = null, CancellationToken cancellationToken = default); + string GetTaskName(string branch, Settings settings); + List GetWorkloggedIssuesByDate(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default); + void SetTodayWorklog(List taskTimeItems, Settings settings, DateTime? date = null, bool dummy = false, bool addCommentsToWorklog = false, CancellationToken cancellationToken = default); + } + + public class JiraApi : IJiraApi { private readonly ILog _log; private readonly IJiraDescriptionSource _descriptionSource; @@ -68,7 +76,7 @@ namespace JiraTimeBot.JiraIntegration return GetIssuesByJQL(jql, settings, date, cancellationToken); } - private void RemoveWorklogsAddedByUser(List taskTimeItems, Settings settings, DateTime? date = null, bool dummy = false, CancellationToken cancellationToken = default(CancellationToken)) + private void RemoveWorklogsAddedByUser(List taskTimeItems, Settings settings, DateTime? date = null, bool dummy = false, CancellationToken cancellationToken = default(CancellationToken)) { var alreadyLoggedToday = GetWorkloggedIssuesByDate(settings, date); foreach (var issue in alreadyLoggedToday) diff --git a/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs b/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs index 32e6b02..068b77c 100644 --- a/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs +++ b/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs @@ -53,6 +53,7 @@ namespace JiraTimeBot.JiraIntegration TimeSpan.Zero, 1, 1, + "", CommitType.Task); workTasks.Add(item); } @@ -66,6 +67,7 @@ namespace JiraTimeBot.JiraIntegration TimeSpan.Zero, 1, 1, + "", CommitType.Task); workTasks.Add(item); } diff --git a/src/JiraTimeBot/JiraIntegration/JiraHistory.cs b/src/JiraTimeBot/JiraIntegration/JiraHistory.cs new file mode 100644 index 0000000..4b73a0a --- /dev/null +++ b/src/JiraTimeBot/JiraIntegration/JiraHistory.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using JiraTimeBot.Configuration; +using JiraTimeBot.TaskTime.Objects; + +namespace JiraTimeBot.JiraIntegration +{ + public interface IJiraHistory + { + List GetDayWorklogs(DateTime date, + Settings settings, + CancellationToken cancellationToken = default(CancellationToken)); + } + + public class JiraHistory: IJiraHistory + { + private readonly IJiraApi _jiraApi; + + public JiraHistory(IJiraApi jiraApi) + { + _jiraApi = jiraApi; + } + + public List GetDayWorklogs(DateTime date, + Settings settings, + CancellationToken cancellationToken = default(CancellationToken)) + { + var tasks = _jiraApi.GetIssuesByJQL("status changed by '%USER%' during (\"%DATE%\",\"%DATE%\")", settings, date, cancellationToken); + List resultItems = new List(); + foreach (var issue in tasks) + { + var workLogs = issue.GetWorklogsAsync(cancellationToken).Result; + var user = settings.JiraUserName; + //user = "Zoya.Aleksandridi"; + var userWorklogs = workLogs.Where(w => + w.CreateDate.GetValueOrDefault().Date == date && w.Author.Equals(user, + StringComparison.InvariantCultureIgnoreCase)).ToList(); + if (!userWorklogs.Any()) + { + continue; + } + + var firstWorklog = userWorklogs.First(); + + var description = string.Join("\r\n", userWorklogs.Select(f => f.Comment).Distinct()); + var totalTime = TimeSpan.FromSeconds(userWorklogs.Sum(f => f.TimeSpentInSeconds)); + var startDate = firstWorklog?.CreateDate ?? date; + var commits = userWorklogs.Sum(f => f.Comment.Count(c => c == '\n')); + var taskType = CommitType.Task; + if (description.Contains("Подготовка и публикация")) + { + taskType = CommitType.Release; + } + + resultItems.Add(new TaskTimeItem(issue.Key.Value, description, issue.Project, startDate, totalTime, commits, 1, "", taskType)); + } + + return resultItems; + } + } +} diff --git a/src/JiraTimeBot/JiraTimeBot.csproj b/src/JiraTimeBot/JiraTimeBot.csproj index 0bc50d7..b048340 100644 --- a/src/JiraTimeBot/JiraTimeBot.csproj +++ b/src/JiraTimeBot/JiraTimeBot.csproj @@ -81,6 +81,7 @@ + diff --git a/src/JiraTimeBot/Job.cs b/src/JiraTimeBot/Job.cs index dfb5832..d288bce 100644 --- a/src/JiraTimeBot/Job.cs +++ b/src/JiraTimeBot/Job.cs @@ -78,8 +78,18 @@ namespace JiraTimeBot _log.Info("Использую Jira как источник информации."); mercurial = _mercurialProviders.JiraCommitEmulator; } - List commits = mercurial.GetMercurialLog(settings, realDate, cancellationToken); - List taskTimes = _taskTimeDiscoverer.CalculateTaskTime(commits, settings, cancellationToken); + + List taskTimes = null; + if (!(tasksProcessor is MeetingProcessor)) + { + List commits = mercurial.GetMercurialLog(settings, realDate, cancellationToken); + taskTimes = _taskTimeDiscoverer.CalculateTaskTime(commits, settings, cancellationToken); + } + else + { + var provider = _mercurialProviders.JiraHistory; + taskTimes = provider.GetDayWorklogs(realDate, settings, cancellationToken); + } if (cancellationToken.IsCancellationRequested) { diff --git a/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs b/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs index 2d8e441..d87cc38 100644 --- a/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs +++ b/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs @@ -6,5 +6,6 @@ namespace JiraTimeBot.Mercurial { MercurialLog MercurialLog { get; } JiraCommitEmulator JiraCommitEmulator { get; } + IJiraHistory JiraHistory { get; } } } diff --git a/src/JiraTimeBot/Mercurial/MercurialLog.cs b/src/JiraTimeBot/Mercurial/MercurialLog.cs index 526e927..dbe1de0 100644 --- a/src/JiraTimeBot/Mercurial/MercurialLog.cs +++ b/src/JiraTimeBot/Mercurial/MercurialLog.cs @@ -80,7 +80,8 @@ namespace JiraTimeBot.Mercurial changeset.Timestamp, TimeSpan.Zero, 1, - changeset.PathActions.Count, + changeset.PathActions.Count, + "", GetCommitType(changeset.Branch)); if (task.Type == CommitType.Release && task.Description.StartsWith("Merge with", StringComparison.CurrentCultureIgnoreCase)) @@ -95,6 +96,7 @@ namespace JiraTimeBot.Mercurial task.Branch = branch; task.Description = $"Подготовка и публикация версии {task.Project} {release}."; + task.ReleaseVersion = release; } workTasks.Add(task); _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}"); diff --git a/src/JiraTimeBot/Properties/AssemblyInfo.cs b/src/JiraTimeBot/Properties/AssemblyInfo.cs index 534c485..6fb7075 100644 --- a/src/JiraTimeBot/Properties/AssemblyInfo.cs +++ b/src/JiraTimeBot/Properties/AssemblyInfo.cs @@ -1,31 +1,31 @@ -using System.Reflection; -using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("JiraTimeBot")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("JiraTimeBot")] -[assembly: AssemblyCopyright("Copyright © 2019")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f3b89316-c38c-4ce6-9d88-0b1373cfba1a")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.64")] -[assembly: AssemblyFileVersion("1.0.64")] -[assembly: AssemblyInformationalVersion("1.0.64")] +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("JiraTimeBot")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("JiraTimeBot")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f3b89316-c38c-4ce6-9d88-0b1373cfba1a")] +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.65")] +[assembly: AssemblyFileVersion("1.0.65")] +[assembly: AssemblyInformationalVersion("1.0.65")] diff --git a/src/JiraTimeBot/TaskTime/Objects/TaskTimeItem.cs b/src/JiraTimeBot/TaskTime/Objects/TaskTimeItem.cs index 75e6035..6ccea34 100644 --- a/src/JiraTimeBot/TaskTime/Objects/TaskTimeItem.cs +++ b/src/JiraTimeBot/TaskTime/Objects/TaskTimeItem.cs @@ -12,9 +12,10 @@ namespace JiraTimeBot.TaskTime.Objects public int FilesAffected { get; set; } public CommitType Type { get; set; } public string Project { get; set; } + public string ReleaseVersion { get; set; } public TaskTimeItem(string branch, string description, string project, DateTime startTime, TimeSpan timeSpent, int commits, - int filesAffected = 1, CommitType type = CommitType.Task) + int filesAffected = 1, string releaseVersion = "", CommitType type = CommitType.Task) { Branch = branch; Description = description; @@ -23,6 +24,7 @@ namespace JiraTimeBot.TaskTime.Objects TimeSpent = timeSpent; StartTime = startTime; FilesAffected = filesAffected; + ReleaseVersion = releaseVersion; Type = type; } diff --git a/src/JiraTimeBot/TaskTime/TaskTimeByCommitsCalculator.cs b/src/JiraTimeBot/TaskTime/TaskTimeByCommitsCalculator.cs index 5d55eb3..3b1bb17 100644 --- a/src/JiraTimeBot/TaskTime/TaskTimeByCommitsCalculator.cs +++ b/src/JiraTimeBot/TaskTime/TaskTimeByCommitsCalculator.cs @@ -99,6 +99,7 @@ namespace JiraTimeBot.TaskTime TimeSpan.FromMinutes(minutes), 1, 1, + "", CommitType.Task); } diff --git a/src/JiraTimeBot/TaskTime/TaskTimeSpread.cs b/src/JiraTimeBot/TaskTime/TaskTimeSpread.cs index 11235bf..9f8e5de 100644 --- a/src/JiraTimeBot/TaskTime/TaskTimeSpread.cs +++ b/src/JiraTimeBot/TaskTime/TaskTimeSpread.cs @@ -19,20 +19,18 @@ namespace JiraTimeBot.TaskTime public List SpreadTime(List source, int minutes, int roundToMinutes, bool roundUp = false, bool appendTime = true) { List newList = new List(); - int remainMinutes = minutes; //Нам нужно раскидать 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); - remainMinutes -= currentTaskTime; var orderedTasks = taskGroup.OrderBy(f => f.StartTime).ToArray(); StringBuilder sb = new StringBuilder(); - foreach (var task in orderedTasks) + foreach (var taskDescription in orderedTasks.Select(f=>f.Description).Distinct()) { - sb.AppendLine($"- {task.Description}"); + sb.AppendLine($"- {taskDescription}"); } var timeSpent = appendTime @@ -48,6 +46,7 @@ namespace JiraTimeBot.TaskTime timeSpent, taskGroup.Sum(f => f.Commits), taskGroup.Sum(f => f.FilesAffected), + taskGroup.First().ReleaseVersion, taskGroup.First().Type); newList.Add(taskTimeItem);