line utility from MSBuild. This will run the analysis and produce a report
of all the issues, but this has no "teeth", that is, nothing makes anyone
look at the report and fix the issues. In order to have FXCop actually
break the build you need to write a custom task the following is an example
of a simple task that breaks the build if there are any issues. It does
need to be told where to find the report via the report location property
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Build.Tasks;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Xml;
namespace Framework.Build.CustomTasks
{
public class CheckFXCop : Task
{
private string _reportLocation;
[Required]
public string ReportLocation
{
get { return _reportLocation; }
set { _reportLocation = value; }
}
/// <summary>
/// Executes the Task
/// </summary>
/// <returns>true if the task successfully executed; otherwise,
false.</returns>
public override bool Execute()
{
bool returnVal = true;
int numIssues = 0;
try
{
FileStream xmlFileStream = new
FileStream(this.ReportLocation, FileMode.Open);
XmlTextReader fxReport = new XmlTextReader(xmlFileStream);
while (fxReport.Read())
{
if (fxReport.LocalName == "Issue")
{
returnVal = false;
numIssues++;
}
}
if (!returnVal)
{
Log.LogError("There are " + numIssues.ToString() + "
FXCop issue(s). Please review the report");
}
return returnVal;
}
catch
{
return false;
}
}
}
}
3 comments:
Here's my own, which adds actually running fxCop as part of the task:
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.IO;
using System.Xml;
[assembly: CLSCompliant(true)]
namespace FxCopTask
{
public class FxCopTask : ToolTask
{
public override bool Execute()
{
try
{
int numIssues = 0;
bool successStatus = base.Execute();
if (!successStatus)
{
return successStatus;
}
if (!File.Exists(this.fxCopOutput))
{
return true;
}
using (FileStream xmlFileStream = new FileStream(this.fxCopOutput, FileMode.Open))
{
XmlTextReader fxReport = new XmlTextReader(xmlFileStream);
while (fxReport.Read())
{
if (fxReport.LocalName == "Issue" && fxReport.NodeType == XmlNodeType.Element)
{
successStatus = false;
numIssues++;
}
}
if (!successStatus)
{
Log.LogError("Found {0} fxCop warnings, see {1} for more details", numIssues, xmlFileStream.Name);
}
return successStatus;
}
}
catch (Exception e)
{
Log.LogErrorFromException(e);
return false;
}
}
const string FXCOPPATH_DEFAULT = "c:\\Program Files\\Microsoft FxCop 1.35\\FxCopCmd.exe";
private string fxCopPath = FXCOPPATH_DEFAULT;
public string FxCopPath
{
get { return fxCopPath; }
set { fxCopPath = value; }
}
private string projectPath;
public string ProjectPath
{
get { return projectPath; }
set { projectPath = value; }
}
private string fxCopOutput = "fxCopOut.xml";
public string FxCopOutput
{
get { return fxCopOutput; }
set { fxCopOutput = value; }
}
private string targetAssembly;
public string TargetAssembly
{
get { return targetAssembly; }
set { targetAssembly = value; }
}
protected override string GenerateFullPathToTool()
{
return fxCopPath;
}
protected override string GenerateCommandLineCommands()
{
CommandLineBuilder builder = new CommandLineBuilder();
if (projectPath != null)
{
builder.AppendSwitch("/project:" + projectPath);
}
else if (targetAssembly != null)
{
builder.AppendSwitch("/file:" + targetAssembly);
}
else
{
Log.LogWarning("FxCopTask requires eith a ProjectPath or a TargetAssembly");
}
if (fxCopOutput != null)
{
builder.AppendSwitch("/out:" + fxCopOutput);
}
return builder.ToString();
}
protected override string ToolName
{
get { return "fxCopCmd.exe"; }
}
}
}
The main reason I don't run fxcop from the task is so I can have the report generated but not break the build. My bosses don't want to see the inital slow down that would result in having to address all of the issues identified by FxCop
Use a multiple-build system. We use Teamcity, and have many different builds.
You can have the FXCop build fail but "put on ignore" by people that don't care about it.
Post a Comment