Files
git-tfs/GitTfs/Commands/Labels.cs

150 lines
5.6 KiB
C#

using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NDesk.Options;
using Sep.Git.Tfs.Core;
using StructureMap;
using Sep.Git.Tfs.Util;
namespace Sep.Git.Tfs.Commands
{
[Pluggable("labels")]
[Description("labels [options] [tfsRemoteId]\n ex : git tfs labels\n git tfs labels -i myRemoteBranche\n git tfs labels --all")]
[RequiresValidGitRepository]
public class Labels : GitTfsCommand
{
private readonly TextWriter _stdout;
private readonly Globals _globals;
private readonly AuthorsFile _authors;
private RemoteOptions _remoteOptions;
public string TfsUsername { get; set; }
public string TfsPassword { get; set; }
public string ParentBranch { get; set; }
public bool LabelAllBranches { get; set; }
public string NameFilter { get; set; }
public string ExcludeNameFilter { get; set; }
string AuthorsFilePath { get; set; }
public Labels(TextWriter stdout, Globals globals, AuthorsFile authors)
{
this._stdout = stdout;
this._globals = globals;
this._authors = authors;
}
public OptionSet OptionSet
{
get
{
return new OptionSet
{
{ "all|fetch-all", "Fetch all the labels on all the TFS remotes (For TFS 2010 and later)", v => LabelAllBranches = v != null },
{ "n|label-name=", "Fetch all the labels respecting this name filter", v => NameFilter = v },
{ "e|exclude-label-name=", "Exclude all the labels respecting this regex name filter", v => ExcludeNameFilter = v },
{ "u|username=", "TFS username", v => TfsUsername = v },
{ "p|password=", "TFS password", v => TfsPassword = v },
{ "a|authors=", "Path to an Authors file to map TFS users to Git users", v => AuthorsFilePath = v },
};
}
}
public int Run(IGitTfsRemote remote)
{
return CreateLabelsForTfsBranch(remote);
}
private int Run(string remoteId)
{
var tfsRemote = _globals.Repository.ReadTfsRemote(remoteId);
if (tfsRemote == null)
throw new GitTfsException("error: No git-tfs repository found. Please try to clone first...\n");
_authors.Parse(AuthorsFilePath, _globals.GitDir);
return CreateLabelsForTfsBranch(tfsRemote);
}
public int Run()
{
if (!LabelAllBranches)
{
return Run(_globals.RemoteId);
}
var allRemotes = _globals.Repository.ReadAllTfsRemotes();
_authors.Parse(AuthorsFilePath, _globals.GitDir);
foreach (var tfsRemote in allRemotes)
{
CreateLabelsForTfsBranch(tfsRemote);
}
return GitTfsExitCodes.OK;
}
private int CreateLabelsForTfsBranch(IGitTfsRemote tfsRemote)
{
if (string.IsNullOrWhiteSpace(NameFilter))
NameFilter = null;
else
NameFilter = NameFilter.Trim();
UpdateRemote(tfsRemote);
_stdout.WriteLine("Looking for label on " + tfsRemote.TfsRepositoryPath + "...");
var labels = tfsRemote.Tfs.GetLabels(tfsRemote.TfsRepositoryPath, NameFilter);
_stdout.WriteLine(labels.Count() +" labels found!");
Regex exludeRegex = null;
if (ExcludeNameFilter != null)
exludeRegex = new Regex(ExcludeNameFilter);
foreach (var label in labels)
{
if (ExcludeNameFilter != null && exludeRegex.IsMatch(label.Name))
continue;
Trace.WriteLine("LabelId:" + label.Id + "/ChangesetId:" + label.ChangesetId + "/LabelName:" + label.Name + "/Owner:" + label.Owner);
Trace.WriteLine("Try to find changeset in git repository...");
string sha1TagCommit = _globals.Repository.FindCommitHashByCommitMessage("git-tfs-id: .*;C" + label.ChangesetId + "[^0-9]");
if (string.IsNullOrWhiteSpace(sha1TagCommit))
{
Trace.WriteLine("This label does not match an existing commit...");
continue;
}
Trace.WriteLine("Commit found! sha1 : " + sha1TagCommit);
string ownerName;
string ownerEmail;
if(_authors.Authors.ContainsKey(label.Owner))
{
var author = _authors.Authors[label.Owner];
ownerName = author.Name;
ownerEmail = author.Email;
}
else
{
ownerName = label.Owner;
ownerEmail = label.Owner;
}
var labelName = (label.IsTransBranch ? label.Name + "(" + tfsRemote.Id + ")" : label.Name).ToGitRefName();
_stdout.WriteLine("Writing label '" + labelName + "'...");
_globals.Repository.CreateTag(labelName, sha1TagCommit, label.Comment, ownerName, ownerEmail ,label.Date);
}
return GitTfsExitCodes.OK;
}
private void UpdateRemote(IGitTfsRemote tfsRemote)
{
if (!string.IsNullOrWhiteSpace(TfsUsername))
{
tfsRemote.TfsUsername = TfsUsername;
tfsRemote.TfsPassword = TfsPassword;
}
}
}
}