Compare commits

..
9 Commits
12 changed files with 131 additions and 113 deletions
+1 -1
View File
@@ -1 +1 @@
1.0.56 1.0.61
+3 -3
View File
@@ -1,5 +1,5 @@
# JiraTimeBot [![Build status](https://ci.appveyor.com/api/projects/status/anmhfvuj4oq84j1f?svg=true)](https://ci.appveyor.com/project/Monster1025/JiraTimeBot) # JiraTimeBot [![Build status](https://ci.appveyor.com/api/projects/status/anmhfvuj4oq84j1f/branch/master?svg=true)](https://ci.appveyor.com/project/monster1025/jiratimebot/branch/master)
Приложение для автоматического добавления Jira Worklog'ов исходя из количества коммитов в ветку. Приложение для автоматического добавления Jira Worklog'ов исходя из количества коммитов в ветку. Возможна работа по JQL-запросу JIRA.
# Ограничения # Ограничения
- Предполагается что все Ваши репозитории находятся в одной папке (к которой вы указываете путь в настройках). - Предполагается что все Ваши репозитории находятся в одной папке (к которой вы указываете путь в настройках).
@@ -19,7 +19,7 @@
- Время запуска - время автоматического запуска бота. Если была установлена галочка "тестовый прогон" - она будет снята. - Время запуска - время автоматического запуска бота. Если была установлена галочка "тестовый прогон" - она будет снята.
- Минут в рабочем дне - количество распределяемых минут (оыбчно 8 * 60). - Минут в рабочем дне - количество распределяемых минут (оыбчно 8 * 60).
- Рандомных минут - если > 0, то будет прибавлено рандомное количество минут к рабочему времени (но кратное значению округления). - Рандомных минут - если > 0, то будет прибавлено рандомное количество минут к рабочему времени (но кратное значению округления).
- Добавлять описание (Режим Mercurial) - добавлять ли в описание CommitMessage, если не установлено - добавляются стандартные фразы программистов (типа "написание кода"). - Добавлять описание (Режим Mercurial) - добавлять ли в описание CommitMessage, если не установлено - описание не заполняются.
- Автозагрузка - загружать ли программу при старте ОС. - Автозагрузка - загружать ли программу при старте ОС.
# Скачать # Скачать
Скачать актуальную версию можно тут: https://github.com/monster1025/JiraTimeBot/releases/latest Скачать актуальную версию можно тут: https://github.com/monster1025/JiraTimeBot/releases/latest
@@ -1,32 +1,13 @@
using JiraTimeBot.Configuration; using JiraTimeBot.Configuration;
using JiraTimeBot.TaskTime.Objects; using JiraTimeBot.TaskTime.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
namespace JiraTimeBot.JiraIntegration.Comments namespace JiraTimeBot.JiraIntegration.Comments
{ {
public class JiraDescriptionSource : IJiraDescriptionSource public class JiraDescriptionSource : IJiraDescriptionSource
{ {
private readonly List<string> _dummyComments = new List<string>
{
"Написание кода", "написание кода", "программирование", "реализация задачи", "кодинг", "код + тесты",
"кодинг", "написание кода и тестов"
};
public string GetDescription(TaskTimeItem taskTimeItem, bool addCommentsToWorklog, Settings settings) public string GetDescription(TaskTimeItem taskTimeItem, bool addCommentsToWorklog, Settings settings)
{ {
if (addCommentsToWorklog) return addCommentsToWorklog ? taskTimeItem.Description : "";
{
return taskTimeItem.Description;
}
if (settings.WorkType == WorkType.Mercurial)
{
return _dummyComments.OrderBy(f => Guid.NewGuid()).FirstOrDefault();
}
return "";
} }
} }
} }
+2 -2
View File
@@ -107,9 +107,9 @@ namespace JiraTimeBot.JiraIntegration
{ {
issue = jira.Issues.Queryable.FirstOrDefault(f => f.Key == taskTimeItem.Branch); issue = jira.Issues.Queryable.FirstOrDefault(f => f.Key == taskTimeItem.Branch);
} }
catch (Exception) catch (Exception ex)
{ {
_log.Error($"Ошибка получения задачи из JIRA: {ex.Message} - {ex.InnerException?.Message}");
} }
if (issue == null) if (issue == null)
{ {
@@ -46,28 +46,28 @@ namespace JiraTimeBot.JiraIntegration
{ {
foreach (var comment in userComments.OrderBy(f=>f.CreatedDate)) foreach (var comment in userComments.OrderBy(f=>f.CreatedDate))
{ {
workTasks.Add(new TaskTimeItem var item = new TaskTimeItem(issue.Key.Value,
{ issue.Summary,
StartTime = issue.Updated.GetValueOrDefault(date.Value), issue.Project,
Description = issue.Summary, issue.Updated.GetValueOrDefault(date.Value),
Branch = issue.Key.Value, TimeSpan.Zero,
FilesAffected = 1, 1,
Commits = 1, 1,
Type = CommitType.Task CommitType.Task);
}); workTasks.Add(item);
} }
} }
else else
{ {
workTasks.Add(new TaskTimeItem var item = new TaskTimeItem(issue.Key.Value,
{ issue.Summary,
StartTime = issue.Updated.GetValueOrDefault(date.Value), issue.Project,
Description = issue.Summary, issue.Updated.GetValueOrDefault(date.Value),
Branch = issue.Key.Value, TimeSpan.Zero,
FilesAffected = 1, 1,
Commits = 1, 1,
Type = CommitType.Task CommitType.Task);
}); workTasks.Add(item);
} }
} }
+1
View File
@@ -92,6 +92,7 @@
<Compile Include="Mercurial\IMercurialLog.cs" /> <Compile Include="Mercurial\IMercurialLog.cs" />
<Compile Include="Mercurial\Modifiers\TechnicalInfoSkipper.cs" /> <Compile Include="Mercurial\Modifiers\TechnicalInfoSkipper.cs" />
<Compile Include="TasksProcessors\IAllTasksProcessors.cs" /> <Compile Include="TasksProcessors\IAllTasksProcessors.cs" />
<Compile Include="TaskTime\Objects\CommitType.cs" />
<Compile Include="TaskTime\TaskTimeSpread.cs" /> <Compile Include="TaskTime\TaskTimeSpread.cs" />
<Compile Include="UI\frmMain.cs"> <Compile Include="UI\frmMain.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
+18 -12
View File
@@ -48,6 +48,8 @@ namespace JiraTimeBot.Mercurial
continue; continue;
} }
var directoryInfo = new DirectoryInfo(repoDirectory);
var repo = new Repository(repoDirectory); var repo = new Repository(repoDirectory);
var logCommand = new LogCommand var logCommand = new LogCommand
{ {
@@ -72,23 +74,27 @@ namespace JiraTimeBot.Mercurial
} }
commitMessage = _technicalInfoSkipper.StripTechnicalInfo(commitMessage); commitMessage = _technicalInfoSkipper.StripTechnicalInfo(commitMessage);
var task = new TaskTimeItem var task = new TaskTimeItem(changeset.Branch,
{ commitMessage,
StartTime = changeset.Timestamp, directoryInfo.Name,
Description = commitMessage, changeset.Timestamp,
Branch = changeset.Branch, TimeSpan.Zero,
FilesAffected = changeset.PathActions.Count, 1,
Commits = 1, changeset.PathActions.Count,
TimeSpent = TimeSpan.Zero, GetCommitType(changeset.Branch));
Type = GetCommitType(changeset.Branch)
};
if (task.Type == CommitType.Release && task.Description.StartsWith("Merge with", StringComparison.CurrentCultureIgnoreCase)) if (task.Type == CommitType.Release && task.Description.StartsWith("Merge with", StringComparison.CurrentCultureIgnoreCase))
{ {
var branch = task.Description.Replace("Merge with", "").Replace(" ", ""); 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", ""); var release = task.Branch.Replace("release", "");
task.Branch = branch; task.Branch = branch;
task.Description = $"Подготовка и публикация версии {release}."; task.Description = $"Подготовка и публикация версии {task.Project} {release}.";
} }
workTasks.Add(task); workTasks.Add(task);
_log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}"); _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress} - {commitMessage}");
+3 -3
View File
@@ -26,6 +26,6 @@ using System.Runtime.InteropServices;
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.56")] [assembly: AssemblyVersion("1.0.61")]
[assembly: AssemblyFileVersion("1.0.56")] [assembly: AssemblyFileVersion("1.0.61")]
[assembly: AssemblyInformationalVersion("1.0.56")] [assembly: AssemblyInformationalVersion("1.0.61")]
@@ -0,0 +1,7 @@
namespace JiraTimeBot.TaskTime.Objects
{
public enum CommitType {
Task = 0,
Release = 1
}
}
@@ -11,10 +11,19 @@ namespace JiraTimeBot.TaskTime.Objects
public int Commits { get; set; } public int Commits { get; set; }
public int FilesAffected { get; set; } public int FilesAffected { get; set; }
public CommitType Type { get; set; } public CommitType Type { get; set; }
} public string Project { get; set; }
public enum CommitType { public TaskTimeItem(string branch, string description, string project, DateTime startTime, TimeSpan timeSpent, int commits,
Task = 0, int filesAffected = 1, CommitType type = CommitType.Task)
Release = 1 {
Branch = branch;
Description = description;
Project = project;
Commits = commits;
TimeSpent = timeSpent;
StartTime = startTime;
FilesAffected = filesAffected;
Type = type;
}
} }
} }
@@ -57,7 +57,18 @@ namespace JiraTimeBot.TaskTime
} }
var workTasks = _spreadHelper.SpreadTime(taskCommits, remainMinutes, settings.RoundToMinutes); var workTasks = _spreadHelper.SpreadTime(taskCommits, remainMinutes, settings.RoundToMinutes);
workTimeItems.AddRange(workTasks); foreach (var workTask in workTasks)
{
var existingItem = workTimeItems.FirstOrDefault(f => f.Branch == workTask.Branch);
if (existingItem != null)
{
existingItem.TimeSpent += workTask.TimeSpent;
existingItem.Description += "\r\n" + workTask.Description;
continue;
}
workTimeItems.Add(workTask);
}
workTimeItems = workTimeItems.OrderByDescending(f => f.TimeSpent).ToList(); workTimeItems = workTimeItems.OrderByDescending(f => f.TimeSpent).ToList();
remainMinutes = minutesPerWorkDay - (int) workTimeItems.Sum(f => f.TimeSpent.TotalMinutes); remainMinutes = minutesPerWorkDay - (int) workTimeItems.Sum(f => f.TimeSpent.TotalMinutes);
@@ -82,19 +93,20 @@ namespace JiraTimeBot.TaskTime
//Если указана задача контроля времени - то спишем туда 30 минут и вычеркнем их из общего рабочего времени. //Если указана задача контроля времени - то спишем туда 30 минут и вычеркнем их из общего рабочего времени.
if (!string.IsNullOrEmpty(timeControlTask)) if (!string.IsNullOrEmpty(timeControlTask))
{ {
return new TaskTimeItem return new TaskTimeItem(timeControlTask,
{ "Ведение учета времени",
TimeSpent = TimeSpan.FromMinutes(minutes), "Service",
Branch = timeControlTask, DateTime.Now,
Commits = 1, TimeSpan.FromMinutes(minutes),
Description = "Ведение учета времени" 1,
}; 1,
CommitType.Task);
} }
return null; return null;
} }
private void FixTooBigInterval(Settings settings, int totalCommitsCount, int workHours) private void FixTooBigInterval(Settings settings, int workHours, int totalCommitsCount)
{ {
//если кол-во коммитов более чем кол-во интервалов - то уменьшим интервал вдвое. //если кол-во коммитов более чем кол-во интервалов - то уменьшим интервал вдвое.
while (totalCommitsCount > (workHours * (60.0 / settings.RoundToMinutes))) while (totalCommitsCount > (workHours * (60.0 / settings.RoundToMinutes)))
+15 -13
View File
@@ -34,19 +34,21 @@ namespace JiraTimeBot.TaskTime
{ {
sb.AppendLine($"- {task.Description}"); sb.AppendLine($"- {task.Description}");
} }
var taskTimeItem = new TaskTimeItem
{ var timeSpent = appendTime
Branch = taskGroup.Key, ? TimeSpan.FromMinutes(taskGroup.Sum(f => f.TimeSpent.TotalMinutes)) +
TimeSpent = appendTime ? TimeSpan.FromMinutes(currentTaskTime)
TimeSpan.FromMinutes(taskGroup.Sum(f=>f.TimeSpent.TotalMinutes)) + TimeSpan.FromMinutes(currentTaskTime): : TimeSpan.FromMinutes(currentTaskTime);
TimeSpan.FromMinutes(currentTaskTime)
, var taskTimeItem = new TaskTimeItem(
Commits = taskGroup.Sum(f=>f.Commits), taskGroup.Key,
Description = sb.ToString(), sb.ToString(),
StartTime = taskGroup.Min(f=>f.StartTime), taskGroup.First().Project,
FilesAffected = taskGroup.Sum(f=>f.FilesAffected), taskGroup.Min(f => f.StartTime),
Type = taskGroup.First().Type timeSpent,
}; taskGroup.Sum(f => f.Commits),
taskGroup.Sum(f => f.FilesAffected),
taskGroup.First().Type);
newList.Add(taskTimeItem); newList.Add(taskTimeItem);
} }