diff --git a/src/JiraTimeBot/App.config b/src/JiraTimeBot/App.config
index 4abcc95..c107c34 100644
--- a/src/JiraTimeBot/App.config
+++ b/src/JiraTimeBot/App.config
@@ -10,12 +10,16 @@
-
-
+
+
-
-
+
+
+
+
+
+
diff --git a/src/JiraTimeBot/Configuration/Settings.cs b/src/JiraTimeBot/Configuration/Settings.cs
index e13ca68..24ddbcf 100644
--- a/src/JiraTimeBot/Configuration/Settings.cs
+++ b/src/JiraTimeBot/Configuration/Settings.cs
@@ -144,5 +144,6 @@ namespace JiraTimeBot.Configuration
{
Mercurial = 0,
JiraLogs = 1,
+ GitLogs = 2
}
}
diff --git a/src/JiraTimeBot/DI/ContainerBuilder.cs b/src/JiraTimeBot/DI/ContainerBuilder.cs
index 3686d0b..2cca8fe 100644
--- a/src/JiraTimeBot/DI/ContainerBuilder.cs
+++ b/src/JiraTimeBot/DI/ContainerBuilder.cs
@@ -43,8 +43,9 @@ namespace JiraTimeBot.DI
_builder.RegisterType().As().AsSelf();
- _builder.RegisterType().As().AsSelf();
- _builder.RegisterType().As().AsSelf();
+ _builder.RegisterType().As().AsSelf();
+ _builder.RegisterType().As().AsSelf();
+ _builder.RegisterType().As().AsSelf();
_builder.RegisterAggregateService();
_builder.RegisterType().As().AsSelf();
diff --git a/src/JiraTimeBot/JiraIntegration/JiraApi.cs b/src/JiraTimeBot/JiraIntegration/JiraApi.cs
index 10d1521..3e83029 100644
--- a/src/JiraTimeBot/JiraIntegration/JiraApi.cs
+++ b/src/JiraTimeBot/JiraIntegration/JiraApi.cs
@@ -72,7 +72,8 @@ namespace JiraTimeBot.JiraIntegration
public List GetWorkloggedIssuesByDate(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default)
{
date = date.GetValueOrDefault(DateTime.Now.Date);
- var jql = "issueFunction in workLogged(\"on %DATE% by '%USER%'\")";
+ //var jql = "issueFunction in workLogged(\"on %DATE% by '%USER%'\")";
+ var jql = "worklogAuthor = '%USER%' && worklogDate = \"%DATE%\"";
return GetIssuesByJQL(jql, settings, date, cancellationToken);
}
diff --git a/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs b/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs
index 068b77c..b692aca 100644
--- a/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs
+++ b/src/JiraTimeBot/JiraIntegration/JiraCommitEmulator.cs
@@ -10,7 +10,7 @@ using JiraTimeBot.TaskTime.Objects;
namespace JiraTimeBot.JiraIntegration
{
- public class JiraCommitEmulator : IMercurialLog
+ public class JiraCommitEmulator : IRepositoryLog
{
private readonly ILog _log;
private readonly JiraApi _jiraApi;
@@ -21,7 +21,7 @@ namespace JiraTimeBot.JiraIntegration
_jiraApi = jiraApi;
}
- public List GetMercurialLog(Settings settings,
+ public List GetRepositoryLog(Settings settings,
DateTime? date = null,
CancellationToken cancellationToken = default(CancellationToken))
{
diff --git a/src/JiraTimeBot/JiraTimeBot.csproj b/src/JiraTimeBot/JiraTimeBot.csproj
index d4e2687..380ae66 100644
--- a/src/JiraTimeBot/JiraTimeBot.csproj
+++ b/src/JiraTimeBot/JiraTimeBot.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -11,6 +12,8 @@
v4.6.1
512
true
+
+
AnyCPU
@@ -36,36 +39,49 @@
app.ico
-
- ..\packages\Atlassian.SDK.10.4.0\lib\net452\Atlassian.Jira.dll
+
+ ..\packages\Atlassian.SDK.12.1.0\lib\net452\Atlassian.Jira.dll
-
- ..\packages\Autofac.4.9.1\lib\net45\Autofac.dll
+
+ ..\packages\Autofac.5.1.2\lib\net461\Autofac.dll
-
- ..\packages\Autofac.Extras.AggregateService.4.1.0\lib\net45\Autofac.Extras.AggregateService.dll
+
+ ..\packages\Autofac.Extras.AggregateService.5.0.0\lib\netstandard2.0\Autofac.Extras.AggregateService.dll
- ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll
+ ..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll
+
+
+ ..\packages\LibGit2Sharp.0.27.0-preview-0034\lib\net46\LibGit2Sharp.dll
..\packages\Mercurial.Net.1.1.1.607\lib\net35-Client\Mercurial.Net.dll
-
- ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
-
- ..\packages\RestSharp.106.6.9\lib\net452\RestSharp.dll
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\RestSharp.106.10.1\lib\net452\RestSharp.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
+
@@ -87,11 +103,12 @@
+
-
+
@@ -161,4 +178,10 @@
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
\ No newline at end of file
diff --git a/src/JiraTimeBot/Job.cs b/src/JiraTimeBot/Job.cs
index d5d4605..7731d1d 100644
--- a/src/JiraTimeBot/Job.cs
+++ b/src/JiraTimeBot/Job.cs
@@ -72,17 +72,22 @@ namespace JiraTimeBot
private bool SetTaskTimesForDateImpl(DateTime setForDate, DateTime realDate, Settings settings, ITasksProcessor tasksProcessor, bool dummyMode, CancellationToken cancellationToken)
{
- IMercurialLog mercurial = _mercurialProviders.MercurialLog;
+ IRepositoryLog mercurial = _mercurialProviders.MercurialLog;
if (settings.WorkType == WorkType.JiraLogs)
{
_log.Info("Использую Jira как источник информации.");
mercurial = _mercurialProviders.JiraCommitEmulator;
}
+ else if (settings.WorkType == WorkType.GitLogs)
+ {
+ _log.Info("Использую Git как источник информации.");
+ mercurial = _mercurialProviders.GitLog;
+ }
List taskTimes;
if (!(tasksProcessor is MeetingProcessor))
{
- List commits = mercurial.GetMercurialLog(settings, realDate, cancellationToken);
+ List commits = mercurial.GetRepositoryLog(settings, realDate, cancellationToken);
taskTimes = _taskTimeDiscoverer.CalculateTaskTime(commits, settings, cancellationToken);
}
else
diff --git a/src/JiraTimeBot/Mercurial/GitLog.cs b/src/JiraTimeBot/Mercurial/GitLog.cs
new file mode 100644
index 0000000..08b320e
--- /dev/null
+++ b/src/JiraTimeBot/Mercurial/GitLog.cs
@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using JiraTimeBot.Configuration;
+using JiraTimeBot.Mercurial.Modifiers;
+using JiraTimeBot.TaskTime.Objects;
+using LibGit2Sharp;
+using LibGit2Sharp.Handlers;
+
+namespace JiraTimeBot.Mercurial
+{
+ public class GitLog : IRepositoryLog
+ {
+ private readonly ILog _log;
+ private readonly ICommitSkipper _commitSkipper;
+ private readonly ITechnicalInfoSkipper _technicalInfoSkipper;
+
+ public GitLog(ILog log, ICommitSkipper commitSkipper, ITechnicalInfoSkipper technicalInfoSkipper)
+ {
+ _log = log;
+ _commitSkipper = commitSkipper;
+ _technicalInfoSkipper = technicalInfoSkipper;
+ }
+
+ public List GetRepositoryLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(settings.RepositoryPath) || !Directory.Exists(settings.RepositoryPath))
+ {
+ _log.Error("Папка с репо не сушествует.");
+ return new List();
+ }
+
+ 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, ".git")))
+ {
+ continue;
+ }
+
+ var directoryInfo = new DirectoryInfo(repoDirectory);
+
+
+ var repo = new LibGit2Sharp.Repository(repoDirectory);
+
+ 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 filter = new CommitFilter { SortBy = CommitSortStrategies.Time };
+
+ foreach (Commit commit in repo.Commits.QueryBy(filter).Take(200))
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return new List();
+ }
+ if (commit.Author.When.DateTime.Date != date || commit.Author.Email != settings.MercurialAuthorEmail)
+ {
+ continue;
+ }
+
+ var branch = ListBranchesContaininingCommit(repo, commit.Sha).Select(f => f.FriendlyName)
+ .Where(f => f.Contains("-") && !f.Contains("/")).Distinct().FirstOrDefault();
+ if (branch == null)
+ {
+ continue;
+ }
+
+ var commitMessage = commit.MessageShort;
+ if (_commitSkipper.IsNeedToSkip(branch, commitMessage))
+ {
+ continue;
+ }
+ commitMessage = _technicalInfoSkipper.StripTechnicalInfo(commitMessage);
+
+ var task = new TaskTimeItem(branch,
+ commitMessage,
+ directoryInfo.Name,
+ commit.Committer.When.DateTime,
+ TimeSpan.Zero,
+ 1,
+ 1, //changeset.PathActions.Count,
+ "",
+ GetCommitType(branch));
+ workTasks.Add(task);
+
+ _log?.Trace($" - Найден commit: {commit.Committer.When.DateTime} - {branch} - {commit.Author.Email} - {commitMessage}");
+ }
+
+ //foreach (var changeset in log)
+ //{
+
+ // 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}");
+ //}
+ }
+ if (!workTasks.Any())
+ {
+ return new List();
+ }
+
+ return workTasks;
+ }
+
+ private CommitType GetCommitType(string branch)
+ {
+ return branch.StartsWith("release") ? CommitType.Release : CommitType.Task;
+ }
+
+ 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 IEnumerable ListBranchesContaininingCommit(Repository repo, string commitSha)
+ {
+ bool directBranchHasBeenFound = false;
+ foreach (var branch in repo.Branches)
+ {
+ if (branch.Tip.Sha != commitSha)
+ {
+ continue;
+ }
+
+ directBranchHasBeenFound = true;
+ yield return branch;
+ }
+
+ if (directBranchHasBeenFound)
+ {
+ yield break;
+ }
+
+ foreach (var branch in repo.Branches)
+ {
+ var commits = repo.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = branch }).Where(c => c.Sha == commitSha);
+
+ if (!commits.Any())
+ {
+ continue;
+ }
+
+ yield return branch;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs b/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs
index d87cc38..d0bc0e8 100644
--- a/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs
+++ b/src/JiraTimeBot/Mercurial/IAllMercurialProviders.cs
@@ -5,6 +5,7 @@ namespace JiraTimeBot.Mercurial
public interface IAllMercurialProviders
{
MercurialLog MercurialLog { get; }
+ GitLog GitLog { get; }
JiraCommitEmulator JiraCommitEmulator { get; }
IJiraHistory JiraHistory { get; }
}
diff --git a/src/JiraTimeBot/Mercurial/IMercurialLog.cs b/src/JiraTimeBot/Mercurial/IRepositoryLog.cs
similarity index 50%
rename from src/JiraTimeBot/Mercurial/IMercurialLog.cs
rename to src/JiraTimeBot/Mercurial/IRepositoryLog.cs
index 1459319..e2b21ad 100644
--- a/src/JiraTimeBot/Mercurial/IMercurialLog.cs
+++ b/src/JiraTimeBot/Mercurial/IRepositoryLog.cs
@@ -6,8 +6,8 @@ using JiraTimeBot.TaskTime.Objects;
namespace JiraTimeBot.Mercurial
{
- public interface IMercurialLog
+ public interface IRepositoryLog
{
- List GetMercurialLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken));
+ List GetRepositoryLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken));
}
}
\ No newline at end of file
diff --git a/src/JiraTimeBot/Mercurial/MercurialLog.cs b/src/JiraTimeBot/Mercurial/MercurialLog.cs
index 390d6ad..ad61f75 100644
--- a/src/JiraTimeBot/Mercurial/MercurialLog.cs
+++ b/src/JiraTimeBot/Mercurial/MercurialLog.cs
@@ -11,7 +11,7 @@ using Mercurial;
namespace JiraTimeBot.Mercurial
{
- public class MercurialLog: IMercurialLog
+ public class MercurialLog: IRepositoryLog
{
private readonly ILog _log;
private readonly ICommitSkipper _commitSkipper;
@@ -24,7 +24,7 @@ namespace JiraTimeBot.Mercurial
_technicalInfoSkipper = technicalInfoSkipper;
}
- public List GetMercurialLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default)
+ public List GetRepositoryLog(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(settings.RepositoryPath) || !Directory.Exists(settings.RepositoryPath))
{
diff --git a/src/JiraTimeBot/Mercurial/Modifiers/CommitSkipper.cs b/src/JiraTimeBot/Mercurial/Modifiers/CommitSkipper.cs
index 53c5d2d..132a7b9 100644
--- a/src/JiraTimeBot/Mercurial/Modifiers/CommitSkipper.cs
+++ b/src/JiraTimeBot/Mercurial/Modifiers/CommitSkipper.cs
@@ -10,6 +10,7 @@ namespace JiraTimeBot.Mercurial.Modifiers
{
return false;
}
+
if (!branch.Contains("-"))
{
return true;
@@ -17,7 +18,8 @@ namespace JiraTimeBot.Mercurial.Modifiers
//Пропускаем Close и Merge коммиты
if (commitMessage.StartsWith($"Close {branch}", StringComparison.InvariantCultureIgnoreCase) ||
- commitMessage.StartsWith($"Merge with", StringComparison.InvariantCultureIgnoreCase))
+ commitMessage.StartsWith($"Merge with", StringComparison.InvariantCultureIgnoreCase) ||
+ commitMessage.StartsWith($"Merge branch", StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
diff --git a/src/JiraTimeBot/UI/frmSettings.Designer.cs b/src/JiraTimeBot/UI/frmSettings.Designer.cs
index 71f88e8..30e83dc 100644
--- a/src/JiraTimeBot/UI/frmSettings.Designer.cs
+++ b/src/JiraTimeBot/UI/frmSettings.Designer.cs
@@ -183,7 +183,8 @@
this.cboWorkType.FormattingEnabled = true;
this.cboWorkType.Items.AddRange(new object[] {
"Mercurial",
- "Jira"});
+ "Jira",
+ "Git"});
this.cboWorkType.Location = new System.Drawing.Point(133, 18);
this.cboWorkType.Name = "cboWorkType";
this.cboWorkType.Size = new System.Drawing.Size(99, 21);
diff --git a/src/JiraTimeBot/UI/frmSettings.cs b/src/JiraTimeBot/UI/frmSettings.cs
index 23987b1..601361e 100644
--- a/src/JiraTimeBot/UI/frmSettings.cs
+++ b/src/JiraTimeBot/UI/frmSettings.cs
@@ -102,7 +102,7 @@ namespace JiraTimeBot.UI
private void cboWorkType_SelectedIndexChanged(object sender, EventArgs e)
{
txtJQL.Enabled = (cboWorkType.SelectedIndex == 1);
- txtRepoPath.Enabled = (cboWorkType.SelectedIndex == 0);
+ txtRepoPath.Enabled = (cboWorkType.SelectedIndex == 0 || cboWorkType.SelectedIndex == 2);
}
}
}
diff --git a/src/JiraTimeBot/packages.config b/src/JiraTimeBot/packages.config
index 2e5c5e6..0b3bef3 100644
--- a/src/JiraTimeBot/packages.config
+++ b/src/JiraTimeBot/packages.config
@@ -1,10 +1,15 @@
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
\ No newline at end of file