Index: Tools/Google.Apis.Release/Repositories/Hg.cs
===================================================================
rename from Tools/Google.Build.Utils/Repositories/Hg.cs
rename to Tools/Google.Apis.Release/Repositories/Hg.cs
--- a/Tools/Google.Build.Utils/Repositories/Hg.cs
+++ b/Tools/Google.Apis.Release/Repositories/Hg.cs
@@ -22,33 +22,26 @@
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
-using Google.Apis.Samples.Helper;
+using Google.Apis.Utils;
+using Google.Apis.Utils.Trace;
-namespace Google.Build.Utils.Repositories
+namespace Google.Apis.Release.Repositories
{
- ///
- /// Mercurial interfacing class
- ///
+ /// Mercurial repository interface class.
public sealed class Hg : IDisposable
{
- ///
- /// Name of the repository.
- ///
+ static readonly TraceSource TraceSource = new TraceSource("Google.Apis");
+
+ /// Gets the name of the repository.summary>
public string Name { get; private set; }
- ///
- /// The URI of the repositoty
- ///
+ /// Gets the URI of the repository
public Uri RepositoryUri { get; private set; }
- ///
- /// The local working directory.
- ///
+ /// Gets the local working directory.
public string WorkingDirectory { get; private set; }
- ///
- /// True if this working copy has pending changes.
- ///
+ /// Gets indication if repository has pending changes.
public bool HasUncommitedChanges
{
get
@@ -58,9 +51,7 @@
}
}
- ///
- /// True if there are unpulled, incoming changes.
- ///
+ /// Gets indication if there are incoming changes.
public bool HasIncomingChanges
{
get
@@ -77,16 +68,14 @@
}
}
- ///
- /// True if this working copy has unpushed changes.
- ///
+ /// Gets indication if the working copy has un-pushed changes.
public bool HasUnpushedChanges
{
get
{
try
{
- string[] changes = RunListeningHg("outgoing {0} {1}", "-l", "1");
+ string[] changes = RunListeningHg(string.Format("outgoing {0} {1}", "-l", "1"));
return changes.Length >= 4;
}
catch (ExternalException)
@@ -99,12 +88,13 @@
}
}
- private Hg(Uri repositoryUri)
- : this(repositoryUri, Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()))
- {
-
- }
- private Hg(Uri repositoryUri, string localDir)
+ ///
+ /// Constructs a new repository. It creates a new repository if the folder doesn't exists, otherwise it gets
+ /// the current status of the repository.
+ ///
+ /// The URI of this repository
+ /// The local directory which contains the repository files
+ public Hg(Uri repositoryUri, string localDir)
{
RepositoryUri = repositoryUri;
WorkingDirectory = Path.GetFullPath(localDir);
@@ -112,19 +102,18 @@
if (!Directory.Exists(WorkingDirectory))
{
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Fetching {1}", Name, repositoryUri);
Directory.CreateDirectory(WorkingDirectory);
- this.CloneFrom(repositoryUri);
+ RunHg(string.Format("clone {0} {1}", repositoryUri.ToString(), WorkingDirectory));
}
else
{
- CommandLine.WriteAction("Using existing repository for " + Name + " at " + WorkingDirectory + " ..");
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Using an existing repository", Name);
RunHg("status");
}
}
- ///
- /// Commits the pending changes.
- ///
+ /// Commits the pending changes.
/// Description of the changes/the commit.
/// Whether a commit was made/possible.
public bool Commit(string message)
@@ -136,54 +125,30 @@
RunHg("status -m -a -r");
- CommandLine.WriteAction("Commiting changes of " + Name + " ..");
- RunHg("commit -m \"{0}\"", message);
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Committing changes", Name);
+ RunHg(string.Format("commit -m \"{0}\"", message));
return true;
}
- ///
- /// Adds a tag to the last revision.
- ///
+ /// Adds a tag to the last revision.
/// The tag to add.
///
- /// If set to true will overwrite existing labels of this name see "hg help tag" and its
- /// --force parameter.
+ /// If set to true will overwrite existing labels of this name see "hg help tag" and its --force parameter.
///
public void Tag(string tagName, bool force = false)
{
- CommandLine.WriteAction("Tagging " + Name + " with " + tagName + "..");
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Tagging with {1}", Name, tagName);
string options = (force ? "-f " : "");
- RunHg("tag {0}\"{1}\"", options, tagName);
+ RunHg(string.Format("tag {0}\"{1}\"", options, tagName));
}
- ///
- /// Adds all unversioned files to the current commit.
- ///
- public void AddUnversionedFiles()
+ /// Adds all unversioned files and remove all versioned files.
+ public void AddRemoveFiles()
{
- RunHg("add");
+ RunHg("addremove");
}
- ///
- /// Marks all versioned files which have been deleted as removed.
- ///
- public void RemoveDeletedFiles()
- {
- var missingFiles = RunListeningHg("status -d")
- .Where(l => l.StartsWith("! "))
- .Select(l => "\"" + l.Substring("! ".Length) + "\"");
-
- string files = String.Join(" ", missingFiles);
- if (!string.IsNullOrEmpty(files))
- {
- CommandLine.WriteAction("Removing files: " + files);
- RunHg("remove {0}", files);
- }
- }
-
- ///
- /// Pushes all commited changes to the server.
- ///
+ /// Pushes all committed changes to the server.
public void Push()
{
if (!HasUnpushedChanges)
@@ -191,99 +156,63 @@
return;
}
- CommandLine.WriteAction("Pushing " + Name + " ..");
- RunShellHg("push");
+ TraceSource.TraceEvent(TraceEventType.Information, "Pushing {0}", Name);
+ RunHg("push");
}
- /// Updates the repository by the branch name.
- ///
+ /// Updates the repository by the branch name.
public void Update(string branchName)
{
- CommandLine.WriteAction("Updating branch to " + branchName);
- RunShellHg("update " + branchName);
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Updating branch to {1}", Name, branchName);
+ RunHg("update " + branchName);
}
- ///
- /// Pulls and updates this clone.
- ///
- public void PullUpdate()
- {
- RunShellHg("hg pull");
- RunShellHg("hg update");
- }
-
- ///
- /// Outputs the diff to the default output stream.
- ///
- public void ShowDiff()
- {
- RunShellHg("diff");
- }
-
- ///
- /// Creates the combined path of the specified directories.
- ///
+ /// Creates the combined path of the specified directories.
public string Combine(params string[] dirs)
{
return dirs.Aggregate(WorkingDirectory, Path.Combine);
}
- ///
- /// Creates a change list by listing all changes made since the last release.
- ///
+ /// Creates a change list by listing all changes made since the last release.
public IEnumerable CreateChangelist()
{
Regex tagRegex = new Regex("Added tag [0-9A-Za-z.-]+ for changeset [^b]+", RegexOptions.Compiled);
string branch = RunListeningHg("branch").Single();
- return RunListeningHg("log --template \"{{rev}}: {{desc}}\\r\\n\" -b {0}", branch)
+ return RunListeningHg(string.Format("log --template \"{{rev}}: {{desc}}\\r\\n\" -b {0}", branch))
.TakeWhile(line => !tagRegex.IsMatch(line));
}
- private void CloneFrom(Uri uri)
+ /// Runs a HG command. In addition it prints errors and messages to trace.
+ private void RunHg(string command)
{
- CommandLine.WriteAction("Fetching " + uri + " ..");
- RunHg("clone {0} {1}", uri.ToString(), WorkingDirectory);
+ RunHg(command,
+ error =>
+ {
+ if (!string.IsNullOrEmpty(error))
+ {
+ TraceSource.TraceEvent(TraceEventType.Error, "[{0}] {1}", Name, error);
+ }
+ },
+ msg =>
+ {
+ if (!string.IsNullOrEmpty(msg))
+ {
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] hg {1}", Name, msg);
+ }
+ });
}
- private void RunShellHg(string command, params string[] args)
- {
- RunHg(command, null, null, args);
- }
-
- private void RunHg(string command, params string[] args)
- {
- RunHg(
- command, error =>
- {
- if (!string.IsNullOrEmpty(error))
- {
- CommandLine.WriteError(error);
- }
- }, msg =>
- {
- if (!string.IsNullOrEmpty(msg))
- {
- CommandLine.WriteResult("hg", msg);
- }
- }, args);
- }
-
- private string[] RunListeningHg(string command, params string[] args)
- {
- var msgs = new List();
- RunHg(command, msgs.Add, msgs.Add, args);
- return msgs.ToArray();
- }
-
- private void RunHg(string command, Action errors, Action msgs, params string[] args)
+ ///
+ /// Run a HG command which the specific callback for errors or messages returned from the command.
+ ///
+ private void RunHg(string command, Action errorCallback = null, Action messageCallback = null)
{
var process = new Process();
- string commandLine = string.Format(command, args);
- process.StartInfo = new ProcessStartInfo("hg", commandLine);
+ process.StartInfo = new ProcessStartInfo("hg", command);
process.StartInfo.WorkingDirectory = WorkingDirectory;
- if (errors != null || msgs != null)
+ if (errorCallback != null || messageCallback != null)
{
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
@@ -292,31 +221,31 @@
}
process.Start();
-
- if (errors != null)
+ if (errorCallback != null)
{
process.ErrorDataReceived += (sender, msg) =>
- {
- if (msg.Data != null)
- {
- errors(msg.Data);
- }
- };
+ {
+ if (msg.Data != null)
+ {
+ errorCallback(msg.Data);
+ }
+ };
process.BeginErrorReadLine();
}
- if (msgs != null)
+ if (messageCallback != null)
{
process.OutputDataReceived += (sender, msg) =>
- {
- if (msg.Data != null)
- {
- msgs(msg.Data);
- }
- };
+ {
+ if (msg.Data != null)
+ {
+ messageCallback(msg.Data);
+ }
+ };
process.BeginOutputReadLine();
}
process.WaitForExit();
+
if (process.ExitCode != 0)
{
string cmdLine = process.StartInfo.FileName + " " + process.StartInfo.Arguments;
@@ -324,27 +253,17 @@
}
}
- ///
- /// Clones a new Mercurial repository.
- ///
- public static Hg Clone(string repository)
+ /// Runs a HG command and returns all its errors and messages output.
+ private string[] RunListeningHg(string command)
{
- return new Hg(new Uri(repository));
- }
-
- ///
- /// Reuses the existing local repository, or creates a new clone of it does not exist.
- ///
- /// The local Mercurial repository.
- /// The remote URL.
- public static Hg Get(string localDir, string repository)
- {
- return new Hg(new Uri(repository), localDir);
+ var msgs = new List();
+ RunHg(command, msgs.Add, msgs.Add);
+ return msgs.ToArray();
}
public void Dispose()
{
- CommandLine.WriteAction("Cleaning up " + Name + " ..");
+ TraceSource.TraceEvent(TraceEventType.Information, "[{0}] Cleaning up", Name);
Directory.Delete(WorkingDirectory, true);
}
}