197 lines
8.2 KiB
C#
197 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Sep.Git.Tfs.Commands;
|
|
using Sep.Git.Tfs.Core.TfsInterop;
|
|
|
|
namespace Sep.Git.Tfs.Core
|
|
{
|
|
public class TfsWorkspace : ITfsWorkspace
|
|
{
|
|
private readonly IWorkspace _workspace;
|
|
private readonly string _localDirectory;
|
|
private readonly TextWriter _stdout;
|
|
private readonly TfsChangesetInfo _contextVersion;
|
|
private readonly IGitTfsRemote _remote;
|
|
private readonly CheckinOptions _checkinOptions;
|
|
private readonly ITfsHelper _tfsHelper;
|
|
private readonly CheckinPolicyEvaluator _policyEvaluator;
|
|
|
|
public TfsWorkspace(IWorkspace workspace, string localDirectory, TextWriter stdout, TfsChangesetInfo contextVersion, IGitTfsRemote remote, CheckinOptions checkinOptions, ITfsHelper tfsHelper, CheckinPolicyEvaluator policyEvaluator)
|
|
{
|
|
_workspace = workspace;
|
|
_policyEvaluator = policyEvaluator;
|
|
_contextVersion = contextVersion;
|
|
_remote = remote;
|
|
_checkinOptions = checkinOptions;
|
|
_tfsHelper = tfsHelper;
|
|
_localDirectory = localDirectory;
|
|
_stdout = stdout;
|
|
}
|
|
|
|
public void Shelve(string shelvesetName, bool evaluateCheckinPolicies, Func<string> generateCheckinComment)
|
|
{
|
|
var pendingChanges = _workspace.GetPendingChanges();
|
|
|
|
if (pendingChanges.IsEmpty())
|
|
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();
|
|
if (evaluateCheckinPolicies)
|
|
{
|
|
foreach (var message in _policyEvaluator.EvaluateCheckin(_workspace, pendingChanges, shelveset.Comment, null, shelveset.WorkItemInfo).Messages)
|
|
{
|
|
_stdout.WriteLine("[Checkin Policy] " + message);
|
|
}
|
|
}
|
|
_workspace.Shelve(shelveset, pendingChanges, _checkinOptions.Force ? TfsShelvingOptions.Replace : TfsShelvingOptions.None);
|
|
}
|
|
|
|
public long CheckinTool(Func<string> generateCheckinComment)
|
|
{
|
|
var pendingChanges = _workspace.GetPendingChanges();
|
|
|
|
if (pendingChanges.IsEmpty())
|
|
throw new GitTfsException("Nothing to checkin!");
|
|
|
|
var checkinComment = _checkinOptions.CheckinComment;
|
|
if (string.IsNullOrWhiteSpace(checkinComment) && !_checkinOptions.NoGenerateCheckinComment)
|
|
checkinComment = generateCheckinComment();
|
|
|
|
var newChangesetId = _tfsHelper.ShowCheckinDialog(_workspace, pendingChanges, GetWorkItemCheckedInfos(), checkinComment);
|
|
if (newChangesetId <= 0)
|
|
throw new GitTfsException("Checkin cancelled!");
|
|
return newChangesetId;
|
|
}
|
|
|
|
public long Checkin(CheckinOptions options)
|
|
{
|
|
if (options == null) options = _checkinOptions;
|
|
|
|
var pendingChanges = _workspace.GetPendingChanges();
|
|
|
|
if (pendingChanges.IsEmpty())
|
|
throw new GitTfsException("Nothing to checkin!");
|
|
|
|
var workItemInfos = GetWorkItemInfos(options);
|
|
var checkinNote = _tfsHelper.CreateCheckinNote(options.CheckinNotes);
|
|
|
|
var checkinProblems = _policyEvaluator.EvaluateCheckin(_workspace, pendingChanges, options.CheckinComment, checkinNote, workItemInfos);
|
|
if (checkinProblems.HasErrors)
|
|
{
|
|
foreach (var message in checkinProblems.Messages)
|
|
{
|
|
if (options.Force && string.IsNullOrWhiteSpace(options.OverrideReason) == false)
|
|
{
|
|
_stdout.WriteLine("[OVERRIDDEN] " + message);
|
|
}
|
|
else
|
|
{
|
|
_stdout.WriteLine("[ERROR] " + message);
|
|
}
|
|
}
|
|
if (!options.Force)
|
|
{
|
|
throw new GitTfsException("No changes checked in.");
|
|
}
|
|
if (String.IsNullOrWhiteSpace(options.OverrideReason))
|
|
{
|
|
throw new GitTfsException("A reason must be supplied (-f REASON) to override the policy violations.");
|
|
}
|
|
}
|
|
|
|
var policyOverride = GetPolicyOverrides(options, checkinProblems.Result);
|
|
var newChangeset = _workspace.Checkin(pendingChanges, options.CheckinComment, options.AuthorTfsUserId, checkinNote, workItemInfos, policyOverride, options.OverrideGatedCheckIn);
|
|
if (newChangeset == 0)
|
|
{
|
|
throw new GitTfsException("Checkin failed!");
|
|
}
|
|
else
|
|
{
|
|
return newChangeset;
|
|
}
|
|
}
|
|
|
|
private TfsPolicyOverrideInfo GetPolicyOverrides(CheckinOptions options, ICheckinEvaluationResult checkinProblems)
|
|
{
|
|
if (!options.Force || String.IsNullOrWhiteSpace(options.OverrideReason))
|
|
return null;
|
|
return new TfsPolicyOverrideInfo { Comment = options.OverrideReason, Failures = checkinProblems.PolicyFailures };
|
|
}
|
|
|
|
public string GetLocalPath(string path)
|
|
{
|
|
return Path.Combine(_localDirectory, path);
|
|
}
|
|
|
|
public void Add(string path)
|
|
{
|
|
_stdout.WriteLine(" add " + path);
|
|
var added = _workspace.PendAdd(GetLocalPath(path));
|
|
if (added != 1) throw new Exception("One item should have been added, but actually added " + added + " items.");
|
|
}
|
|
|
|
public void Edit(string path)
|
|
{
|
|
_stdout.WriteLine(" edit " + path);
|
|
GetFromTfs(path);
|
|
var edited = _workspace.PendEdit(GetLocalPath(path));
|
|
if (edited != 1) throw new Exception("One item should have been edited, but actually edited " + edited + " items.");
|
|
}
|
|
|
|
public void Delete(string path)
|
|
{
|
|
_stdout.WriteLine(" delete " + path);
|
|
GetFromTfs(path);
|
|
var deleted = _workspace.PendDelete(GetLocalPath(path));
|
|
if (deleted != 1) throw new Exception("One item should have been deleted, but actually deleted " + deleted + " items.");
|
|
}
|
|
|
|
public void Rename(string pathFrom, string pathTo, string score)
|
|
{
|
|
_stdout.WriteLine(" rename " + pathFrom + " to " + pathTo + " (score: " + score + ")");
|
|
GetFromTfs(pathFrom);
|
|
var result = _workspace.PendRename(GetLocalPath(pathFrom), GetLocalPath(pathTo));
|
|
if (result != 1) throw new ApplicationException("Unable to rename item from " + pathFrom + " to " + pathTo);
|
|
}
|
|
|
|
private void GetFromTfs(string path)
|
|
{
|
|
_workspace.ForceGetFile(_remote.TfsRepositoryPath + "/" + path, (int)_contextVersion.ChangesetId);
|
|
}
|
|
|
|
public void Get(int changesetId)
|
|
{
|
|
_workspace.GetSpecificVersion(changesetId);
|
|
}
|
|
|
|
public void Get(IChangeset changeset)
|
|
{
|
|
changeset.Get(_workspace);
|
|
}
|
|
|
|
private IEnumerable<IWorkItemCheckinInfo> GetWorkItemInfos(CheckinOptions options = null)
|
|
{
|
|
return GetWorkItemInfosHelper<IWorkItemCheckinInfo>(_tfsHelper.GetWorkItemInfos, options);
|
|
}
|
|
|
|
private IEnumerable<IWorkItemCheckedInfo> GetWorkItemCheckedInfos()
|
|
{
|
|
return GetWorkItemInfosHelper<IWorkItemCheckedInfo>(_tfsHelper.GetWorkItemCheckedInfos);
|
|
}
|
|
|
|
private IEnumerable<T> GetWorkItemInfosHelper<T>(Func<IEnumerable<string>, TfsWorkItemCheckinAction, IEnumerable<T>> func, CheckinOptions options = null)
|
|
{
|
|
var checkinOptions = options ?? _checkinOptions;
|
|
|
|
var workItemInfos = func(checkinOptions.WorkItemsToAssociate, TfsWorkItemCheckinAction.Associate);
|
|
workItemInfos = workItemInfos.Append(
|
|
func(checkinOptions.WorkItemsToResolve, TfsWorkItemCheckinAction.Resolve));
|
|
return workItemInfos;
|
|
}
|
|
}
|
|
}
|