Merge pull request #336 from l3m/correct-authors
Correct author attribution
This commit is contained in:
@@ -6,7 +6,7 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
{
|
||||
public partial class WrapperForWorkspace
|
||||
{
|
||||
public int Checkin(IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
public int Checkin(IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
{
|
||||
var checkinParameters = new WorkspaceCheckInParameters(_bridge.Unwrap<PendingChange>(changes), comment)
|
||||
@@ -14,9 +14,12 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
CheckinNotes = _bridge.Unwrap<CheckinNote>(checkinNote),
|
||||
AssociatedWorkItems = _bridge.Unwrap<WorkItemCheckinInfo>(workItemChanges),
|
||||
PolicyOverride = ToTfs(policyOverrideInfo),
|
||||
OverrideGatedCheckIn = overrideGatedCheckIn
|
||||
OverrideGatedCheckIn = overrideGatedCheckIn,
|
||||
};
|
||||
|
||||
if (author != null)
|
||||
checkinParameters.Author = author;
|
||||
|
||||
return _workspace.CheckIn(checkinParameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,20 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
{
|
||||
public partial class WrapperForWorkspace
|
||||
{
|
||||
public int Checkin(IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
public int Checkin(IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
{
|
||||
if (author != null)
|
||||
{
|
||||
return _workspace.CheckIn(
|
||||
_bridge.Unwrap<PendingChange>(changes),
|
||||
comment,
|
||||
author,
|
||||
_bridge.Unwrap<CheckinNote>(checkinNote),
|
||||
_bridge.Unwrap<WorkItemCheckinInfo>(workItemChanges),
|
||||
ToTfs(policyOverrideInfo));
|
||||
}
|
||||
|
||||
return _workspace.CheckIn(
|
||||
_bridge.Unwrap<PendingChange>(changes),
|
||||
comment,
|
||||
@@ -16,5 +27,7 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
_bridge.Unwrap<WorkItemCheckinInfo>(workItemChanges),
|
||||
ToTfs(policyOverrideInfo));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
{
|
||||
public partial class WrapperForWorkspace
|
||||
{
|
||||
public int Checkin(IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
public int Checkin(IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges,
|
||||
TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
{
|
||||
var checkinParameters = new WorkspaceCheckInParameters(_bridge.Unwrap<PendingChange>(changes), comment)
|
||||
{
|
||||
@@ -17,7 +17,12 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
OverrideGatedCheckIn = overrideGatedCheckIn
|
||||
};
|
||||
|
||||
if (author != null)
|
||||
checkinParameters.Author = author;
|
||||
|
||||
return _workspace.CheckIn(checkinParameters);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,8 +416,9 @@ namespace Sep.Git.Tfs.VsCommon
|
||||
_bridge.Unwrap<PolicyFailure>(policyOverrideInfo.Failures));
|
||||
}
|
||||
|
||||
|
||||
public ICheckinEvaluationResult EvaluateCheckin(TfsCheckinEvaluationOptions options, IPendingChange[] allChanges, IPendingChange[] changes,
|
||||
string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges)
|
||||
string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges)
|
||||
{
|
||||
return _bridge.Wrap<WrapperForCheckinEvaluationResult, CheckinEvaluationResult>(_workspace.EvaluateCheckin(
|
||||
_bridge.Convert<CheckinEvaluationOptions>(options),
|
||||
|
||||
@@ -238,12 +238,17 @@ namespace Sep.Git.Tfs.VsFake
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ICheckinEvaluationResult EvaluateCheckin(TfsCheckinEvaluationOptions options, IPendingChange[] allChanges, IPendingChange[] changes, string comment, string authors, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Shelve(IShelveset shelveset, IPendingChange[] changes, TfsShelvingOptions options)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Checkin(IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges, TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
public int Checkin(IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges, TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -34,13 +34,14 @@ namespace Sep.Git.Tfs.Commands
|
||||
(reviewer) => { CheckinNotes["Performance Reviewer"] = reviewer; } },
|
||||
{ "no-gate", "Disables gated checkin.",
|
||||
v => { OverrideGatedCheckIn = true; } },
|
||||
{ "A|authors=", "Path to an Authors file to map TFS users to Git users", v => AuthorsFilePath = v },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> _workItemsToAssociate = new List<string>();
|
||||
private List<string> _workItemsToResolve = new List<string>();
|
||||
private Dictionary<string, string> _checkinNotes = new Dictionary<string,string>();
|
||||
private Dictionary<string, string> _checkinNotes = new Dictionary<string, string>();
|
||||
|
||||
public string CheckinComment { get; set; }
|
||||
// This can be extended to checkin when the $EDITOR is invoked.
|
||||
@@ -52,5 +53,9 @@ namespace Sep.Git.Tfs.Commands
|
||||
public List<string> WorkItemsToAssociate { get { return _workItemsToAssociate; } }
|
||||
public List<string> WorkItemsToResolve { get { return _workItemsToResolve; } }
|
||||
public Dictionary<string, string> CheckinNotes { get { return _checkinNotes; } }
|
||||
|
||||
public string AuthorsFilePath { get; set; }
|
||||
public string AuthorTfsUserId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,11 @@ namespace Sep.Git.Tfs.Commands
|
||||
string commitMessage = _checkinOptions.NoGenerateCheckinComment
|
||||
? repo.GetCommitMessage(target)
|
||||
: repo.GetCommitMessage(target, tfsLatest);
|
||||
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, commitMessage);
|
||||
|
||||
GitCommit commit = repo.GetCommit(target);
|
||||
|
||||
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, commitMessage, commit);
|
||||
|
||||
_stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
|
||||
long newChangesetId = tfsRemote.Checkin(target, parentChangeset, commitSpecificCheckinOptions);
|
||||
tfsRemote.FetchWithMerge(newChangesetId, gitParents);
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Sep.Git.Tfs.Core
|
||||
public CheckinPolicyEvaluationResult EvaluateCheckin(IWorkspace workspace, IPendingChange[] pendingChanges, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemInfo)
|
||||
{
|
||||
var result = workspace.EvaluateCheckin(TfsCheckinEvaluationOptions.All, pendingChanges,
|
||||
pendingChanges, comment, checkinNote,
|
||||
pendingChanges, comment, null, checkinNote,
|
||||
workItemInfo);
|
||||
return new CheckinPolicyEvaluationResult(result);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using LibGit2Sharp;
|
||||
@@ -37,5 +38,14 @@ namespace Sep.Git.Tfs.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Tuple<string,string> AuthorAndEmail
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Tuple<string,string>(_commit.Author.Name, _commit.Author.Email);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Sep.Git.Tfs.Core.TfsInterop
|
||||
public interface IWorkspace
|
||||
{
|
||||
IPendingChange[] GetPendingChanges();
|
||||
ICheckinEvaluationResult EvaluateCheckin(TfsCheckinEvaluationOptions options, IPendingChange[] allChanges, IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges);
|
||||
ICheckinEvaluationResult EvaluateCheckin(TfsCheckinEvaluationOptions options, IPendingChange[] allChanges, IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges);
|
||||
void Shelve(IShelveset shelveset, IPendingChange[] changes, TfsShelvingOptions options);
|
||||
int Checkin(IPendingChange[] changes, string comment, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges, TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn);
|
||||
int Checkin(IPendingChange[] changes, string comment, string author, ICheckinNote checkinNote, IEnumerable<IWorkItemCheckinInfo> workItemChanges, TfsPolicyOverrideInfo policyOverrideInfo, bool overrideGatedCheckIn);
|
||||
int PendAdd(string path);
|
||||
int PendEdit(string path);
|
||||
int PendDelete(string path);
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Sep.Git.Tfs.Core
|
||||
}
|
||||
|
||||
var policyOverride = GetPolicyOverrides(options, checkinProblems.Result);
|
||||
var newChangeset = _workspace.Checkin(pendingChanges, options.CheckinComment, checkinNote, workItemInfos, policyOverride, options.OverrideGatedCheckIn);
|
||||
var newChangeset = _workspace.Checkin(pendingChanges, options.CheckinComment, options.AuthorTfsUserId, checkinNote, workItemInfos, policyOverride, options.OverrideGatedCheckIn);
|
||||
if (newChangeset == 0)
|
||||
{
|
||||
throw new GitTfsException("Checkin failed!");
|
||||
|
||||
+87
-10
@@ -9,27 +9,96 @@ namespace Sep.Git.Tfs.Util
|
||||
{
|
||||
public class Author
|
||||
{
|
||||
public string Name;
|
||||
public string Email;
|
||||
public Author(string tfsUserId, string name, string email)
|
||||
{
|
||||
TfsUserId = tfsUserId;
|
||||
_gitAuthor = new Tuple<string, string>(name, email);
|
||||
_gitUserId = BuildGitUserId(_gitAuthor);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gitAuthor.Item1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string Email
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gitAuthor.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
public string TfsUserId { get; set; }
|
||||
|
||||
public string GitUserId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gitUserId;
|
||||
}
|
||||
}
|
||||
|
||||
// we only use the trimmed email address as identity
|
||||
// (dictionary key) to avoid mismatches because of
|
||||
// active directory name formatting rules.
|
||||
public static string BuildGitUserId(string email)
|
||||
{
|
||||
return email.Trim();
|
||||
}
|
||||
|
||||
public static string BuildGitUserId(Tuple<string,string> gitUser)
|
||||
{
|
||||
return BuildGitUserId(gitUser.Item2);
|
||||
}
|
||||
|
||||
#region (private)
|
||||
private Tuple<string, string> _gitAuthor;
|
||||
private string _gitUserId;
|
||||
#endregion
|
||||
}
|
||||
|
||||
[StructureMapSingleton]
|
||||
public class AuthorsFile
|
||||
{
|
||||
private readonly Dictionary<string, Author> authors = new Dictionary<string, Author>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Author> _authorsByTfsUserId = new Dictionary<string, Author>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Author> _authorsByGitUserId = new Dictionary<string, Author>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public AuthorsFile()
|
||||
{ }
|
||||
{}
|
||||
|
||||
|
||||
public Dictionary<string, Author> Authors
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.authors;
|
||||
return this._authorsByTfsUserId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Dictionary<string, Author> AuthorsByGitUserId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._authorsByGitUserId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Author FindAuthor(Tuple<string,string> gitUser)
|
||||
{
|
||||
string key = Author.BuildGitUserId(gitUser);
|
||||
Author a;
|
||||
return _authorsByGitUserId.TryGetValue(key, out a) ? a : null;
|
||||
}
|
||||
|
||||
|
||||
// The first time a tfs user id or a git id is encountered, it is used as lookup key.
|
||||
public void Parse(TextReader authorsFileStream)
|
||||
{
|
||||
if (authorsFileStream != null)
|
||||
@@ -50,11 +119,19 @@ namespace Sep.Git.Tfs.Util
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!authors.ContainsKey(match.Groups[1].Value))
|
||||
{
|
||||
//git svn doesn't trim, but maybe this should?
|
||||
authors.Add(match.Groups[1].Value, new Author() { Name = match.Groups[2].Value, Email = match.Groups[3].Value });
|
||||
}
|
||||
//git svn doesn't trim, but maybe this should?
|
||||
string tfsUserId = match.Groups[1].Value;//.Trim();
|
||||
string name = match.Groups[2].Value;//.Trim();
|
||||
string email = match.Groups[3].Value;//.Trim();
|
||||
|
||||
Author a = new Author(tfsUserId, name, email);
|
||||
|
||||
if (!_authorsByTfsUserId.ContainsKey(a.TfsUserId))
|
||||
_authorsByTfsUserId.Add(a.TfsUserId, a);
|
||||
|
||||
if (!_authorsByGitUserId.ContainsKey(a.GitUserId))
|
||||
_authorsByGitUserId.Add(a.GitUserId, a);
|
||||
|
||||
}
|
||||
}
|
||||
line = authorsFileStream.ReadLine();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Sep.Git.Tfs.Commands;
|
||||
using Sep.Git.Tfs.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
using StructureMap;
|
||||
|
||||
namespace Sep.Git.Tfs.Util
|
||||
{
|
||||
@@ -38,6 +40,23 @@ namespace Sep.Git.Tfs.Util
|
||||
return customCheckinOptions;
|
||||
}
|
||||
|
||||
public CheckinOptions BuildCommitSpecificCheckinOptions(CheckinOptions sourceCheckinOptions, string commitMessage, GitCommit commit)
|
||||
{
|
||||
var customCheckinOptions = Clone(sourceCheckinOptions);
|
||||
|
||||
customCheckinOptions.CheckinComment = commitMessage;
|
||||
|
||||
ProcessWorkItemCommands(customCheckinOptions, writer);
|
||||
|
||||
ProcessCheckinNoteCommands(customCheckinOptions, writer);
|
||||
|
||||
ProcessForceCommand(customCheckinOptions, writer);
|
||||
|
||||
ProcessAuthor(customCheckinOptions, writer, commit);
|
||||
|
||||
return customCheckinOptions;
|
||||
}
|
||||
|
||||
private CheckinOptions Clone(CheckinOptions source)
|
||||
{
|
||||
CheckinOptions clone = new CheckinOptions();
|
||||
@@ -50,6 +69,8 @@ namespace Sep.Git.Tfs.Util
|
||||
clone.OverrideGatedCheckIn = source.OverrideGatedCheckIn;
|
||||
clone.WorkItemsToAssociate.AddRange(source.WorkItemsToAssociate);
|
||||
clone.WorkItemsToResolve.AddRange(source.WorkItemsToResolve);
|
||||
clone.AuthorsFilePath = source.AuthorsFilePath;
|
||||
clone.AuthorTfsUserId = source.AuthorTfsUserId;
|
||||
foreach (var note in source.CheckinNotes)
|
||||
{
|
||||
clone.CheckinNotes[note.Key] = note.Value;
|
||||
@@ -108,6 +129,8 @@ namespace Sep.Git.Tfs.Util
|
||||
checkinOptions.CheckinComment = GitTfsConstants.TfsReviewerRegex.Replace(checkinOptions.CheckinComment, "").Trim(' ', '\r', '\n');
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ProcessForceCommand(CheckinOptions checkinOptions, TextWriter writer)
|
||||
{
|
||||
MatchCollection workitemMatches;
|
||||
@@ -124,5 +147,32 @@ namespace Sep.Git.Tfs.Util
|
||||
checkinOptions.CheckinComment = GitTfsConstants.TfsForceRegex.Replace(checkinOptions.CheckinComment, "").Trim(' ', '\r', '\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ProcessAuthor(CheckinOptions checkinOptions, TextWriter writer, GitCommit commit)
|
||||
{
|
||||
if (checkinOptions.AuthorsFilePath == null)
|
||||
{
|
||||
writer.WriteLine("Author file was not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// get authors file FIXME
|
||||
AuthorsFile af = new AuthorsFile();
|
||||
TextReader tr = new StreamReader(checkinOptions.AuthorsFilePath);
|
||||
af.Parse(tr);
|
||||
|
||||
Author a = af.FindAuthor(commit.AuthorAndEmail);
|
||||
if (a == null)
|
||||
{
|
||||
checkinOptions.AuthorTfsUserId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
checkinOptions.AuthorTfsUserId = a.TfsUserId;
|
||||
writer.WriteLine("Commit was authored by git user {0} {1} ({2})", a.Name, a.Email, a.TfsUserId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything))
|
||||
.Return(checkinEvaluationResult);
|
||||
@@ -68,6 +69,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
workspace.Expect(w => w.Checkin(
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything,
|
||||
Arg<TfsPolicyOverrideInfo>.Is.Anything,
|
||||
@@ -109,6 +111,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything))
|
||||
.Return(checkinEvaluationResult);
|
||||
@@ -116,6 +119,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
workspace.Expect(w => w.Checkin(
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything,
|
||||
Arg<TfsPolicyOverrideInfo>.Is.Anything,
|
||||
@@ -160,6 +164,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything))
|
||||
.Return(checkinEvaluationResult);
|
||||
@@ -167,6 +172,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
workspace.Expect(w => w.Checkin(
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything,
|
||||
Arg<TfsPolicyOverrideInfo>.Is.Anything,
|
||||
@@ -212,6 +218,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything))
|
||||
.Return(checkinEvaluationResult);
|
||||
@@ -219,6 +226,7 @@ namespace Sep.Git.Tfs.Test.Core
|
||||
workspace.Expect(w => w.Checkin(
|
||||
Arg<IPendingChange[]>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<string>.Is.Anything,
|
||||
Arg<ICheckinNote>.Is.Anything,
|
||||
Arg<IEnumerable<IWorkItemCheckinInfo>>.Is.Anything,
|
||||
Arg<TfsPolicyOverrideInfo>.Is.Anything,
|
||||
|
||||
@@ -53,19 +53,19 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
[Fact]
|
||||
public void AuthorsFileMultiLineRecord()
|
||||
{
|
||||
string author =
|
||||
string author =
|
||||
@"Domain\Test.User = Test User <TestUser@example.com>
|
||||
Domain\Different.User = Three Name User < TestUser@example.com >";
|
||||
AuthorsFile authFile = new AuthorsFile();
|
||||
authFile.Parse(new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(author))));
|
||||
Assert.NotNull(authFile.Authors);
|
||||
Assert.Equal<int>(2, authFile.Authors.Count);
|
||||
|
||||
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Test.User"));
|
||||
Author auth = authFile.Authors[@"Domain\Test.User"];
|
||||
Assert.Equal<string>("Test User", auth.Name);
|
||||
Assert.Equal<string>("TestUser@example.com", auth.Email);
|
||||
|
||||
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Different.User"));
|
||||
auth = authFile.Authors[@"Domain\Different.User"];
|
||||
Assert.Equal<string>("Three Name User", auth.Name);
|
||||
@@ -167,5 +167,114 @@ differentDomain\Blåbærsyltetøy = ÆØÅ User <ÆØÅ@example.com>";
|
||||
Assert.Equal<int>(1, authFile.Authors.Count);
|
||||
Assert.True(authFile.Authors.ContainsKey(@"domain\Blåbærsyltetøy"));
|
||||
}
|
||||
|
||||
|
||||
private string _MergeAuthorsIntoString(string[] authors)
|
||||
{
|
||||
string result = @"";
|
||||
|
||||
for (int i = 0; i < authors.Length; ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
result += Environment.NewLine;
|
||||
|
||||
result += authors[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private AuthorsFile _SetupAuthorsFile(string[] authors)
|
||||
{
|
||||
string author = _MergeAuthorsIntoString(authors);
|
||||
|
||||
AuthorsFile authFile = new AuthorsFile();
|
||||
authFile.Parse(new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(author))));
|
||||
return authFile;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthorsFileMultipleUsers()
|
||||
{
|
||||
string[] authors = {
|
||||
@"Domain\Test.User = Test User <TestUser@example.com>",
|
||||
@"Domain\Different.User = Three Name User < DiffUser@example.com >",
|
||||
@"Domain\Yet.Another.User = Mr. 3 <yau@example.com>"
|
||||
};
|
||||
|
||||
AuthorsFile authFile = _SetupAuthorsFile(authors);
|
||||
|
||||
Assert.Equal<int>(authors.Length, authFile.Authors.Count);
|
||||
Assert.Equal<int>(authors.Length, authFile.AuthorsByGitUserId.Count);
|
||||
|
||||
// contains all tfs users
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Test.User"));
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Different.User"));
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Yet.Another.User"));
|
||||
|
||||
// contains all git users
|
||||
Assert.True(authFile.AuthorsByGitUserId.ContainsKey(Author.BuildGitUserId("TestUser@example.com")));
|
||||
Assert.True(authFile.AuthorsByGitUserId.ContainsKey(Author.BuildGitUserId("DiffUser@example.com")));
|
||||
Assert.True(authFile.AuthorsByGitUserId.ContainsKey(Author.BuildGitUserId("YAU@example.com")));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void AuthorsFileDifferentIdsForUsersWithSameEmail()
|
||||
{
|
||||
string[] authors = {
|
||||
@"Domain\Test.User = Test User <TestUser@example.com>",
|
||||
@"Domain\Different.User = Three Name User < TestUser@example.com >",
|
||||
@"Domain\Yet.Another.User = Mr. 3 <testuser@example.com>"
|
||||
};
|
||||
|
||||
AuthorsFile authFile = _SetupAuthorsFile(authors);
|
||||
|
||||
Assert.NotNull(authFile.AuthorsByGitUserId);
|
||||
|
||||
// multiple users with the same email -> 3 tfs users, 1 git user
|
||||
Assert.Equal<int>(authors.Length, authFile.Authors.Count);
|
||||
Assert.Equal<int>(1, authFile.AuthorsByGitUserId.Count);
|
||||
|
||||
// contains all tfs users
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Test.User"));
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Different.User"));
|
||||
Assert.True(authFile.Authors.ContainsKey(@"Domain\Yet.Another.User"));
|
||||
|
||||
// contains all git users
|
||||
Assert.True(authFile.AuthorsByGitUserId.ContainsKey(Author.BuildGitUserId("TestUser@example.com")));
|
||||
|
||||
// return the first tfs user id in the authors file when multiple
|
||||
// match to the same git id.
|
||||
Tuple<string, string> git_author = new Tuple<string, string>("Test User", "TestUser@example.com");
|
||||
Author a = authFile.FindAuthor(git_author);
|
||||
Assert.NotNull(a);
|
||||
Assert.Equal(a.TfsUserId, @"Domain\Test.User");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void AuthorsFileFindAuthors()
|
||||
{
|
||||
string[] authors = {
|
||||
@"Domain\Test.User = Test User <TestUser@example.com>",
|
||||
@"Domain\Different.User = Three Name User < TestUser@example.com >",
|
||||
@"Domain\Yet.Another.User = Mr. 3 <testuser@example.com>"
|
||||
};
|
||||
|
||||
AuthorsFile authFile = _SetupAuthorsFile(authors);
|
||||
|
||||
// find existing author
|
||||
Tuple<string, string> gitAuthor = new Tuple<string, string>("Test User", "TestUser@example.com");
|
||||
Author existingAuthor = authFile.FindAuthor(gitAuthor);
|
||||
Assert.NotNull(existingAuthor);
|
||||
|
||||
// try to find unknown author
|
||||
Tuple<string, string> gitUnknownAuthor = new Tuple<string, string>("Test User", "TestFailUser@example.com");
|
||||
Author unknownAuthor = authFile.FindAuthor(gitUnknownAuthor);
|
||||
Assert.Null(unknownAuthor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user