TFS: Query for builds containing a specific changeset - build

I have a number of build definitions that get executed based upon a single branch in TFS (eg Main).
I'd like to (somehow) query TFS to find all builds containing a specific changeset number that I supply, and return a list of string of the names of the builds that TFS contains. Any kind of app (VS extension, CLI app, winforms, whatever) will do.
Note: this isn't a 'plz give me the code' request; I'm willing to hoof it and do serious work on this. Any pointers to documentation on how to query the database or SDK, or an example of how to query builds; just some place to start looking would be extremely helpful. Thanks.

The following snippet will crawl all Build Definitions of all Team Project of a Collection, and will check each and every build for an Association to the input changeset number:
using System;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace FindChangesetInBuild
{
class Program
{
static void Main(string[] args)
{
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfs:8080/tfs/collectionName"));
var versionControl = teamProjectCollection.GetService<VersionControlServer>();
var buildService = (IBuildServer)teamProjectCollection.GetService(typeof(IBuildServer));
var teamProjects = versionControl.GetAllTeamProjects(true);
foreach (var teamProject in teamProjects)
{
var buildDefinitions = buildService.QueryBuildDefinitions(teamProject.Name);
foreach (var buildDefinition in buildDefinitions)
{
var builds = buildService.QueryBuilds(buildDefinition);
foreach (var buildDetail in builds)
{
var changesets = InformationNodeConverters.GetAssociatedChangesets(buildDetail);
if (changesets.Any(changesetSummary => changesetSummary.ChangesetId == Convert.ToInt32(args[0])))
{
Console.WriteLine("Changeset was build in "+buildDetail.BuildNumber);
}
}
}
}
}
}
}
Needless to say, this is a brute force attack.You can further refine the code if you narrow down the list of buildDefinition, make focus on specific teamProjects etc. In any case I can hardly imagine the above to be useful as-is!Apart from (obviously) MSDN, a great resource for TFS-SDK is Shai Raiten's blog.For Build-Speficic examples, check also here & here for some possibly interesting SO posts.

You can use this little DB Query in TFS 2010 and just substitute 90264 with your changeset id.
USE Tfs_Warehouse
go
SELECT BuildName
FROM DimBuild
INNER JOIN FactBuildChangeset
ON DimBuild.BuildSK = FactBuildChangeset.BuildSK
WHERE FactBuildChangeset.ChangesetSK = 90264

Related

VSIX how to get current snapshot document name?

