From 90be28873755ca835e045cd39de30654f2eef4c2 Mon Sep 17 00:00:00 2001 From: Danil Kislov Date: Fri, 15 Mar 2019 16:36:45 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B0=D1=81=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JiraTimeBotForm/JiraTimeBotForm.csproj | 2 + JiraTimeBotForm/Job.cs | 14 +- .../Mercurial/MercurialCommitItem.cs | 17 ++ JiraTimeBotForm/Mercurial/MercurialLog.cs | 145 ++++++++++++++++++ .../TaskTime/ITaskTimeDiscoverer.cs | 3 +- .../TaskTime/TaskTimeDiscoverer.cs | 137 ++--------------- JiraTimeBotForm/frmMain.cs | 6 +- 7 files changed, 193 insertions(+), 131 deletions(-) create mode 100644 JiraTimeBotForm/Mercurial/MercurialCommitItem.cs create mode 100644 JiraTimeBotForm/Mercurial/MercurialLog.cs diff --git a/JiraTimeBotForm/JiraTimeBotForm.csproj b/JiraTimeBotForm/JiraTimeBotForm.csproj index f75af83..6f7c7c1 100644 --- a/JiraTimeBotForm/JiraTimeBotForm.csproj +++ b/JiraTimeBotForm/JiraTimeBotForm.csproj @@ -83,6 +83,8 @@ frmMain.cs + + diff --git a/JiraTimeBotForm/Job.cs b/JiraTimeBotForm/Job.cs index 12b7ab0..c05918c 100644 --- a/JiraTimeBotForm/Job.cs +++ b/JiraTimeBotForm/Job.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using JiraTimeBotForm.CommitWorks; using JiraTimeBotForm.Configuration; +using JiraTimeBotForm.Mercurial; using JiraTimeBotForm.TaskProcessors; using JiraTimeBotForm.TasksProcessors; using JiraTimeBotForm.TaskTime; @@ -13,12 +14,14 @@ namespace JiraTimeBotForm { class Job { - private readonly BuzzwordReplacer _buzzwordReplacer; + private readonly MercurialLog _mercurialLog; + private readonly TaskTimeDiscoverer _taskTimeDiscoverer; private readonly ILog _log; - public Job(BuzzwordReplacer buzzwordReplacer, ILog log) + public Job(MercurialLog mercurialLog, TaskTimeDiscoverer taskTimeDiscoverer, ILog log) { - _buzzwordReplacer = buzzwordReplacer; + _mercurialLog = mercurialLog; + _taskTimeDiscoverer = taskTimeDiscoverer; _log = log; } @@ -31,8 +34,6 @@ namespace JiraTimeBotForm private void DoTheJobImpl(Settings settings, ITasksProcessor tasksProcessor, CancellationToken cancellationToken) { - var taskDiscoverer = new TaskTimeDiscoverer(_buzzwordReplacer, _log); - int daysDiff = 0; if (tasksProcessor is MeetingProcessor) { @@ -43,7 +44,8 @@ namespace JiraTimeBotForm { DateTime date = DateTime.Now.Date.AddDays(daysDiff); - List taskTimes = taskDiscoverer.GetTaskTimes(settings, date, cancellationToken); + List commits = _mercurialLog.GetMercurialLog(settings, date, cancellationToken); + List taskTimes = _taskTimeDiscoverer.GetTaskTimes(settings, commits, cancellationToken); if (cancellationToken.IsCancellationRequested) { diff --git a/JiraTimeBotForm/Mercurial/MercurialCommitItem.cs b/JiraTimeBotForm/Mercurial/MercurialCommitItem.cs new file mode 100644 index 0000000..9dae37c --- /dev/null +++ b/JiraTimeBotForm/Mercurial/MercurialCommitItem.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiraTimeBotForm.Mercurial +{ + public class MercurialCommitItem + { + public string Description { get; set; } + public string Branch { get; set; } + + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + } +} diff --git a/JiraTimeBotForm/Mercurial/MercurialLog.cs b/JiraTimeBotForm/Mercurial/MercurialLog.cs new file mode 100644 index 0000000..54318e2 --- /dev/null +++ b/JiraTimeBotForm/Mercurial/MercurialLog.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using JiraTimeBotForm.Configuration; +using JiraTimeBotForm.TaskTime; +using Mercurial; + +namespace JiraTimeBotForm.Mercurial +{ + public class MercurialLog + { + private readonly ILog _log; + + public MercurialLog(ILog log) + { + _log = log; + } + + public List GetMercurialLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken)) + { + date = date.GetValueOrDefault(DateTime.Now.Date); + + var workTasks = new List(); + foreach (var repoDirectory in Directory.GetDirectories(settings.RepositoryPath)) + { + if (cancellationToken.IsCancellationRequested) + { + return new List(); + } + + //var project = new DirectoryInfo(repoDirectory).Name; + if (!Directory.Exists(Path.Combine(repoDirectory, ".hg"))) + { + continue; + } + + var repo = new Repository(repoDirectory); + var logCommand = new LogCommand + { + Date = date, + Users = { settings.MercurialAuthorEmail }, + AdditionalArguments = { "--encoding=utf-8"}, + }; + + var log = repo.Log(logCommand); + + foreach (var changeset in log) + { + if (cancellationToken.IsCancellationRequested) + { + return new List(); + } + + var commitMessage = FixEncoding(changeset.CommitMessage); + if (IsNeedToSkip(changeset.Branch, commitMessage)) + { + continue; + } + commitMessage = StripTechnicalInfo(commitMessage); + //commitMessage = _buzzwordReplacer.FixBuzzwords(commitMessage); + + workTasks.Add(new MercurialCommitItem + { + Description = commitMessage, + Branch = changeset.Branch, + StartTime = changeset.Timestamp, + EndTime = changeset.Timestamp + }); + _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}"); + } + } + if (!workTasks.Any()) + { + return new List(); + } + + return workTasks; + } + + + private string StripTechnicalInfo(string commitMessage) + { + if (!commitMessage.Contains("Signed-by:")) + { + return commitMessage; + } + + var arr = commitMessage.Split('\n'); + var sb = new StringBuilder(); + foreach (var itm in arr) + { + if (string.IsNullOrEmpty(itm)) + { + continue; + } + if (itm.StartsWith("Signed-by")) + { + continue; + } + if (itm.StartsWith("Jira:")) + { + continue; + } + + sb.AppendLine(itm); + } + + var message = sb.ToString(); + message = message.TrimEnd('\n'); + message = message.TrimEnd('\r'); + + return message; + } + + private bool IsNeedToSkip(string branch, string commitMessage) + { + if (!branch.Contains("-")) + { + return true; + } + + //Пропускаем Close и Merge коммиты + if (commitMessage.StartsWith($"Close {branch} ", StringComparison.InvariantCultureIgnoreCase) || + commitMessage.StartsWith($"Merge with ", StringComparison.InvariantCultureIgnoreCase)) + { + return true; + } + + return false; + } + + private string FixEncoding(string source) + { + //перекодируем сообщение - ибо оно криво забирается в 1252 + Encoding srcEncodingFormat = Encoding.GetEncoding("windows-1252"); + byte[] originalByteString = srcEncodingFormat.GetBytes(source); + var commitMessage = Encoding.UTF8.GetString(originalByteString); + return commitMessage; + } + } +} diff --git a/JiraTimeBotForm/TaskTime/ITaskTimeDiscoverer.cs b/JiraTimeBotForm/TaskTime/ITaskTimeDiscoverer.cs index c520e40..e6b5b48 100644 --- a/JiraTimeBotForm/TaskTime/ITaskTimeDiscoverer.cs +++ b/JiraTimeBotForm/TaskTime/ITaskTimeDiscoverer.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.Threading; using JiraTimeBotForm.Configuration; +using JiraTimeBotForm.Mercurial; namespace JiraTimeBotForm.TaskTime { public interface ITaskTimeDiscoverer { - List GetTaskTimes(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken)); + List GetTaskTimes(Settings settings, List commitItems, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/JiraTimeBotForm/TaskTime/TaskTimeDiscoverer.cs b/JiraTimeBotForm/TaskTime/TaskTimeDiscoverer.cs index f70aa73..8ed5df2 100644 --- a/JiraTimeBotForm/TaskTime/TaskTimeDiscoverer.cs +++ b/JiraTimeBotForm/TaskTime/TaskTimeDiscoverer.cs @@ -3,92 +3,37 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Text.RegularExpressions; using System.Threading; -using JiraTimeBotForm.CommitWorks; using JiraTimeBotForm.Configuration; +using JiraTimeBotForm.Mercurial; using Mercurial; namespace JiraTimeBotForm.TaskTime { public class TaskTimeDiscoverer: ITaskTimeDiscoverer { - private readonly BuzzwordReplacer _buzzwordReplacer; private readonly ILog _log; - public TaskTimeDiscoverer(BuzzwordReplacer buzzwordReplacer, ILog log = null) + public TaskTimeDiscoverer(ILog log) { - _buzzwordReplacer = buzzwordReplacer; _log = log; } - public List GetTaskTimes(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken)) + public List GetTaskTimes(Settings settings, List commitItems, CancellationToken cancellationToken = default(CancellationToken)) { - var workTimeItems = new List(); + int remainMinutes = settings.MinuterPerWorkDay; + int totalCommitsCount = commitItems.Count; - date = date.GetValueOrDefault(DateTime.Now.Date); + List workTimeItems = new List(); - var workTasks = new List(); - foreach (var repoDirectory in Directory.GetDirectories(settings.RepositoryPath)) + //Нам нужно раскидать 480 минут в день. + foreach (var taskGroup in commitItems.GroupBy(f => f.Branch).OrderByDescending(f=>f.Count())) { if (cancellationToken.IsCancellationRequested) { - return workTimeItems; + return new List(); } - //var project = new DirectoryInfo(repoDirectory).Name; - if (!Directory.Exists(Path.Combine(repoDirectory, ".hg"))) - { - continue; - } - - var repo = new Repository(repoDirectory); - var logCommand = new LogCommand - { - Date = date, - Users = { settings.MercurialAuthorEmail }, - AdditionalArguments = { "--encoding=utf-8"}, - }; - - var log = repo.Log(logCommand); - - foreach (var changeset in log) - { - if (cancellationToken.IsCancellationRequested) - { - return workTimeItems; - } - - var commitMessage = FixEncoding(changeset.CommitMessage); - if (IsNeedToSkip(changeset.Branch, commitMessage)) - { - continue; - } - commitMessage = StripTechnicalInfo(commitMessage); - commitMessage = _buzzwordReplacer.FixBuzzwords(commitMessage); - - workTasks.Add(new TaskTimeItem - { - Description = commitMessage, - Branch = changeset.Branch, - Commits = 1, - StartTime = changeset.Timestamp, - EndTime = changeset.Timestamp - }); - _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}"); - } - } - if (!workTasks.Any()) - { - return new List(); - } - - int remainMinutes = settings.MinuterPerWorkDay; - int totalCommitsCount = workTasks.Count; - - //Нам нужно раскидать 480 минут в день. - foreach (var taskGroup in workTasks.GroupBy(f => f.Branch).OrderByDescending(f=>f.Count())) - { int currentTaskCommits = taskGroup.Count(); int currentTaskTime = (int)RoundTo(settings.MinuterPerWorkDay / totalCommitsCount * currentTaskCommits); remainMinutes = remainMinutes - currentTaskTime; @@ -113,6 +58,11 @@ namespace JiraTimeBotForm.TaskTime workTimeItems.Add(taskTimeItem); } + + if (remainMinutes != 0) + { + _log.Trace($"Погрешность распределения времени: {remainMinutes}. Добавляю к первой задаче."); + } //если переборщили или не достаточно добавили до 8 часов - скореектируем остаток в первой задаче (она самая трудозатратная). workTimeItems.First().Time += TimeSpan.FromMinutes(remainMinutes); @@ -120,65 +70,6 @@ namespace JiraTimeBotForm.TaskTime } - private string StripTechnicalInfo(string commitMessage) - { - if (!commitMessage.Contains("Signed-by:")) - { - return commitMessage; - } - - var arr = commitMessage.Split('\n'); - var sb = new StringBuilder(); - foreach (var itm in arr) - { - if (string.IsNullOrEmpty(itm)) - { - continue; - } - if (itm.StartsWith("Signed-by")) - { - continue; - } - if (itm.StartsWith("Jira:")) - { - continue; - } - - sb.AppendLine(itm); - } - - var message = sb.ToString(); - message = message.TrimEnd('\n'); - message = message.TrimEnd('\r'); - - return message; - } - - private bool IsNeedToSkip(string branch, string commitMessage) - { - if (!branch.Contains("-")) - { - return true; - } - - //Пропускаем Close и Merge коммиты - if (commitMessage.StartsWith($"Close {branch} ", StringComparison.InvariantCultureIgnoreCase) || - commitMessage.StartsWith($"Merge with ", StringComparison.InvariantCultureIgnoreCase)) - { - return true; - } - - return false; - } - - private string FixEncoding(string source) - { - //перекодируем сообщение - ибо оно криво забирается в 1252 - Encoding srcEncodingFormat = Encoding.GetEncoding("windows-1252"); - byte[] originalByteString = srcEncodingFormat.GetBytes(source); - var commitMessage = Encoding.UTF8.GetString(originalByteString); - return commitMessage; - } private decimal RoundTo(decimal value, decimal to = 15, bool up = true) { diff --git a/JiraTimeBotForm/frmMain.cs b/JiraTimeBotForm/frmMain.cs index eb36758..8126658 100644 --- a/JiraTimeBotForm/frmMain.cs +++ b/JiraTimeBotForm/frmMain.cs @@ -6,8 +6,10 @@ using System.Threading.Tasks; using System.Windows.Forms; using JiraTimeBotForm.CommitWorks; using JiraTimeBotForm.Configuration; +using JiraTimeBotForm.Mercurial; using JiraTimeBotForm.Passwords; using JiraTimeBotForm.TasksProcessors; +using JiraTimeBotForm.TaskTime; using Newtonsoft.Json; // This is the code for your desktop app. @@ -59,7 +61,9 @@ namespace JiraTimeBotForm trayIcon.Click += btnTray_Click; trayIcon.DoubleClick += btnTray_Click; - _job = new Job(_buzzwordReplacer, _log); + var mercurialLog = new MercurialLog(_log); + var taskTimeDiscoverer = new TaskTimeDiscoverer(_log); + _job = new Job(mercurialLog, taskTimeDiscoverer, _log); _controls = new Control[] { txtJiraLogin, txtJiraPassword, txtMercurialEmail, actTime, txtRepoPath, txtDummyMode, btnSave, btnStart, btnMeeting, chkAddComments }; }