Viser innlegg med etiketten MSBuild. Vis alle innlegg
Viser innlegg med etiketten MSBuild. Vis alle innlegg

mandag 7. desember 2009

Changing TFS emails to link to Team System Web Access – Part 2 - Visual Studio Team System (VSTS) Blog - by Neno Loje

Neno Loje stated in Changing TFS emails to link to Team System Web Access – Part 2 - Visual Studio Team System (VSTS) Blog - by Neno Loje that:

"There are four areas to look at:
Work Item notification mails (has already been discussed here)
Build notification mails
Check-in notification mails
Mails sent by Team Explorer (feature of TFS 2008 SP1)
Area 1 is part of a separate blog post, for Area 2 there are currently no equivalent steps (as stated in KB956761)."

I just couldn't live with it so I made it work, like this in BuildCompletionEvent2.xsl:

   1:        <div class="Title">


   2:          <xsl:call-template name="link">


   3:            <xsl:with-param name="format" select="'html'"/>


   4:            <xsl:with-param name="embolden" select="'true'"/>


   5:            <xsl:with-param name="fontSize" select="'larger'"/>


   6:            <xsl:with-param name="link" select="concat(substring-before(Url,':8080/Build/Build.aspx?artifactMonike'),':8090/UI/Pages/Build/Details.aspx?builduri=vstfs%3A%2F%2F%2FBuild%2FBuild%2F',substring-after(Url,'artifactMoniker='))"/>


   7:            <xsl:with-param name="displayText" select="Title"/>


   8:          </xsl:call-template>


   9:        </div>




Where the point of the matter is line 11. The change was inspired by the original post by Neno and a simple fix.



To add even more we even changed it a bit more to include a link to a report over the failing tests for the last 72 hours. I am not showing the report part, but the take-away is the inclusion of the link:



 



   1:  <xsl:if test="StatusCode != 'Succeeded'">


   2:     <tr>


   3:       <td class="PropName">Build Log Location: </td>


   4:       <td class="PropValue">


   5:         <xsl:call-template name="link">


   6:           <xsl:with-param name="format" select="'html'"/>


   7:           <xsl:with-param name="embolden" select="'false'"/>


   8:           <xsl:with-param name="link" select="LogLocation"/>


   9:           <xsl:with-param name="displayText" select="LogLocation"/>


  10:         </xsl:call-template>


  11:       </td>


  12:     </tr>


  13:     <tr>


  14:       <xsl:call-template name="link">


  15:         <xsl:with-param name="format" select="'html'"/>


  16:         <xsl:with-param name="embolden" select="'true'"/>


  17:         <xsl:with-param name="fontSize" select="'larger'"/>


  18:         <xsl:with-param name="link" select="concat(substring-before(Url,':8080/Build/Build.aspx?artifactMonike'),'/ReportServer/Pages/ReportViewer.aspx?/Confirmit/Failed+Tests&rs%3aCommand=Render&BuildParam=',substring-after(Url,'artifactMoniker='))"/>


  19:         <xsl:with-param name="displayText" select="'Report on failing tests in this build'"/>


  20:       </xsl:call-template>


  21:     </tr>


  22:   </xsl:if>




The added code is the lines 13 – 21.



Happy coding

lørdag 21. mars 2009

Build task for searching in files

Technorati Tags: ,

Just to test out the code add-in I just added to Live Writer I thought I would share this little build task for filtering out files based on standard string search, with or without regular expressions. Disclaimer! The regular expression mode didn’t work as I had expected and my needs there and then didn’t exceed pure freetext search, so it may need some tweaking, and of course the usual use at own risk bla bla.

namespace YourNameSpace.BuildTasks
{
using System.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Build.Utilities;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;

/// <summary>
/// Finds files with a content that has one or more matches
/// for the pattern provided.
/// </summary>
public class FindFilesWithContent : Task
{
public FindFilesWithContent()
{
results = new List<TaskItem>();
} // Properties
[Required]
public ITaskItem[] FilesToSearch { get; set; }
[Required]
public string Pattern { get; set; }
public bool UseRegExp { get; set; }
private readonly List<TaskItem> results;
[Output]
public ITaskItem[] Results
{
get { return results.ToArray(); }
}
public override bool Execute()
{
if(UseRegExp) Log.LogMessage(MessageImportance.Low,
"Using regular expression", new object[] { null });
Log.LogMessage(MessageImportance.Low,
"Matching with pattern {0}", new object[] { Pattern });
foreach (ITaskItem taskItem in FilesToSearch)
{
if (!File.Exists(taskItem.ItemSpec))
{
Log.LogError("File does not exist: {0}",
new object[] { taskItem.ItemSpec });
}

//Read the whole text file to the end before closing it
StreamReader reader = new StreamReader(taskItem.ItemSpec);
string allRead = reader.ReadToEnd();
reader.Close();

Log.LogMessage(MessageImportance.Low,
"Content of file to match: {0}",
new object[] { allRead });

//Do the matching
if (Compare(allRead, Pattern))
{
results.Add(new TaskItem(taskItem));
Log.LogMessage(MessageImportance.Low,
"File matched: {0}",
new object[] { taskItem.ItemSpec });
}
else
Log.LogMessage(MessageImportance.Low,
"File did not match: {0}",
new object[] { taskItem.ItemSpec });
}
return true;
}

private bool Compare(string stringToSearch, string pattern)
{
if (UseRegExp)
return Regex.IsMatch(stringToSearch, pattern);
return stringToSearch.Contains(pattern);
}
}
}




The usage is as follows:





<!--UseRegExp="false" is default-->
<FindFilesWithContent
FilesToSearch="@(FilesToSearchWithin)"
Pattern="This string I will find"
UseRegExp="false">
<Output TaskParameter="Results"
ItemName="FilesThatHaveMatchingContent"/>
</FindFilesWithContent>





mandag 29. desember 2008

MSbuild of VS solution under target clean is just plain wrong

One of our solutions has been bothering us for a long time so I finally decided to make a simple demo of the problem.

In my demo solution I have three library type C# projects Level0, Level1 and Level2. Adding and removing a (project) reference from Level1 to Level0 and building with both default and clean targets using MSBuild illustrates the problem. Beneath is the ouput of the clean build without the reference in place:

C:\Test\BuildDependencies>msbuild C:\Test\BuildDependencies\BuildDependencies.sln /t:clean
Microsoft (R) Build Engine Version 3.5.30729.1[Microsoft .NET Framework, Version 2.0.50727.3053]Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 12/29/2008 4:01:39 PM.Project "C:\Test\BuildDependencies\BuildDependencies.sln" on node 0 (clean target(s)). Building solution configuration "DebugAny CPU".Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level0\Level0.csproj" (2) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level0\bin\Debug\Level0.dll". Deleting file "C:\Test\BuildDependencies\Level0\bin\Debug\Level0.pdb". Deleting file "C:\Test\BuildDependencies\Level0\obj\Debug\Level0.dll". Deleting file "C:\Test\BuildDependencies\Level0\obj\Debug\Level0.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level0\Level0.csproj" (Clean target(s)).
Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level1\Level1.csproj" (3) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.dll". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.pdb". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.tlb". Deleting file "C:\Test\BuildDependencies\Level1\obj\Debug\Level1.dll". Deleting file "C:\Test\BuildDependencies\Level1\obj\Debug\Level1.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level1\Level1.csproj" (Clean target(s)).
Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level2\Level2.csproj" (4) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level2\bin\Debug\Level2.dll". Deleting file "C:\Test\BuildDependencies\Level2\bin\Debug\Level2.pdb". Deleting file "C:\Test\BuildDependencies\Level2\obj\Debug\Level2.dll". Deleting file "C:\Test\BuildDependencies\Level2\obj\Debug\Level2.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level2\Level2.csproj" (Clean target(s)).
Done Building Project "C:\Test\BuildDependencies\BuildDependencies.sln" (clean target(s)).
Build succeeded. 0 Warning(s) 0 Error(s)


Here is the output with the reference (Level1 -> Level0) in place:

C:\Test\BuildDependencies>msbuild C:\Test\BuildDependencies\BuildDependencies.sln /t:clean
Microsoft (R) Build Engine Version 3.5.30729.1[Microsoft .NET Framework, Version 2.0.50727.3053]Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 12/29/2008 4:02:14 PM.Project "C:\Test\BuildDependencies\BuildDependencies.sln" on node 0 (clean target(s)). Building solution configuration "DebugAny CPU".Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level0\Level0.csproj" (2) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level0\bin\Debug\Level0.dll". Deleting file "C:\Test\BuildDependencies\Level0\bin\Debug\Level0.pdb". Deleting file "C:\Test\BuildDependencies\Level0\obj\Debug\Level0.dll". Deleting file "C:\Test\BuildDependencies\Level0\obj\Debug\Level0.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level0\Level0.csproj" (Clean target(s)).
Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level2\Level2.csproj" (3) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level2\bin\Debug\Level2.dll". Deleting file "C:\Test\BuildDependencies\Level2\bin\Debug\Level2.pdb". Deleting file "C:\Test\BuildDependencies\Level2\obj\Debug\Level2.dll". Deleting file "C:\Test\BuildDependencies\Level2\obj\Debug\Level2.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level2\Level2.csproj" (Clean target(s)).
Project "C:\Test\BuildDependencies\BuildDependencies.sln" (1) is building "C:\Test\BuildDependencies\Level1\Level1.csproj" (4) on node 0 (Clean target(s)). Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.dll". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.pdb". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level1.tlb". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level0.dll". Deleting file "C:\Test\BuildDependencies\Level1\bin\Debug\Level0.pdb". Deleting file "C:\Test\BuildDependencies\Level1\obj\Debug\ResolveAssemblyReference.cache". Deleting file "C:\Test\BuildDependencies\Level1\obj\Debug\Level1.dll". Deleting file "C:\Test\BuildDependencies\Level1\obj\Debug\Level1.pdb".EntityClean: Successfully cleaned the output for 0 EDMX files.Done Building Project "C:\Test\BuildDependencies\Level1\Level1.csproj" (Clean target(s)).
Done Building Project "C:\Test\BuildDependencies\BuildDependencies.sln" (clean target(s)).

Now, the point is that allthough adding the reference alters the build order MSBuild does not build the clean targets in the correct order.

If you don't beleive me have a look at the .sln.cache that gets generated (if you use MSBuild V3 and VS2008). Compare the Clean and the Build targets and you will see that the build order is the same (BuildLevel0 is done before BuildLevel1 etc.).

Cleaning a referer after the referee (is that the right term?) will fail in some cases. Specifically it will fail if you need the refered assembly to clean the current assembly.

When do you need the referred assembly to clean the current one? Well our build breaks during clean with the "MSB3395: Cannot unregister assembly" error. It seems our referring assembly needs some type in the referred assembly to properly unregister. I am currently investigating why this is the case but the result doesn't change the fact that MSBuild has an issue here.

It's obvious if you think about it. If you have access to dependency information you should always clean in the opposite order of the way you normally build. Am I the only one getting this?!? Shouldn't this be obvious to the guys in redmond too?!?

tirsdag 16. desember 2008

AdditionalReferencePaths can/will screw up your Team Build

Just spent several days pondering over a Team Build that only builds the first time after a thorough clean of the build directory. Prelimenary conclusion is as follows:

It seems like the AdditionalReferencePaths option is given a higher priority than the framework itself. This leads to resolving things like System.dll from the output path instead of from the relevant target framework(!!).

The reason I started thinking this is that the it was obvious from the build log that our output path was beeing preferred for stuff like System.dll, System.Data.dll etc. We are deliberately not using CopyLocal and simultaneously have set all our $(Output) to one directory. All file references are picked up from this folder.

I tested out this conclusion by simply removing the one AdditionalReferencePaths inclusion we had and it did the trick.

Now, this preference of AdditionalReferencePaths over target framework path cannot be a good descicion from MS can it?