I have been trying to to create an extension that highlights specific line numbers for me in Visual Studio in the margins.
I manged to get my marking in the margins using predefined line number but for it to work properly I need to know what the current document FullName is (Path and filename)
After much googling I figured out how to do it with the sample code (which is not ideal)
DTE2 dte = (DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.15.0");
var activeDocument = dte.ActiveDocument;
var docName = activeDocument.Name;
var docFullName = activeDocument.FullName;
Now I know the problems here
is that is for specific version bases on the text
there is no way to select which instance (when running more than one VS)
It seems to be very slow
I have a feeling I should be doing this with MEF Attributes but the MS docs examples are so simple that they do not work for me. I scanned a few SO questions too and I just cannot get them to work. They mostly talk about Services.. which I do not have and have no idea how to get.
The rest of my code uses SnapshotSpans as in the example Extension of Todo_Classification examples which is great if you do NOT need to know the file name.
I have never done any extensions development. Please can somebody help me do this correctly.
You can use following code to get a file from a snapshot without any dependencies.
public string GetDocumentPath(Microsoft.VisualStudio.Text.ITextSnapshot ts)
{
Microsoft.VisualStudio.Text.ITextDocument textDoc;
bool rc = ts.TextBuffer.Properties.TryGetProperty(
typeof(Microsoft.VisualStudio.Text.ITextDocument), out textDoc);
if (rc && textDoc != null)
return textDoc.FilePath;
return null;
}
If you don't mind adding Microsoft.CodeAnalysis.EditorFeatures.Text to your project it will provide you with an extension method Document GetOpenDocumentInCurrentContextWithChanges() on the Microsoft.VisualStudio.Text.Snapshot class. (Plus many other Rosyln based helpers)
using Microsoft.CodeAnalysis.Text;
Document doc = span.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

Debug script code that is being executed with Roslyn CSharpScript

I created this test console application to run some C# code with the Roslyn scripting engine (in the Microsoft.CodeAnalysis.CSharp.Scripting nuget package).
string code = "int test = 123;\r\nConsole.WriteLine(\"hello, world!\");";
var options = ScriptOptions.Default.WithImports("System");
var script = CSharpScript.Create(code, options);
await script.RunAsync();
This works, but now I would also like the option of somehow debugging into the script that is being executed. Is there a way to do that?
Figured out a way to do it by writing the code to a temporary file, and adding debugging information pointing to that file. Then I can step into the RunAsync call, and visual studio will load the temporary file, show an execution pointer, and will let me inspect variables.
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.IO;
using System.Text;
namespace RoslynScriptingTest
{
class Program
{
static async Task Main(string[] args)
{
string code = "int test = 123;\r\nConsole.WriteLine(\"hello, world!\");";
string tmpFile = Path.GetTempFileName();
var encoding = Encoding.UTF8;
File.WriteAllText(tmpFile, code, encoding);
try
{
var options = ScriptOptions.Default
.WithImports("System")
.WithEmitDebugInformation(true)
.WithFilePath(tmpFile)
.WithFileEncoding(encoding);
var script = CSharpScript.Create(code, options);
await script.RunAsync();
}
finally
{
File.Delete(tmpFile);
}
Console.ReadKey();
}
}
}
The debugging only seems to work when "just my code" is enabled in the visual studio debugger settings.
In my actual use case, I'm actually loading the code from an XML file, so it would be better if I could point to that original file and map the line numbers somehow. But this is already a good start.

Sitecore: Glass Mapper Code First

It is possible to automatically generate Sitecore templates just coding models? I'm using Sitecore 8.0 and I saw Glass Mapper Code First approach but I cant find more information about that.
Not sure why there isn't much info about it, but you can definitely model/code first!. I do it alot using the attribute configuration approach like so:
[SitecoreType(true, "{generated guid}")]
public class ExampleModel
{
[SitecoreField("{generated guid}", SitecoreFieldType.SingleLineText)]
public virtual string Title { get; set; }
}
Now how this works. The SitecoreType 'true' value for the first parameter indicates it may be used for codefirst. There is a GlassCodeFirstDataprovider which has an Initialize method, executed in Sitecore's Initialize pipeline. This method will collect all configurations marked for codefirst and create it in the sql dataprovider. The sections and fields are stored in memory. It also takes inheritance into account (base templates).
I think you first need to uncomment some code in the GlassMapperScCustom class you get when you install the project via Nuget. The PostLoad method contains the few lines that execute the Initialize method of each CodeFirstDataprovider.
var dbs = global::Sitecore.Configuration.Factory.GetDatabases();
foreach (var db in dbs)
{
var provider = db.GetDataProviders().FirstOrDefault(x => x is GlassDataProvider) as GlassDataProvider;
if (provider != null)
{
using (new SecurityDisabler())
{
provider.Initialise(db);
}
}
}
Furthermore I would advise to use code first on development only. You can create packages or serialize the templates as usual and deploy them to other environment so you dont need the dataprovider (and potential risks) there.
You can. But it's not going to be Glass related.
Code first is exactly what Sitecore.PathFinder is looking to achieve. There's not a lot of info publicly available on this yet however.
Get started here: https://github.com/JakobChristensen/Sitecore.Pathfinder

Powershell and XMLRPC

We are a Windows shop using Powershell extensively.We also have a Spacewalk that I would like to poll some data from as part of the existing Powershell script. Spacewalk API is exposed via XMLRPC.
I have spent some time searching for examples on how this can be done but the information is really scarce. The closest I could get was this link ( no longer available)
https://web.archive.org/web/20080202045713/http://thepowershellguy.com/blogs/posh/archive/2008/01/31/powershell-and-xmlrpc-posh-challenge-part-12.aspx
Lack of examples makes me think that I am looking in the wrong direction. I know about new-webserviceproxy and I used it for quering Sharepoint but I don't see anyone using it for XMLRPC calls.
It is trivial to write the call in Perl or Python but this is not what I need in this specific case...
Am I going the wrong way here?
Just implemented this myself, so I thought I'd pass it along.
You can actually download the DLL instead of compiling the source yourself - I found the DLL by using NuGet, but some say you can get it from the zip.
I decided to implement the interfaces in C# code within powershell to maximize portability / ease of development. If you want, you can compile the C# code as a DLL and load that using powershell, but you'll have to go back and recompile every time you want to make a change to the C# code. Here, powershell recompiles for you on the fly. (The only downside is that if you use the native windows powershell IDE, you have to close and reopen to clear your session every time you make a change to the C# code)
Here's an example of the OpenSubtitles API using XML-RPC.NET and powershell (not the cleanest code, but hopefully illustrates the XML-RPC.net usage):
$source = #'
namespace OpenSubtitlesAPI
{
using CookComputing.XmlRpc;
[XmlRpcUrl("http://api.opensubtitles.org/xml-rpc")]
public interface IOpenSubtitles : IXmlRpcProxy
{
[XmlRpcMethod("LogIn")]
XmlRpcStruct LogIn(string username, string password, string language, string useragent);
[XmlRpcMethod("LogOut")]
XmlRpcStruct LogOut(string token);
[XmlRpcMethod("SearchSubtitles")]
XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries);
[XmlRpcMethod("SearchSubtitles")]
XmlRpcStruct SearchSubtitles(string token, XmlRpcStruct[] queries, int limit);
}
public class ProxyFactory
{
public static IOpenSubtitles CreateProxy()
{
return XmlRpcProxyGen.Create<IOpenSubtitles>();
}
}
}
'#
# Load XML-RPC.NET and custom interfaces
if ([Type]::GetType("OpenSubtitlesAPI.ProxyFactory") -eq $null)
{
[Reflection.Assembly]::LoadFile("C:\path\to\CookComputing.XmlRpcV2.dll") | Out-Null
$dynamicAssembly = Add-Type -TypeDefinition $source -ReferencedAssemblies ("C:\path\to\CookComputing.XmlRpcV2.dll")
}
# Set up proxy
$proxy = [OpenSubtitlesAPI.ProxyFactory]::CreateProxy()
$proxy.UserAgent = "user agent"
$proxy.EnableCompression = $true
# Log in
$LogInResponse = $proxy.LogIn("user name", "password", "language", "user agent")
# Build query
$query = New-Object CookComputing.XmlRpc.XmlRpcStruct
$query.Add("moviehash", "movie hash")
$query.Add("moviebytesize", "movie size")
$query.Add("sublanguageid", "language")
$queries = #($query)
# Search
$SearchResponse = $proxy.SearchSubtitles($LogInResponse.token, $queries)
# Log out
$LogOutResponse = $proxy.LogOut($LogInResponse.token)
My response is a bit delayed to the initial question, but hopefully this helps someone out there.
Have you looked at XML-RPC.NET? You would have to create a XmlRpcProxyGen class in C# that implements IXmlRpcProxy but once you've done that, you should be able to load that .NET assembly and use the proxy class from PowerShell.

