Skip to content

Commit 1c1b8ee

Browse files
committed
Send output from build and git-tfs to pending changes window
Add cleanup workspaces button
1 parent 070fac1 commit 1c1b8ee

10 files changed

+317
-22
lines changed

BasicSccProvider.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
</ItemGroup>
9595
<ItemGroup>
9696
<Compile Include="Blinkbox\CommandIds.cs" />
97+
<Compile Include="Blinkbox\BuildNotificationLogger.cs" />
98+
<Compile Include="Blinkbox\NotificationWriter.cs" />
9799
<Compile Include="Blinkbox\Events\BlinkboxSccHooks.cs" />
98100
<Compile Include="Blinkbox\BlinkboxScc.cs" />
99101
<Compile Include="Blinkbox\Events\OnPackageInitialiseArgs.cs" />
@@ -107,6 +109,9 @@
107109
<Compile Include="Blinkbox\Options\BlinkboxOptionsPage.cs">
108110
<SubType>Component</SubType>
109111
</Compile>
112+
<Compile Include="PendingChangesView.bb.cs" >
113+
<DependentUpon>PendingChangesView.xaml</DependentUpon>
114+
</Compile>
110115
<Compile Include="GitToolCommands.cs" />
111116
<Compile Include="GitSccOptions.cs" />
112117
<Compile Include="PendingChangesView.xaml.cs">

Blinkbox/BlinkboxScc.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace GitScc.Blinkbox
2424

2525
using Microsoft.Build.Evaluation;
2626
using Microsoft.Build.Execution;
27+
using Microsoft.Build.Framework;
2728
using Microsoft.VisualStudio;
2829
using Microsoft.VisualStudio.OLE.Interop;
2930
using Microsoft.VisualStudio.Shell;
@@ -141,6 +142,7 @@ private int QueryCommandStatus(Guid commandGroupGuid, OLECMD[] commands, OLECMDF
141142

142143
case Blinkbox.CommandIds.GitTfsCheckinButtonId:
143144
case Blinkbox.CommandIds.GitTfsGetLatestButtonId:
145+
case Blinkbox.CommandIds.GitTfsCleanWorkspacesButtonId:
144146
case Blinkbox.CommandIds.GitTfsMenu:
145147
case Blinkbox.CommandIds.GitTfsMenuGroup:
146148
// Disable controls if git-tfs is not found.
@@ -220,6 +222,9 @@ private void DeploySuccessfulCommit(object sender, OnCommitArgs commit)
220222
if (commit.Success)
221223
{
222224
commit.Hash = this.GetLatestCommitHash();
225+
226+
NotificationWriter.Clear();
227+
NotificationWriter.Write("Commit " + commit.Hash + " successful, begin build...");
223228

224229
try
225230
{
@@ -231,6 +236,8 @@ private void DeploySuccessfulCommit(object sender, OnCommitArgs commit)
231236
return;
232237
}
233238

239+
NotificationWriter.Write("Deploy project found at " + buildProjectFileName);
240+
234241
// Initisalise our own project collection which can be cleaned up after the build. This is to prevent caching of the project.
235242
using (var projectCollection = new ProjectCollection(Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.ToolsetLocations))
236243
{
@@ -246,13 +253,17 @@ private void DeploySuccessfulCommit(object sender, OnCommitArgs commit)
246253
var msbuildProject = new ProjectInstance(buildProjectFileName, globalProperties, "4.0", projectCollection);
247254

248255
// Build it
249-
WriteToStatusBar("Build " + Path.GetFileNameWithoutExtension(msbuildProject.FullPath));
256+
WriteToStatusBar("Building " + Path.GetFileNameWithoutExtension(msbuildProject.FullPath));
250257
var buildRequest = new BuildRequestData(msbuildProject, new string[] { });
251-
var result = BuildManager.DefaultBuildManager.Build(new BuildParameters(projectCollection), buildRequest);
258+
259+
var buildParams = new BuildParameters(projectCollection);
260+
buildParams.Loggers = new List<ILogger>() { new BuildNotificationLogger() { Verbosity = LoggerVerbosity.Normal } };
261+
262+
var result = BuildManager.DefaultBuildManager.Build(buildParams, buildRequest);
252263

253264
if (result.OverallResult == BuildResultCode.Failure)
254265
{
255-
string message = result.Exception == null ? "Unknown error" : result.Exception.Message;
266+
string message = result.Exception == null ? "Unknown error: please see output window." : result.Exception.Message;
256267
MessageBox.Show(message, "Build failed", MessageBoxButton.OK, MessageBoxImage.Error);
257268
return;
258269
}
@@ -266,6 +277,7 @@ private void DeploySuccessfulCommit(object sender, OnCommitArgs commit)
266277

267278
// Clean up project to prevent caching.
268279
projectCollection.UnloadAllProjects();
280+
projectCollection.UnregisterAllLoggers();
269281
}
270282
}
271283
catch (Exception exc)

Blinkbox/BuildNotificationLogger.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="BuildNotificationLogger.cs" company="blinkbox">
3+
// TODO: Update copyright text.
4+
// </copyright>
5+
// <summary>
6+
// </summary>
7+
// --------------------------------------------------------------------------------------------------------------------
8+
9+
namespace GitScc.Blinkbox
10+
{
11+
using System.Diagnostics;
12+
13+
using Microsoft.Build.Framework;
14+
15+
/// <summary>
16+
/// Sends build messages to the VS output window
17+
/// </summary>
18+
public class BuildNotificationLogger : ILogger
19+
{
20+
/// <summary>
21+
/// Gets or sets Verbosity.
22+
/// </summary>
23+
public LoggerVerbosity Verbosity
24+
{
25+
get;
26+
set;
27+
}
28+
29+
/// <summary>
30+
/// Gets or sets Parameters.
31+
/// </summary>
32+
public string Parameters
33+
{
34+
get;
35+
set;
36+
}
37+
38+
39+
/// <summary>
40+
/// Initialises the logger.
41+
/// </summary>
42+
/// <param name="buildEventSource">
43+
/// The event source.
44+
/// </param>
45+
public void Initialize(IEventSource buildEventSource)
46+
{
47+
if (this.Verbosity == LoggerVerbosity.Diagnostic)
48+
{
49+
buildEventSource.MessageRaised += (sender, args) => NotificationWriter.Write(args.Message);
50+
buildEventSource.TargetFinished += (sender, args) => Trace.WriteLine(args.Message);
51+
}
52+
53+
buildEventSource.WarningRaised += (sender, args) => NotificationWriter.Write(args.Message);
54+
buildEventSource.ErrorRaised += (sender, args) => NotificationWriter.Write(args.Message);
55+
buildEventSource.BuildStarted += (sender, args) => NotificationWriter.Write(args.Message);
56+
buildEventSource.BuildFinished += (sender, args) => NotificationWriter.Write(args.Message);
57+
}
58+
59+
/// <summary>
60+
/// Cleans up.
61+
/// </summary>
62+
public void Shutdown()
63+
{
64+
}
65+
}
66+
}

Blinkbox/CommandIds.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,10 @@ public class CommandIds
3838
/// Identifies the GitTfsGetLatest command.
3939
/// </summary>
4040
public const int GitTfsGetLatestButtonId = 0x404;
41+
42+
/// <summary>
43+
/// Identifies the GitTfs CleanWorkspaces command.
44+
/// </summary>
45+
public const int GitTfsCleanWorkspacesButtonId = 0x405;
4146
}
4247
}

Blinkbox/GitTfs.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class GitTfs
1616
/// <summary>
1717
/// Commands which appear in the git tfs menu
1818
/// </summary>
19-
private static readonly List<GitTfsCommand> menuOptions = new List<GitTfsCommand> { Commands.Checkin, Commands.GetLatest };
19+
private static readonly List<GitTfsCommand> menuOptions = new List<GitTfsCommand> { Commands.Checkin, Commands.GetLatest, Commands.CleanWorkspace };
2020

2121
/// <summary>
2222
/// Gets the menu options.
@@ -33,16 +33,32 @@ public static List<GitTfsCommand> MenuOptions
3333
/// <summary>
3434
/// Runs a command in the git tfs commandline environment.
3535
/// </summary>
36-
/// <param name="command">The command.</param>
37-
/// <param name="workingDirectory">The working directory.</param>
36+
/// <param name="command">
37+
/// The command.
38+
/// </param>
39+
/// <param name="workingDirectory">
40+
/// The working directory.
41+
/// </param>
3842
public static void RunGitTfsCommand(string command, string workingDirectory)
3943
{
40-
var processStartInfo = new ProcessStartInfo("cmd.exe", "/k git tfs " + command);
41-
processStartInfo.UseShellExecute = false;
42-
processStartInfo.CreateNoWindow = false;
43-
processStartInfo.WorkingDirectory = workingDirectory;
44-
processStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
45-
System.Diagnostics.Process.Start(processStartInfo);
44+
var process = new System.Diagnostics.Process();
45+
process.StartInfo = new ProcessStartInfo("cmd.exe", "/k git tfs " + command);
46+
process.StartInfo.UseShellExecute = false;
47+
process.StartInfo.CreateNoWindow = true;
48+
process.StartInfo.WorkingDirectory = workingDirectory;
49+
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
50+
51+
// Write output to the pending changes window
52+
NotificationWriter.Clear();
53+
NotificationWriter.NewSection("Git-Tfs " + command);
54+
process.StartInfo.RedirectStandardOutput = true;
55+
process.StartInfo.RedirectStandardError = true;
56+
process.OutputDataReceived += (sender, args) => NotificationWriter.Write(args.Data);
57+
process.ErrorDataReceived += (sender, args) => NotificationWriter.Write(args.Data);
58+
59+
process.Start();
60+
process.BeginOutputReadLine();
61+
process.BeginErrorReadLine();
4662
}
4763

4864
/// <summary>
@@ -59,6 +75,11 @@ public struct Commands
5975
/// Get latest command syntax.
6076
/// </summary>
6177
public static readonly GitTfsCommand GetLatest = new GitTfsCommand { Name = "Get Latest", CommandText = "pull", CommandId = Blinkbox.CommandIds.GitTfsGetLatestButtonId };
78+
79+
/// <summary>
80+
/// cleanup workspace command syntax.
81+
/// </summary>
82+
public static readonly GitTfsCommand CleanWorkspace = new GitTfsCommand { Name = "Clean Workspace", CommandText = "cleanup-workspaces", CommandId = Blinkbox.CommandIds.GitTfsCleanWorkspacesButtonId };
6283
}
6384

6485
/// <summary>

Blinkbox/NotificationWriter.cs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="NotificationWriter.cs" company="blinkbox">
3+
// TODO: Update copyright text.
4+
// </copyright>
5+
// <summary>
6+
// </summary>
7+
// --------------------------------------------------------------------------------------------------------------------
8+
9+
namespace GitScc.Blinkbox
10+
{
11+
using System;
12+
using System.Collections.Concurrent;
13+
using System.Threading;
14+
15+
/// <summary>
16+
/// This class is repsonsible for writing messages into Visual Studio Output Window.
17+
/// </summary>
18+
public class NotificationWriter
19+
{
20+
/// <summary>
21+
/// Lock for singleton initialisation.
22+
/// </summary>
23+
private static readonly object sync = new object();
24+
25+
/// <summary>
26+
/// A queue of the messages.
27+
/// </summary>
28+
private readonly ConcurrentQueue<string> messages = new ConcurrentQueue<string>();
29+
30+
/// <summary>
31+
/// A thread for writing messages to the output window.
32+
/// </summary>
33+
private readonly Thread processingThread;
34+
35+
/// <summary>
36+
/// The singleton instance of the NotificationWriter.
37+
/// </summary>
38+
private static NotificationWriter instance = null;
39+
40+
/// <summary>
41+
/// Initializes a new instance of the <see cref="NotificationWriter"/> class.
42+
/// </summary>
43+
public NotificationWriter()
44+
{
45+
this.processingThread = new Thread(this.ProcessMessages);
46+
this.processingThread.Start();
47+
}
48+
49+
/// <summary>
50+
/// Gets a singleton Instance.
51+
/// </summary>
52+
private static NotificationWriter Instance
53+
{
54+
get
55+
{
56+
if (instance == null)
57+
{
58+
lock (sync)
59+
{
60+
instance = instance ?? new NotificationWriter();
61+
}
62+
}
63+
64+
return instance;
65+
}
66+
}
67+
68+
/// <summary>
69+
/// Writes a message into our output pane.
70+
/// </summary>
71+
/// <param name="message">Message to write.</param>
72+
public static void Write(string message)
73+
{
74+
Instance.messages.Enqueue(message);
75+
}
76+
77+
/// <summary>
78+
/// Writes a new section to the output window.
79+
/// </summary>
80+
/// <param name="name">
81+
/// The name.
82+
/// </param>
83+
public static void NewSection(string name)
84+
{
85+
Write(Environment.NewLine + "#### " + name + " ############################################");
86+
}
87+
88+
/// <summary>
89+
/// Clears the output pane.
90+
/// </summary>
91+
public static void Clear()
92+
{
93+
PendingChangesView.ClearDiffEditor();
94+
}
95+
96+
/// <summary>
97+
/// Periodically checks for messages and writes them to the output window.
98+
/// </summary>
99+
private void ProcessMessages()
100+
{
101+
while (true)
102+
{
103+
this.WriteMessageQueue();
104+
System.Threading.Thread.Sleep(500);
105+
}
106+
}
107+
108+
/// <summary>
109+
/// Writes all mesages in the queue to the output window.
110+
/// </summary>
111+
private void WriteMessageQueue()
112+
{
113+
while (!this.messages.IsEmpty)
114+
{
115+
string message = null;
116+
this.messages.TryDequeue(out message);
117+
if (!string.IsNullOrEmpty(message))
118+
{
119+
PendingChangesView.WriteToDiffWindow(message);
120+
}
121+
}
122+
}
123+
}
124+
}

GitSccOptions.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ public class GitSccOptions
1414
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
1515
"gitscc.config");
1616

17-
public string GitBashPath { get; set; }
18-
public string GitTfsPath { get; set; }
17+
public string GitBashPath { get; set; }
1918
public string GitExtensionPath { get; set; }
2019
public string DifftoolPath { get; set; }
2120
public string TortoiseGitPath { get; set; }
@@ -81,13 +80,6 @@ private void Init()
8180
@"C:\Program Files (x86)\Git\bin\sh.exe",
8281
});
8382
}
84-
if (string.IsNullOrEmpty(GitTfsPath))
85-
{
86-
GitTfsPath = TryFindFile(new string[]{
87-
@"C:\Program Files\Git-tfs\git-tfs.exe",
88-
@"C:\Program Files (x86)\Git-tfs\git-tfs.exe",
89-
});
90-
}
9183
if (string.IsNullOrEmpty(GitExtensionPath))
9284
{
9385
GitExtensionPath = TryFindFile(new string[]{

0 commit comments

Comments
 (0)