Merge pull request #912 from NathanLBCooper/master
Automatically Associate work items with a shelve command.
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Sep.Git.Tfs.Commands
|
||||
{
|
||||
private readonly TextWriter _stdout;
|
||||
private readonly CheckinOptions _checkinOptions;
|
||||
private readonly CommitSpecificCheckinOptionsFactory _checkinOptionsFactory;
|
||||
private readonly CheckinOptionsFactory _checkinOptionsFactory;
|
||||
private readonly TfsWriter _writer;
|
||||
private readonly Globals _globals;
|
||||
private readonly AuthorsFile _authors;
|
||||
@@ -28,7 +28,7 @@ namespace Sep.Git.Tfs.Commands
|
||||
{
|
||||
_stdout = stdout;
|
||||
_checkinOptions = checkinOptions;
|
||||
_checkinOptionsFactory = new CommitSpecificCheckinOptionsFactory(_stdout, globals, authors);
|
||||
_checkinOptionsFactory = new CheckinOptionsFactory(_stdout, globals);
|
||||
_writer = writer;
|
||||
_globals = globals;
|
||||
_authors = authors;
|
||||
@@ -131,7 +131,7 @@ namespace Sep.Git.Tfs.Commands
|
||||
var parents = commit.Parents.Where(c => c.Sha != currentParent).ToArray();
|
||||
string tfsRepositoryPathOfMergedBranch = FindTfsRepositoryPathOfMergedBranch(tfsRemote, parents, target);
|
||||
|
||||
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, message, commit);
|
||||
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, message, commit, _authors);
|
||||
|
||||
_stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
|
||||
try
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.IO;
|
||||
using NDesk.Options;
|
||||
using Sep.Git.Tfs.Core;
|
||||
using Sep.Git.Tfs.Util;
|
||||
using StructureMap;
|
||||
|
||||
namespace Sep.Git.Tfs.Commands
|
||||
@@ -13,14 +14,18 @@ namespace Sep.Git.Tfs.Commands
|
||||
{
|
||||
private readonly TextWriter _stdout;
|
||||
private readonly CheckinOptions _checkinOptions;
|
||||
private readonly CheckinOptionsFactory _checkinOptionsFactory;
|
||||
private readonly TfsWriter _writer;
|
||||
private readonly Globals _globals;
|
||||
|
||||
private bool EvaluateCheckinPolicies { get; set; }
|
||||
|
||||
public Shelve(TextWriter stdout, CheckinOptions checkinOptions, TfsWriter writer)
|
||||
public Shelve(TextWriter stdout, CheckinOptions checkinOptions, TfsWriter writer, Globals globals)
|
||||
{
|
||||
_stdout = stdout;
|
||||
_globals = globals;
|
||||
_checkinOptions = checkinOptions;
|
||||
_checkinOptionsFactory = new CheckinOptionsFactory(_stdout, _globals);
|
||||
_writer = writer;
|
||||
}
|
||||
|
||||
@@ -52,9 +57,25 @@ namespace Sep.Git.Tfs.Commands
|
||||
_stdout.WriteLine("Shelveset \"" + shelvesetName + "\" already exists. Use -f to replace it.");
|
||||
return GitTfsExitCodes.ForceRequired;
|
||||
}
|
||||
changeset.Remote.Shelve(shelvesetName, referenceToShelve, changeset, EvaluateCheckinPolicies);
|
||||
|
||||
var commit = _globals.Repository.GetCommit(refToShelve);
|
||||
var message = commit != null // this is only null in the unit tests
|
||||
? BuildCommitMessage(commit, !_checkinOptions.NoGenerateCheckinComment,
|
||||
changeset.Remote.MaxCommitHash)
|
||||
: string.Empty;
|
||||
|
||||
var shelveSpecificCheckinOptions = _checkinOptionsFactory.BuildShelveSetSpecificCheckinOptions(_checkinOptions, message);
|
||||
|
||||
changeset.Remote.Shelve(shelvesetName, referenceToShelve, changeset, shelveSpecificCheckinOptions, EvaluateCheckinPolicies);
|
||||
return GitTfsExitCodes.OK;
|
||||
});
|
||||
}
|
||||
|
||||
public string BuildCommitMessage(GitCommit commit, bool generateCheckinComment, string latest)
|
||||
{
|
||||
return generateCheckinComment
|
||||
? _globals.Repository.GetCommitMessage(commit.Sha, latest)
|
||||
: _globals.Repository.GetCommit(commit.Sha).Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace Sep.Git.Tfs.Core
|
||||
throw DerivedRemoteException;
|
||||
}
|
||||
|
||||
public void Shelve(string shelvesetName, string treeish, TfsChangesetInfo parentChangeset, bool evaluateCheckinPolicies)
|
||||
public void Shelve(string shelvesetName, string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options, bool evaluateCheckinPolicies)
|
||||
{
|
||||
throw DerivedRemoteException;
|
||||
}
|
||||
|
||||
@@ -846,9 +846,9 @@ namespace Sep.Git.Tfs.Core
|
||||
Repository.UpdateRef(destinationRef, commit, "Shelveset " + shelvesetName + " from " + shelvesetOwner);
|
||||
}
|
||||
|
||||
public void Shelve(string shelvesetName, string head, TfsChangesetInfo parentChangeset, bool evaluateCheckinPolicies)
|
||||
public void Shelve(string shelvesetName, string head, TfsChangesetInfo parentChangeset, CheckinOptions options, bool evaluateCheckinPolicies)
|
||||
{
|
||||
WithWorkspace(parentChangeset, workspace => Shelve(shelvesetName, head, parentChangeset, evaluateCheckinPolicies, workspace));
|
||||
WithWorkspace(parentChangeset, workspace => Shelve(shelvesetName, head, parentChangeset, options, evaluateCheckinPolicies, workspace));
|
||||
}
|
||||
|
||||
public bool HasShelveset(string shelvesetName)
|
||||
@@ -856,10 +856,10 @@ namespace Sep.Git.Tfs.Core
|
||||
return Tfs.HasShelveset(shelvesetName);
|
||||
}
|
||||
|
||||
private void Shelve(string shelvesetName, string head, TfsChangesetInfo parentChangeset, bool evaluateCheckinPolicies, ITfsWorkspace workspace)
|
||||
private void Shelve(string shelvesetName, string head, TfsChangesetInfo parentChangeset, CheckinOptions options, bool evaluateCheckinPolicies, ITfsWorkspace workspace)
|
||||
{
|
||||
PendChangesToWorkspace(head, parentChangeset.GitCommit, workspace);
|
||||
workspace.Shelve(shelvesetName, evaluateCheckinPolicies, () => Repository.GetCommitMessage(head, parentChangeset.GitCommit));
|
||||
workspace.Shelve(shelvesetName, evaluateCheckinPolicies, options);
|
||||
}
|
||||
|
||||
public int CheckinTool(string head, TfsChangesetInfo parentChangeset)
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Sep.Git.Tfs.Core
|
||||
void QuickFetch();
|
||||
void QuickFetch(int changesetId);
|
||||
void Unshelve(string shelvesetOwner, string shelvesetName, string destinationBranch, Action<Exception> ignorableErrorHandler, bool force);
|
||||
void Shelve(string shelvesetName, string treeish, TfsChangesetInfo parentChangeset, bool evaluateCheckinPolicies);
|
||||
void Shelve(string shelvesetName, string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options, bool evaluateCheckinPolicies);
|
||||
bool HasShelveset(string shelvesetName);
|
||||
int CheckinTool(string head, TfsChangesetInfo parentChangeset);
|
||||
int Checkin(string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null);
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Sep.Git.Tfs.Core
|
||||
/// <summary>
|
||||
/// Shelves all pending changes, with the given shelveset name.
|
||||
/// </summary>
|
||||
void Shelve(string shelvesetName, bool evaluateCheckinPolicies, Func<string> generateCheckinComment);
|
||||
void Shelve(string shelvesetName, bool evaluateCheckinPolicies, CheckinOptions checkinOptions);
|
||||
/// <summary>
|
||||
/// Evaluates check-in policies and checks in all pending changes.
|
||||
/// </summary>
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Sep.Git.Tfs.Core
|
||||
this.Remote = remote;
|
||||
}
|
||||
|
||||
public void Shelve(string shelvesetName, bool evaluateCheckinPolicies, Func<string> generateCheckinComment)
|
||||
public void Shelve(string shelvesetName, bool evaluateCheckinPolicies, CheckinOptions checkinOptions)
|
||||
{
|
||||
var pendingChanges = _workspace.GetPendingChanges();
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace Sep.Git.Tfs.Core
|
||||
throw new GitTfsException("Nothing to shelve!");
|
||||
|
||||
var shelveset = _tfsHelper.CreateShelveset(_workspace, shelvesetName);
|
||||
shelveset.Comment = string.IsNullOrWhiteSpace(_checkinOptions.CheckinComment) && !_checkinOptions.NoGenerateCheckinComment ? generateCheckinComment() : _checkinOptions.CheckinComment;
|
||||
shelveset.WorkItemInfo = GetWorkItemInfos().ToArray();
|
||||
shelveset.Comment = checkinOptions.CheckinComment;
|
||||
shelveset.WorkItemInfo = GetWorkItemInfos(checkinOptions).ToArray();
|
||||
if (evaluateCheckinPolicies)
|
||||
{
|
||||
foreach (var message in _policyEvaluator.EvaluateCheckin(_workspace, pendingChanges, shelveset.Comment, null, shelveset.WorkItemInfo).Messages)
|
||||
|
||||
@@ -202,10 +202,11 @@
|
||||
<Compile Include="Util\AuthorsFile.cs" />
|
||||
<Compile Include="Util\Bouncer.cs" />
|
||||
<Compile Include="Util\ChangeSieve.cs" />
|
||||
<Compile Include="Util\CheckinOptionsExtensions.cs" />
|
||||
<Compile Include="Util\ConfigPropertyLoader.cs" />
|
||||
<Compile Include="Util\ExportMetadatasInitializer.cs" />
|
||||
<Compile Include="Util\PathResolver.cs" />
|
||||
<Compile Include="Util\CommitSpecificCheckinOptionsFactory.cs" />
|
||||
<Compile Include="Util\CheckinOptionsFactory.cs" />
|
||||
<Compile Include="Core\GitTfsVersionProvider.cs" />
|
||||
<Compile Include="Util\ExceptionFormattingExtensions.cs" />
|
||||
<Compile Include="Util\GitTfsCommandFactory.cs" />
|
||||
|
||||
+11
-64
@@ -1,67 +1,14 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Sep.Git.Tfs.Commands;
|
||||
using Sep.Git.Tfs.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
using StructureMap;
|
||||
|
||||
namespace Sep.Git.Tfs.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CheckinOptions"/> that is customized based
|
||||
/// on extracting special git-tfs commands from a git commit message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class handles the pre-checkin commit message parsing that
|
||||
/// enables special git-tfs commands:
|
||||
/// https://github.com/git-tfs/git-tfs/blob/master/doc/Special-actions-in-commit-messages.md
|
||||
/// </remarks>
|
||||
public class CommitSpecificCheckinOptionsFactory
|
||||
public static class CheckinOptionsExtensions
|
||||
{
|
||||
private readonly TextWriter writer;
|
||||
private readonly Globals globals;
|
||||
private AuthorsFile authors;
|
||||
|
||||
public CommitSpecificCheckinOptionsFactory(TextWriter writer, Globals globals, AuthorsFile authors)
|
||||
{
|
||||
this.writer = writer;
|
||||
this.globals = globals;
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public CheckinOptions BuildCommitSpecificCheckinOptions(CheckinOptions sourceCheckinOptions, string commitMessage)
|
||||
{
|
||||
var customCheckinOptions = Clone(sourceCheckinOptions);
|
||||
|
||||
customCheckinOptions.CheckinComment = commitMessage;
|
||||
|
||||
ProcessWorkItemCommands(customCheckinOptions, writer);
|
||||
|
||||
ProcessCheckinNoteCommands(customCheckinOptions, writer);
|
||||
|
||||
ProcessForceCommand(customCheckinOptions, writer);
|
||||
|
||||
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)
|
||||
public static CheckinOptions Clone(this CheckinOptions source, Globals globals)
|
||||
{
|
||||
CheckinOptions clone = new CheckinOptions();
|
||||
|
||||
@@ -94,18 +41,19 @@ namespace Sep.Git.Tfs.Util
|
||||
return clone;
|
||||
}
|
||||
|
||||
private void ProcessWorkItemCommands(CheckinOptions checkinOptions, TextWriter writer)
|
||||
public static void ProcessWorkItemCommands(this CheckinOptions checkinOptions, TextWriter writer, bool isResolvable = true)
|
||||
{
|
||||
MatchCollection workitemMatches;
|
||||
if ((workitemMatches = GitTfsConstants.TfsWorkItemRegex.Matches(checkinOptions.CheckinComment)).Count > 0)
|
||||
{
|
||||
foreach (Match match in workitemMatches)
|
||||
{
|
||||
if (match.Groups["action"].Value == "resolve")
|
||||
if (isResolvable && match.Groups["action"].Value == "resolve")
|
||||
{
|
||||
writer.WriteLine("Resolving work item {0}", match.Groups["item_id"]);
|
||||
checkinOptions.WorkItemsToResolve.Add(match.Groups["item_id"].Value);
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
writer.WriteLine("Associating with work item {0}", match.Groups["item_id"]);
|
||||
checkinOptions.WorkItemsToAssociate.Add(match.Groups["item_id"].Value);
|
||||
}
|
||||
@@ -131,7 +79,7 @@ namespace Sep.Git.Tfs.Util
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessCheckinNoteCommands(CheckinOptions checkinOptions, TextWriter writer)
|
||||
public static void ProcessCheckinNoteCommands(this CheckinOptions checkinOptions, TextWriter writer)
|
||||
{
|
||||
foreach (Match match in GitTfsConstants.TfsReviewerRegex.Matches(checkinOptions.CheckinComment))
|
||||
{
|
||||
@@ -160,7 +108,7 @@ namespace Sep.Git.Tfs.Util
|
||||
|
||||
|
||||
|
||||
private void ProcessForceCommand(CheckinOptions checkinOptions, TextWriter writer)
|
||||
public static void ProcessForceCommand(this CheckinOptions checkinOptions, TextWriter writer)
|
||||
{
|
||||
MatchCollection workitemMatches;
|
||||
if ((workitemMatches = GitTfsConstants.TfsForceRegex.Matches(checkinOptions.CheckinComment)).Count == 1)
|
||||
@@ -179,7 +127,7 @@ namespace Sep.Git.Tfs.Util
|
||||
|
||||
|
||||
|
||||
private void ProcessAuthor(CheckinOptions checkinOptions, TextWriter writer, GitCommit commit)
|
||||
public static void ProcessAuthor(this CheckinOptions checkinOptions, TextWriter writer, GitCommit commit, AuthorsFile authors)
|
||||
{
|
||||
if (!authors.IsParseSuccessfull)
|
||||
return;
|
||||
@@ -194,6 +142,5 @@ namespace Sep.Git.Tfs.Util
|
||||
checkinOptions.AuthorTfsUserId = a.TfsUserId;
|
||||
writer.WriteLine("Commit was authored by git user {0} {1} ({2})", a.Name, a.Email, a.TfsUserId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.IO;
|
||||
using Sep.Git.Tfs.Commands;
|
||||
using Sep.Git.Tfs.Core;
|
||||
|
||||
namespace Sep.Git.Tfs.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CheckinOptions"/> that is customized based
|
||||
/// on extracting special git-tfs commands from a git commit message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class handles the pre-checkin commit message parsing that
|
||||
/// enables special git-tfs commands:
|
||||
/// https://github.com/git-tfs/git-tfs/blob/master/doc/Special-actions-in-commit-messages.md
|
||||
/// </remarks>
|
||||
public class CheckinOptionsFactory
|
||||
{
|
||||
private readonly TextWriter writer;
|
||||
private readonly Globals globals;
|
||||
|
||||
public CheckinOptionsFactory(TextWriter writer, Globals globals)
|
||||
{
|
||||
this.writer = writer;
|
||||
this.globals = globals;
|
||||
}
|
||||
|
||||
public CheckinOptions BuildCommitSpecificCheckinOptions(CheckinOptions sourceCheckinOptions, string commitMessage)
|
||||
{
|
||||
var customCheckinOptions = sourceCheckinOptions.Clone(this.globals);
|
||||
|
||||
customCheckinOptions.CheckinComment = commitMessage;
|
||||
|
||||
customCheckinOptions.ProcessWorkItemCommands(writer);
|
||||
|
||||
customCheckinOptions.ProcessCheckinNoteCommands(writer);
|
||||
|
||||
customCheckinOptions.ProcessForceCommand(writer);
|
||||
|
||||
return customCheckinOptions;
|
||||
}
|
||||
|
||||
public CheckinOptions BuildCommitSpecificCheckinOptions(CheckinOptions sourceCheckinOptions,
|
||||
string commitMessage, GitCommit commit, AuthorsFile authors)
|
||||
{
|
||||
var customCheckinOptions = BuildCommitSpecificCheckinOptions(sourceCheckinOptions, commitMessage);
|
||||
|
||||
customCheckinOptions.ProcessAuthor(writer, commit, authors);
|
||||
|
||||
return customCheckinOptions;
|
||||
}
|
||||
|
||||
public CheckinOptions BuildShelveSetSpecificCheckinOptions(CheckinOptions sourceCheckinOptions,
|
||||
string commitMessage)
|
||||
{
|
||||
var customCheckinOptions = sourceCheckinOptions.Clone(this.globals);
|
||||
|
||||
customCheckinOptions.CheckinComment = commitMessage;
|
||||
|
||||
customCheckinOptions.ProcessWorkItemCommands(writer, false);
|
||||
|
||||
return customCheckinOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,8 +118,8 @@ namespace Sep.Git.Tfs.Test.Commands
|
||||
|
||||
mocks.ClassUnderTest.Run("shelveset name");
|
||||
|
||||
remote.AssertWasCalled(x => x.Shelve(null, null, null, false),
|
||||
y => y.Constraints(Is.Equal("shelveset name"), Is.Equal("HEAD"), Is.Anything(), Is.Anything()));
|
||||
remote.AssertWasCalled(x => x.Shelve(null, null, null, null, false),
|
||||
y => y.Constraints(Is.Equal("shelveset name"), Is.Equal("HEAD"), Is.Anything(), Is.Anything(), Is.Anything()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -135,8 +135,8 @@ namespace Sep.Git.Tfs.Test.Commands
|
||||
|
||||
mocks.ClassUnderTest.Run("shelveset name", "treeish");
|
||||
|
||||
remote.AssertWasCalled(x => x.Shelve(null, null, null, false),
|
||||
y => y.Constraints(Is.Equal("shelveset name"), Is.Equal("treeish"), Is.Anything(), Is.Anything()));
|
||||
remote.AssertWasCalled(x => x.Shelve(null, null, null, null, false),
|
||||
y => y.Constraints(Is.Equal("shelveset name"), Is.Equal("treeish"), Is.Anything(), Is.Anything(), Is.Anything()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -158,7 +158,7 @@ namespace Sep.Git.Tfs.Test.Commands
|
||||
mocks.ClassUnderTest.Run("shelveset name", "treeish");
|
||||
|
||||
mocks.Get<IGitTfsRemote>().AssertWasNotCalled(
|
||||
x => x.Shelve(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<TfsChangesetInfo>.Is.Anything, Arg<bool>.Is.Anything));
|
||||
x => x.Shelve(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<TfsChangesetInfo>.Is.Anything, Arg<CheckinOptions>.Is.Anything, Arg<bool>.Is.Anything));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -171,7 +171,7 @@ namespace Sep.Git.Tfs.Test.Commands
|
||||
mocks.ClassUnderTest.Run("shelveset name", "treeish");
|
||||
|
||||
mocks.Get<IGitTfsRemote>().AssertWasCalled(
|
||||
x => x.Shelve(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<TfsChangesetInfo>.Is.Anything, Arg<bool>.Is.Anything));
|
||||
x => x.Shelve(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<TfsChangesetInfo>.Is.Anything, Arg<CheckinOptions>.Is.Anything, Arg<bool>.Is.Anything));
|
||||
}
|
||||
|
||||
private TfsChangesetInfo ChangesetForRemote(string remoteId)
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
<Compile Include="Util\CommitSpecificCheckinOptionsFactoryTests.cs" />
|
||||
<Compile Include="Util\GitTfsCommandRunnerTests.cs" />
|
||||
<Compile Include="Util\BouncerTest.cs" />
|
||||
<Compile Include="Util\ShelveSpecificCheckinOptionsFactoryTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GitTfs.VsFake\GitTfs.VsFake.csproj">
|
||||
|
||||
@@ -12,15 +12,15 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
public class CommitSpecificCheckinOptionsFactoryTests
|
||||
{
|
||||
private RhinoAutoMocker<CommitSpecificCheckinOptionsFactory> mocks;
|
||||
private RhinoAutoMocker<CheckinOptionsFactory> mocks;
|
||||
|
||||
public CommitSpecificCheckinOptionsFactoryTests()
|
||||
{
|
||||
mocks = new RhinoAutoMocker<CommitSpecificCheckinOptionsFactory>();
|
||||
mocks = new RhinoAutoMocker<CheckinOptionsFactory>();
|
||||
mocks.Get<Globals>().Repository = mocks.Get<IGitRepository>();
|
||||
}
|
||||
|
||||
private CommitSpecificCheckinOptionsFactory GetCommitSpecificCheckinOptions(string workItemRegex = null)
|
||||
private CheckinOptionsFactory GetCheckinOptionsFactory(string workItemRegex = null)
|
||||
{
|
||||
IGitRepository gitRepository = mocks.Get<IGitRepository>();
|
||||
mocks.Get<Globals>().Repository = gitRepository;
|
||||
@@ -28,7 +28,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
gitRepository.Stub(r => r.GitDir).Return(".");
|
||||
gitRepository.Stub(r => r.GetConfig(GitTfsConstants.WorkItemAssociateRegexConfigKey)).Return(workItemRegex);
|
||||
|
||||
return new CommitSpecificCheckinOptionsFactory(new StringWriter(), mocks.Get<Globals>(), new AuthorsFile());
|
||||
return new CheckinOptionsFactory(new StringWriter(), mocks.Get<Globals>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -44,7 +44,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
|
||||
formatted git commit message";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(singletonCheckinOptions, commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(singletonCheckinOptions, commitMessage);
|
||||
Assert.Equal(commitMessage, specificCheckinOptions.CheckinComment);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
|
||||
";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("1234", specificCheckinOptions.WorkItemsToAssociate);
|
||||
@@ -78,7 +78,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
|
||||
git-tfs-work-item: 1234";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("5676", specificCheckinOptions.WorkItemsToAssociate);
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions(@"workitem id:(?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory(@"workitem id:(?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(0, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem id:5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions(@"workitem id:(?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory(@"workitem id:(?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("5676", specificCheckinOptions.WorkItemsToAssociate);
|
||||
}
|
||||
@@ -116,7 +116,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions(@"workitem id:((?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory(@"workitem id:((?<item_id>\d+)").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(0, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions(@"").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory(@"").BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("5676", specificCheckinOptions.WorkItemsToAssociate);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #56p76";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("56", specificCheckinOptions.WorkItemsToAssociate);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
string commitMessage = @"test workitem #f5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(0, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
string commitMessage = @"test workitem #5676 1 only
|
||||
git-tfs-work-item: 1234";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(2, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("1234", specificCheckinOptions.WorkItemsToAssociate);
|
||||
Assert.Contains("5676", specificCheckinOptions.WorkItemsToAssociate);
|
||||
@@ -167,7 +167,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
string commitMessage = @"test workitem #5676
|
||||
git-tfs-work-item: 5676";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("5676", specificCheckinOptions.WorkItemsToAssociate);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
|
||||
";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToResolve.Count);
|
||||
Assert.Contains("1234", specificCheckinOptions.WorkItemsToResolve);
|
||||
Assert.Equal(expectedCheckinComment.Replace(Environment.NewLine, "NEWLINE"), specificCheckinOptions.CheckinComment.Replace(Environment.NewLine, "NEWLINE"));
|
||||
@@ -211,7 +211,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
|
||||
";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToResolve.Count);
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("1234", specificCheckinOptions.WorkItemsToResolve);
|
||||
@@ -238,7 +238,7 @@ namespace Sep.Git.Tfs.Test.Util
|
||||
"Some more information,\n" +
|
||||
"in a paragraph.";
|
||||
|
||||
var specificCheckinOptions = GetCommitSpecificCheckinOptions().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildCommitSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
Assert.Equal(3, specificCheckinOptions.CheckinNotes.Count);
|
||||
Assert.Equal("John Smith", specificCheckinOptions.CheckinNotes["Code Reviewer"]);
|
||||
Assert.Equal("Teddy Knox", specificCheckinOptions.CheckinNotes["Security Reviewer"]);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.IO;
|
||||
using Sep.Git.Tfs.Commands;
|
||||
using Sep.Git.Tfs.Core;
|
||||
using Sep.Git.Tfs.Util;
|
||||
using StructureMap.AutoMocking;
|
||||
using Xunit;
|
||||
|
||||
namespace Sep.Git.Tfs.Test.Util
|
||||
{
|
||||
public class ShelveSpecificCheckinOptionsFactoryTests
|
||||
{
|
||||
private RhinoAutoMocker<CheckinOptionsFactory> mocks;
|
||||
|
||||
public ShelveSpecificCheckinOptionsFactoryTests()
|
||||
{
|
||||
mocks = new RhinoAutoMocker<CheckinOptionsFactory>();
|
||||
mocks.Get<Globals>().Repository = mocks.Get<IGitRepository>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Adds_work_item_to_associate_and_removes_checkin_command_comment()
|
||||
{
|
||||
string commitMessage = @"test message
|
||||
|
||||
formatted git commit message
|
||||
|
||||
git-tfs-work-item: 1234 associate";
|
||||
|
||||
string expectedCheckinComment = @"test message
|
||||
|
||||
formatted git commit message
|
||||
|
||||
";
|
||||
|
||||
var specificCheckinOptions = GetCheckinOptionsFactory().BuildShelveSetSpecificCheckinOptions(new CheckinOptions(), commitMessage);
|
||||
|
||||
Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
|
||||
Assert.Contains("1234", specificCheckinOptions.WorkItemsToAssociate);
|
||||
Assert.Equal(expectedCheckinComment, specificCheckinOptions.CheckinComment);
|
||||
}
|
||||
|
||||
private CheckinOptionsFactory GetCheckinOptionsFactory()
|
||||
{
|
||||
return new CheckinOptionsFactory(new StringWriter(), mocks.Get<Globals>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
## Summary
|
||||
Creates a TFS shelveset from a Git branch.
|
||||
|
||||
## Features
|
||||
[Special actions in commit messages](../special-actions-in-commit-messages.md) can be inserted, to associate TFS work items.
|
||||
|
||||
## Synopsis
|
||||
|
||||
Usage: git-tfs shelve [options] shelveset-name [ref-to-shelve]
|
||||
where options are:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
* Shelve commands can be automatically associated with work items (#908)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The [rcheckin](commands/rcheckin.md) command examines the commmit message for additional TFS specific
|
||||
The [rcheckin](commands/rcheckin.md) command examines the commit message for additional TFS specific
|
||||
notifications. The following may be appended as separate lines to the end of the commit message:
|
||||
|
||||
* `git-tfs-work-item: <id>` will link the new changeset with the given work item and the default action type.
|
||||
@@ -8,6 +8,10 @@ notifications. The following may be appended as separate lines to the end of the
|
||||
* `git-tfs-performance-reviewer: <name>` sets the Performance Reviewer field.
|
||||
* `git-tfs-force: <reason>` will force the checkin, overriding TFS checkin policies with the given reason.
|
||||
|
||||
The [shelve](commands/shelve.md) command also examines the commit message for the following TFS specific notifications, in the same matter as the rcheckin command:
|
||||
|
||||
* `git-tfs-work-item: <id>` will link the new changeset with the given work item and the default action type.
|
||||
|
||||
Additionally the text of the message is searched for work item IDs. If a string matching a # followed
|
||||
by a valid work-item ID number is found, then the commit will be associated with the specified TFS work-item.
|
||||
For cases where this may be undesirable, the default match may be overridden by setting the
|
||||
|
||||
Reference in New Issue
Block a user