Can I programmatically collapse/expand all preprocessor blocks of a certain name in Visual Studio 2012?

My current project has a lot of debug preprocessor blocks scattered throughout the code. These are intentionally named differently to the system _DEBUG and NDEBUG macros, so I have a lot of this:
// Some code here
#ifdef PROJNAME_DEBUG
//unit tests, assumption testing, etc.
#endif
// code continues
These blocks sometimes get rather large, and their presence can sometimes inhibit code readability. In Visual Studio 2012 I can easily collapse these, but it would be nice to automatically have all of them collapsed, allowing me to expand them if I want to see what's in there. However, as I also have a bunch of header guards I don't want to collapse all preprocessor blocks, only the #ifdef PROJNAME_DEBUG ones.
Can I do this?
This is the most easiest scenario you can achive it, I think.
You should create an Add-In first in C#. (in VS 2013 they become deprecated :( )
In the OnConnection method you should add your command:
public void OnConnection( object application, ext_ConnectMode connectMode, object addInInst, ref Array custom )
{
_applicationObject = (DTE2)application;
if (connectMode == ext_ConnectMode.ext_cm_AfterStartup || connectMode == ext_ConnectMode.ext_cm_Startup)
{
Commands2 commands = (Commands2)_applicationObject.Commands;
try
{
//Add a command to the Commands collection:
Command command = commands.AddNamedCommand2(_addInInstance, "MyAddinMenuBar", "MyAddinMenuBar", "Executes the command for MyAddinMenuBar", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
}
catch (System.ArgumentException)
{
//If we are here, bla, bla... (Auto generated)
}
}
}
Note: you can find how parameters are act at the reference of AddNamedCommand2
The template created version would be also fine, but naturaly it worth to name your command properly.
After that you need to add your logic to Exec method:
public void Exec( string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled )
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == "MyAddinMenuBar.Connect.MyAddinMenuBar")
{
List<string> args = (varIn as string).Split(' ').ToList();
TextSelection ts;
ts = (TextSelection)_applicationObject.ActiveDocument.Selection;
EditPoint ep = (ts.ActivePoint).CreateEditPoint();
ep.StartOfDocument();
do
{
string actualLine = ep.GetLines(ep.Line, ep.Line + 1);
if (args.TrueForAll(filter => actualLine.Contains(filter)))
{
_applicationObject.ExecuteCommand("Edit.GoTo", ep.Line.ToString());
_applicationObject.ExecuteCommand("Edit.ToggleOutliningExpansion");
}
ep.LineDown();
} while (!ep.AtEndOfDocument);
handled = true;
return;
}
}
}
Note: Name you given to the command is checked in exec.
Than you can build.
Deployment of Add-In can happen through an [ProjectName].AddIn file in ..\Documents\Visaul Studio 20[XY]\AddIns\. (Created by the template, you should copy if you move the Add-In elsewhere)
You should place your Add-In assembly where the Assembly element of the mentioned file you set to point. To change version you should modify the text in Version element.
After you deployed and started Studio, you should activate the Add-In in the manager in Toolsmenu.
You need to expand all collapsable section in your code file (CTRL+M+L with C# IDE settigs).
This is required because I found only a way to invert the state of collapsion. If you find better command, you can change it.
Next you should activate Command Window to use the the created command.
Now only you need to type your commands name, like this:
MyAddinMenuBar.Connect.MyAddinMenuBar #ifdef PROJNAME_DEBUG
Hopefully magic will happen.
This solution is independent of language of code you edit so pretty multifunctional.