Wednesday, June 20, 2012

NuGet integration in LinqPad

NuGet is amazing in Visual Studio. With it I can easily download and add references to popular libraries in my project with only a few clicks in Manage NuGet Packages or keystrokes when using the Package Manager Console. I really like that because I can try out new libraries without too much effort. I also like LinqPad to try out snippets of code. But if I want to try a library I have to download the binaries from a web site, unzip them on my disk and finally add references to the assemblies from my query before I can start to play around with it.

The new version of LinqPad (v4.42.04 currently still in beta) finally gets an integration with NuGet directly in the tool but only with the Premium Edition. Let's take a look at how it works.

In the Query Properties (F4) we have a new option: Add NuGet...


This will open the NuGet Manager window


On the left we can see all the NuGet packages we already downloaded. Those will be stored in our local AppData folder and be available for all queries. In the middle section we have the NuGet feed search where we can browse for packages to download. Finally in the section on the right we see all the information on the currently selected package.

To add a package to the current query simply click Add To Query. If the package was not already downloaded LinqPad will do it now and after that it will appear in the left section. Finally we can select namespaces to use in the query by clicking Add namespace.

LinqPad will also automatically check for updates for us so we just have to click Update next to the package. All the queries using this package will get updated to the latest version too.

We are not limited to the official NuGet feed but we could also add new feeds to connect to, even our own if we wish. We can add new feeds by clicking the Settings button in the lower left of the window.


Here we can add a remote feed or a local folder if we wish. After that we'll have the option to choose which feed to use in the main NuGet Manager window using the list down the middle section.

Going back to the Query Properties window all the packages we added will be shown as a reference with the location set to NuGet. If we click on NuGet we can see the current version of the package and an option to Show assemblies in this package.


Here we can exclude some assemblies from the package if we need to.

One additional FREE new feature this time we get in this version is the ability to browse for namespaces to add from existing references. In the Additional Namespace Imports tab click on Pick from assemblies


We can now select one assembly to see the list of available namespaces from it. Then simply select the namespaces we want and click Add Selected Namespaces.

Summary

I know that not everyone have the Premium version of LinqPad but still I wanted to show you what appends when 2 amazing productivity tools collide! I guess it is possible to use some NuGet Powershell cmdlet to do part of the job. It think a stand alone NuGet client could be a good idea for someone to come up with too.

Anyway, hope you get the chance to play with those two together

Saturday, June 9, 2012

TFS Queries: Build agents status and build queue

For an intro on LinqPad and the TFS API please read this post
For the list of all the posts in this series please read this one

Context


Sometimes it's hard to figure out exactly why a build is pending and not running right after it was queued. It can be because the build agents are currently busy building other builds, or because build agents are not started or even because the windows services for the build agents are not running. Looking at the Build Explorer we can only see builds from one team project at a time which is not ideal when you have a lot of them.

Fortunately we can create a LinqPad query to get all this information in one report.

Required references


Microsoft.TeamFoundation.Build.Client
Microsoft.TeamFoundation.Client
Microsoft.TeamFoundation.Framework.Client
System.ServiceProcess

Query (C# Statements)

var tfs = TfsTeamProjectCollectionFactory
 .GetTeamProjectCollection(new Uri("http://localhost:8088/tfs"));

tfs.EnsureAuthenticated();

var buildServer = tfs.GetService<IBuildServer>();

var queryAgents = buildServer.QueryBuildAgents(buildServer.CreateBuildAgentSpec());
queryAgents.Agents
 .Select(x => new
 {
  x.MachineName,
  Controller = x.Controller.Name,
  x.Enabled,
  x.Status,
  x.QueueCount
 })
 .Dump("TFS build agents");

queryAgents.Agents
 .SelectMany(x => ServiceController.GetServices(x.ServiceHost.Name)
  .Where(s => s.ServiceName.StartsWith("TFSBuildServiceHost")))
 .Select(x => new
 {
  x.MachineName,
  x.ServiceName,
  x.Status
 })
 .Dump("Windows Services of build agents");
 
buildServer
 .QueryQueuedBuilds(buildServer.CreateBuildQueueSpec("*"))
 .QueuedBuilds
 .Select(x => new
 {
  x.TeamProject,
  BuildDefinition = x.BuildDefinition.Name,
  x.QueuePosition,
  x.QueueTime,
  x.Priority,
  x.CustomGetVersion,
  x.RequestedFor,
  x.Reason,
  x.Status
 })
 .OrderBy(x => x.QueuePosition)
 .Dump("Queued builds");


Result


We get a list of the build agents status. Then the state of the windows services running the build agents. Finally the full content of the build queue regardless of the team project.

TFS build agents

IEnumerable<> (2 items)
MachineName Controller Enabled Status QueueCount
Server4 Server4 -

Controller
False Available 0
Server1 Server1 -

Controller
True Available 3
3

Windows Services of build agents

IEnumerable<> (2 items)
MachineName ServiceName Status
Server4 TFSBuildServiceHost Running
Server1 TFSBuildServiceHost Running
Queued builds

IOrderedEnumerable<> (3 items)
TeamProject BuildDefinition QueuePosition QueueTime Priority CustomGetVersion RequestedFor Reason Status
Project1 CI 1 2012-06-01 16:58:32 Normal C3243 Pascal IndividualCI InProgress
Project1 Daily 2 2012-06-01 16:58:32 Normal C3243 Pascal IndividualCI Queued
Project1 Performance 3 2012-06-01 16:58:32 Normal C3243 Pascal IndividualCI Queued
6