@@ -0,0 +1,214 @@
//
// This source code is released under the MIT License; see the accompanying license file.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Win32;

namespace OpenCover.MSBuild
{

/// <summary>Executes OpenCover with the specified arguments.</summary>
/// <example>
/// <code><![CDATA[
/// <Target Name="Test">
/// <OpenCover
/// Target="xunit.console.exe"
/// TargetArgs="&quot;C:\My tests folder\MyTests.xunit&quot; /silent"
/// />
/// </Target>
/// ]]></code>
/// </example>
public class OpenCover:
ToolTask
{

public OpenCover()
{
DefaultFilters=true;
Register=true;
}

protected override string GenerateFullPathToTool()
{
RegistryKey key=null;

string[] keyNames=new string[] { _OpenCoverRegKey, _OpenCoverRegKeyWow6432 };
foreach (string kn in keyNames)
{
key=Registry.CurrentUser.OpenSubKey(kn);
if (key!=null)
break;

key=Registry.LocalMachine.OpenSubKey(kn);
if (key!=null)
break;
}

if (key==null)
{
Log.LogError("Could not find OpenCover installation registry key");
return null;
}

string rd=(string)key.GetValue(_OpenCoverRegValue);
if (string.IsNullOrEmpty(rd))
{
Log.LogError("Could not find OpenCover installation path");
return null;
}

return Path.Combine(rd, ToolExe);
}

protected override string GenerateCommandLineCommands()
{
CommandLineBuilder builder=new CommandLineBuilder();

if (Register)
builder.AppendSwitch("-register:user");
if (!DefaultFilters)
builder.AppendSwitch("-nodefaultfilters");
if (MergeByHash)
builder.AppendSwitch("-mergebyhash");
if (ShowUnvisited)
builder.AppendSwitch("-showunvisited");

builder.AppendSwitchIfNotNull("-target:", Target);
builder.AppendSwitchIfNotNull("-targetdir:", TargetWorkingDir);
builder.AppendSwitchIfNotNull("-targetargs", TargetArgs);

var filters=new List<ITaskItem>();
if (Include!=null)
{
foreach (ITaskItem ti in Include)
ti.ItemSpec=string.Concat('+', ti.ItemSpec);
filters.AddRange(Include);
}
if (Exclude!=null)
{
foreach (ITaskItem ti in Exclude)
ti.ItemSpec=string.Concat('-', ti.ItemSpec);
filters.AddRange(Exclude);
}
if (filters.Count>0)
builder.AppendSwitchIfNotNull("-filters:", filters.ToArray<ITaskItem>(), " ");

builder.AppendSwitchIfNotNull("-output:", Output);

return builder.ToString();
}

protected override string GetWorkingDirectory()
{
string ret=null;
if (TargetWorkingDir!=null)
ret=TargetWorkingDir.GetMetadata("FullPath");

if (string.IsNullOrEmpty(ret))
ret=base.GetWorkingDirectory();

return ret;
}

protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
{
if (_OutputRegex.IsMatch(singleLine))
{
base.LogEventsFromTextOutput(singleLine, MessageImportance.Low);
_ToolStarted=true;
return;
}


base.LogEventsFromTextOutput(singleLine, (_ToolStarted ? MessageImportance.Normal : MessageImportance.Low));
}

public bool DefaultFilters
{
get;
set;
}

public ITaskItem[] Include
{
get;
set;
}

public ITaskItem[] Exclude
{
get;
set;
}

public bool MergeByHash
{
get;
set;
}

public ITaskItem Output
{
get;
set;
}

public bool Register
{
get;
set;
}

public bool ShowUnvisited
{
get;
set;
}

[Required]
public ITaskItem Target
{
get;
set;
}

public ITaskItem TargetWorkingDir
{
get;
set;
}

public string TargetArgs
{
get;
set;
}

protected override string ToolName
{
get
{
return "OpenCover.Console.exe";
}
}

private bool _ToolStarted;

private static Regex _OutputRegex=new Regex(@"^\[\d{5}\] \[\d{5}\] ", RegexOptions.Compiled | RegexOptions.Multiline);
private const string _OpenCoverRegKey=@"SOFTWARE\SWilde\OpenCover\";
private const string _OpenCoverRegKeyWow6432=@"SOFTWARE\Wow6432Node\SWilde\OpenCover\";
private const string _OpenCoverRegValue="Path";
}
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<OpenCoverMSBuildTasksPath Condition="'$(OpenCoverMSBuildTasksPath)' == ''">$(MSBuildExtensionsPath32)\OpenCover</OpenCoverMSBuildTasksPath>
<OpenCoverMSBuildTasksLib>$(OpenCoverMSBuildTasksPath)\Isogeo.MSBuild.dll</OpenCoverMSBuildTasksLib>
</PropertyGroup>

<UsingTask AssemblyFile="$(OpenCoverMSBuildTasksLib)" TaskName="OpenCover.MSBuild.OpenCover" />
</Project>
@@ -0,0 +1,20 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenCover.MSBuild")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("OpenCover.MSBuild")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("321e0940-9257-41ae-8ec0-376e75115431")]
@@ -40,6 +40,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenCover.Integration.Test"
{BDFCE9C6-A116-45AF-94DC-F491D0CE8EB2} = {BDFCE9C6-A116-45AF-94DC-F491D0CE8EB2}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenCover.MSBuild", "OpenCover.MSBuild\OpenCover.MSBuild.csproj", "{746A6B40-4570-40CB-BBE5-CEECEE9E220F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -102,6 +104,14 @@ Global
{C5533EEB-9AEF-4CC9-8E76-3FFE57D09C23}.Release|x64.Build.0 = Release|Any CPU
{C5533EEB-9AEF-4CC9-8E76-3FFE57D09C23}.Release|x86.ActiveCfg = Release|Any CPU
{C5533EEB-9AEF-4CC9-8E76-3FFE57D09C23}.Release|x86.Build.0 = Release|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Debug|x64.ActiveCfg = Debug|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Debug|x64.Build.0 = Debug|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Debug|x86.ActiveCfg = Debug|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Debug|x86.Build.0 = Debug|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Release|x64.ActiveCfg = Release|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Release|x64.Build.0 = Release|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Release|x86.ActiveCfg = Release|Any CPU
{746A6B40-4570-40CB-BBE5-CEECEE9E220F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE