diff --git a/Playground/CruiseControl.Command/Command.cs b/Playground/CruiseControl.Command/Command.cs
new file mode 100644
index 000000000..0cb78b6b6
--- /dev/null
+++ b/Playground/CruiseControl.Command/Command.cs
@@ -0,0 +1,15 @@
+namespace CruiseControl.Command
+{
+ public class Command
+ {
+ #region Public properties
+ #region Name
+ public string Name { get; set; }
+ #endregion
+
+ #region Arguments
+ public string[] Arguments { get; set; }
+ #endregion
+ #endregion
+ }
+}
diff --git a/Playground/CruiseControl.Command/CruiseControl.Command.csproj b/Playground/CruiseControl.Command/CruiseControl.Command.csproj
index a90aa42b3..258bae7bb 100644
--- a/Playground/CruiseControl.Command/CruiseControl.Command.csproj
+++ b/Playground/CruiseControl.Command/CruiseControl.Command.csproj
@@ -43,6 +43,7 @@
+
diff --git a/Playground/CruiseControl.Command/Program.cs b/Playground/CruiseControl.Command/Program.cs
index dbfffb59c..1330c60e4 100644
--- a/Playground/CruiseControl.Command/Program.cs
+++ b/Playground/CruiseControl.Command/Program.cs
@@ -1,5 +1,8 @@
namespace CruiseControl.Command
{
+ using System;
+ using System.Diagnostics;
+ using System.Linq;
using CruiseControl.Common;
class Program
@@ -7,7 +10,113 @@ class Program
static void Main(string[] args)
{
var connection = new ServerConnection(args[0]);
- connection.Ping();
+ var exit = false;
+ WriteToConsole(ConsoleColor.White, "CruiseControl.NET: Interactive Console");
+ WriteToConsole(ConsoleColor.White, new string('=', 40));
+ WriteToConsole(ConsoleColor.Yellow, "Retrieving server name...");
+ var fullUrn = connection.RetrieveServerName();
+ WriteToConsole(ConsoleColor.Yellow, "...server name is '{0}'", fullUrn);
+ var shortUrn = fullUrn.Substring(10);
+ while (!exit)
+ {
+ Console.Write(shortUrn + ">");
+ var command = ReadFromConsole();
+ switch (command.Name)
+ {
+ case "exit":
+ exit = true;
+ break;
+
+ case "ping":
+ RunPingCommand(connection);
+ break;
+
+ case "query":
+ RunQueryCommand(connection, fullUrn);
+ break;
+
+ case "invoke":
+ RunInvokeCommand(connection, fullUrn, command.Arguments);
+ break;
+ }
+ }
+ }
+
+ private static Command ReadFromConsole()
+ {
+ var input = Console.ReadLine();
+ var parts = input.Split(' ');
+ var command = new Command();
+ if (parts.Length > 0)
+ {
+ command.Name = parts[0].ToLowerInvariant();
+ command.Arguments = parts.Skip(1).ToArray();
+ }
+
+ return command;
+ }
+
+ private static void WriteToConsole(ConsoleColor colour, string message, params object[] args)
+ {
+ var oldColour = Console.ForegroundColor;
+ try
+ {
+ Console.ForegroundColor = colour;
+ Console.WriteLine(message, args);
+ }
+ finally
+ {
+ Console.ForegroundColor = oldColour;
+ }
+ }
+
+ private static void RunPingCommand(ServerConnection connection)
+ {
+ WriteToConsole(ConsoleColor.Yellow, "Sending ping...");
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ var result = connection.Ping();
+ stopwatch.Stop();
+ if (result)
+ {
+ WriteToConsole(ConsoleColor.Yellow, "...ping received in {0}ms", stopwatch.ElapsedMilliseconds);
+ }
+ else
+ {
+ WriteToConsole(ConsoleColor.Red, "...ping failed!", stopwatch.ElapsedMilliseconds);
+ }
+ }
+
+ private static void RunQueryCommand(ServerConnection connection, string fullUrn)
+ {
+ WriteToConsole(ConsoleColor.Yellow, "Querying '{0}'...", fullUrn);
+ try
+ {
+ var result = connection.Query(fullUrn);
+ WriteToConsole(ConsoleColor.Yellow, "...{0} action(s) retrieved", result.Length);
+ foreach (var action in result)
+ {
+ WriteToConsole(ConsoleColor.White, "\t{0}", action.Name);
+ }
+ }
+ catch (Exception error)
+ {
+ WriteToConsole(ConsoleColor.Red, "...failed: " + error.Message);
+ }
+ }
+
+ private static void RunInvokeCommand(ServerConnection connection, string fullUrn, string[] arguments)
+ {
+ WriteToConsole(ConsoleColor.Yellow, "Invoking '{1}' on '{0}'...", fullUrn, arguments[0]);
+ try
+ {
+ var result = connection.Invoke(fullUrn, arguments[0], arguments.Skip(1).ToArray());
+ WriteToConsole(ConsoleColor.Yellow, "...completed");
+ }
+ catch (Exception error)
+ {
+ WriteToConsole(ConsoleColor.Red, "...failed: " + error.Message);
+ }
}
}
}
diff --git a/Playground/CruiseControl.Common/CruiseControl.Common.csproj b/Playground/CruiseControl.Common/CruiseControl.Common.csproj
index b78a79582..8d7de7171 100644
--- a/Playground/CruiseControl.Common/CruiseControl.Common.csproj
+++ b/Playground/CruiseControl.Common/CruiseControl.Common.csproj
@@ -43,6 +43,8 @@
+
+
diff --git a/Playground/CruiseControl.Common/Messages/ServerItem.cs b/Playground/CruiseControl.Common/Messages/ServerItem.cs
new file mode 100644
index 000000000..de14d9415
--- /dev/null
+++ b/Playground/CruiseControl.Common/Messages/ServerItem.cs
@@ -0,0 +1,40 @@
+namespace CruiseControl.Common.Messages
+{
+ ///
+ /// An item on the server.
+ ///
+ public class ServerItem
+ {
+ #region Public properties
+ #region DisplayName
+ ///
+ /// Gets or sets the display name.
+ ///
+ ///
+ /// The display name.
+ ///
+ public string DisplayName { get; set; }
+ #endregion
+
+ #region Urn
+ ///
+ /// Gets or sets the URN.
+ ///
+ ///
+ /// The URN of the item.
+ ///
+ public string Urn { get; set; }
+ #endregion
+
+ #region Description
+ ///
+ /// Gets or sets the description.
+ ///
+ ///
+ /// The description.
+ ///
+ public string Description { get; set; }
+ #endregion
+ #endregion
+ }
+}
diff --git a/Playground/CruiseControl.Common/Messages/ServerItemList.cs b/Playground/CruiseControl.Common/Messages/ServerItemList.cs
new file mode 100644
index 000000000..72534c965
--- /dev/null
+++ b/Playground/CruiseControl.Common/Messages/ServerItemList.cs
@@ -0,0 +1,20 @@
+namespace CruiseControl.Common.Messages
+{
+ ///
+ /// A blank message.
+ ///
+ public class ServerItemList
+ {
+ #region Public properties
+ #region Children
+ ///
+ /// Gets or sets the children.
+ ///
+ ///
+ /// The children.
+ ///
+ public ServerItem[] Children { get; set; }
+ #endregion
+ #endregion
+ }
+}
diff --git a/Playground/CruiseControl.Console/CruiseControl.Console.csproj b/Playground/CruiseControl.Console/CruiseControl.Console.csproj
index 3e6cf2053..be5a77046 100644
--- a/Playground/CruiseControl.Console/CruiseControl.Console.csproj
+++ b/Playground/CruiseControl.Console/CruiseControl.Console.csproj
@@ -50,6 +50,10 @@
+
+ {166D519E-854D-4405-9FAE-C6825CF7BBE6}
+ CruiseControl.Common
+
{74405CD5-BD3D-4912-A465-F929FA20220B}
CruiseControl.Core
diff --git a/Playground/CruiseControl.Core.Tests/ServerTests.cs b/Playground/CruiseControl.Core.Tests/ServerTests.cs
index 9142bb2b4..62d9a42b3 100644
--- a/Playground/CruiseControl.Core.Tests/ServerTests.cs
+++ b/Playground/CruiseControl.Core.Tests/ServerTests.cs
@@ -188,6 +188,17 @@ public void CloseCommunicationsCleansUpEachChannel()
server.CloseCommunications();
Assert.IsTrue(cleaned);
}
+
+ [Test]
+ public void ListProjectsIncludesAllProjects()
+ {
+ var server = new Server(
+ "test",
+ new Project("project1"),
+ new Project("project2"));
+ var result = server.ListProjects(null);
+ Assert.AreEqual(2, result.Children.Length);
+ }
#endregion
}
}
diff --git a/Playground/CruiseControl.Core/Server.cs b/Playground/CruiseControl.Core/Server.cs
index 69ab5de1f..8cf882e88 100644
--- a/Playground/CruiseControl.Core/Server.cs
+++ b/Playground/CruiseControl.Core/Server.cs
@@ -11,6 +11,7 @@
using CruiseControl.Core.Utilities;
using Ninject;
using NLog;
+ using Messages = CruiseControl.Common.Messages;
///
/// The root configuration node.
@@ -235,6 +236,34 @@ public virtual void Validate(IValidationLog validationLog)
#endregion
#endregion
+ #region Actions
+ #region ListProjects()
+ ///
+ /// Lists the projects on the server.
+ ///
+ /// The request containing the details.
+ /// A message containing the response details.
+ [RemoteAction]
+ [Description("Lists the projects on the server.")]
+ public virtual Messages.ServerItemList ListProjects(Messages.Blank request)
+ {
+ var projects = this.Children.SelectMany(c => c.ListProjects());
+ var response = new Messages.ServerItemList
+ {
+ Children = projects
+ .Select(p => new Messages.ServerItem
+ {
+ Description = p.Description,
+ DisplayName = p.Name,
+ Urn = p.UniversalName
+ })
+ .ToArray()
+ };
+ return response;
+ }
+ #endregion
+ #endregion
+
#region Private methods
#region LocateInChildren()
///
diff --git a/Playground/CruiseControl.Core/ServerItem.cs b/Playground/CruiseControl.Core/ServerItem.cs
index 8f9f5a590..a55ee1db9 100644
--- a/Playground/CruiseControl.Core/ServerItem.cs
+++ b/Playground/CruiseControl.Core/ServerItem.cs
@@ -42,6 +42,14 @@ protected ServerItem(string name)
public string Name { get; set; }
#endregion
+ #region Description
+ ///
+ /// Gets the description.
+ ///
+ [DefaultValue(null)]
+ public string Description { get; set; }
+ #endregion
+
#region ItemType
///
/// Gets the type of the item.