Skip to content
Permalink
Browse files

Coverlet Tool (#11)

* A very rushed start

* Make sure coverlet settings has an output by default

* Add test project and basic test

* Run tests using Cake

* Make tool an standard cake tool and add paths

This allows cake to discover the coverlet tool in the global directory
and should handle unix correctly.

- Writing of the settings file has been moved to an arguments processor
which does it individually for each type of parameter

* Update docs to include multiple formats

closes #12

* Remove any cpu for appveyor

Should fix the test failures
  • Loading branch information...
Romanx committed Dec 2, 2018
1 parent 6359be0 commit 4d86d077fe528c660bac0d9d17bc595cc1bd2cb5
@@ -0,0 +1,28 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/test/Cake.Coverlet.Tests/bin/Debug/netcoreapp2.1/Cake.Coverlet.Tests.dll",
"args": [],
"cwd": "${workspaceFolder}/test/Cake.Coverlet.Tests",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
"console": "internalConsole",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
,]
}
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/test/Cake.Coverlet.Tests/Cake.Coverlet.Tests.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
@@ -16,6 +16,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
version.json = version.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{EEC95ADF-2D7A-4B97-9D4E-27F2F198FFC6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Coverlet.Tests", "test\Cake.Coverlet.Tests\Cake.Coverlet.Tests.csproj", "{77208523-570A-4419-B4C9-F26B33D3BAA0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -38,12 +42,25 @@ Global
{826C61AF-EC41-4A17-81E3-2611447207D2}.Release|x64.Build.0 = Release|Any CPU
{826C61AF-EC41-4A17-81E3-2611447207D2}.Release|x86.ActiveCfg = Release|Any CPU
{826C61AF-EC41-4A17-81E3-2611447207D2}.Release|x86.Build.0 = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|x64.ActiveCfg = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|x64.Build.0 = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|x86.ActiveCfg = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Debug|x86.Build.0 = Debug|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|Any CPU.Build.0 = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|x64.ActiveCfg = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|x64.Build.0 = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|x86.ActiveCfg = Release|Any CPU
{77208523-570A-4419-B4C9-F26B33D3BAA0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{826C61AF-EC41-4A17-81E3-2611447207D2} = {E0CB0BC0-F7D4-4D3B-97C3-15C790FFC71D}
{77208523-570A-4419-B4C9-F26B33D3BAA0} = {EEC95ADF-2D7A-4B97-9D4E-27F2F198FFC6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0FCEF3CA-5B6C-4AB4-8B40-CC4FDBA72E34}
@@ -1,7 +1,6 @@
version: 1.0.1000000.{build}
image: Visual Studio 2017
configuration: Release
platform: Any CPU
install:
- cmd: git submodule update --init --recursive
- ps: >-
@@ -32,11 +32,18 @@ Task("Build")
.IsDependentOn("Restore")
.Does<MyBuildData>((data) =>
{
DotNetCoreBuild("./src/Cake.Coverlet/", data.BuildSettings);
DotNetCoreBuild("./Cake.Coverlet.sln", data.BuildSettings);
});

Task("Pack")
Task("Test")
.IsDependentOn("Build")
.Does<MyBuildData>((data) =>
{
DotNetCoreTest("./test/Cake.Coverlet.Tests", data.TestSettings);
});

Task("Pack")
.IsDependentOn("Test")
.Does<MyBuildData>((data) =>
{
DotNetCorePack("./src/Cake.Coverlet/Cake.Coverlet.csproj", data.PackSettings);
@@ -56,6 +63,7 @@ public class MyBuildData
public ConvertableDirectoryPath ArtifactsDirectory { get; }
public DotNetCoreBuildSettings BuildSettings { get; }
public DotNetCorePackSettings PackSettings { get; }
public DotNetCoreTestSettings TestSettings { get; }
public IReadOnlyList<ConvertableDirectoryPath> BuildDirs { get; }

public MyBuildData(
@@ -79,5 +87,11 @@ public class MyBuildData
NoBuild = true,
Configuration = Configuration,
};

TestSettings = new DotNetCoreTestSettings
{
NoBuild = true,
Configuration = Configuration
};
}
}
@@ -9,6 +9,8 @@ In order to use the addin please make sure you've included Coverlet in the proje
#addin nuget:?package=Cake.Coverlet
```

You can also install coverlet as a global tool on your machine or with the [Cake.DotNetTool.Module]() and run the command separately from MSBuild.

**Note:** Works with Coverlet 2.1.1 and up

Then use one of the following snippets
@@ -28,7 +30,42 @@ Task("Test")
CoverletOutputName = $"results-{DateTime.UtcNow:dd-MM-yyyy-HH-mm-ss-FFF}"
};
DotNetCoreTest("./test/Stubble.Core.Tests/Stubble.Core.Tests.csproj", testSetting, coveletSettings);
DotNetCoreTest("./test/My.Project.Tests/My.Project.Tests.csproj", testSetting, coveletSettings);
}
```
Or for when installed as a tool:
```csharp
Task("Test")
.IsDependentOn("Build")
.Does<MyBuildData>((data) =>
{
var coveletSettings = new CoverletSettings {
CollectCoverage = true,
CoverletOutputFormat = CoverletOutputFormat.opencover,
CoverletOutputDirectory = Directory(@".\coverage-results\"),
CoverletOutputName = $"results-{DateTime.UtcNow:dd-MM-yyyy-HH-mm-ss-FFF}"
};
// I want to specify the specific dll file and the project exactly.
Coverlet(
"./test/My.Project.Tests/bin/Debug/net46/My.Project.Tests.dll",
"./test/My.Project.Tests/My.Project.Tests.csproj",
coveletSettings);
// I want to specify just the project file and the dll can be
// inferred from the name of the project file.
Coverlet(
"./test/My.Project.Tests/My.Project.Tests.csproj",
coveletSettings);
// I want to specify just the project directory, we will discover
// any proj file in the directory (take the first) and infer the
// name from the found project.
Coverlet(
"./test/My.Project.Tests",
coveletSettings);
}
```
@@ -57,4 +94,26 @@ Task("Test")
We expose a default transformer for the standard practice of appending the current datetime to the file as `WithDateTimeTransformer()`
If you wish to only change the directory that the output is written to then set the `CoverletOutputDirectory` and the filename handling will be done by coverlet as usual.
If you wish to only change the directory that the output is written to then set the `CoverletOutputDirectory` and the filename handling will be done by coverlet as usual.
## Settings more than one output
You can support multiple coverlet formats by providing them like this:
```csharp
var coveletSettings = new CoverletSettings {
CollectCoverage = true,
CoverletOutputFormat = CoverletOutputFormat.opencover | CoverletOutputFormat.covertura,
CoverletOutputDirectory = Directory(@".\coverage-results\"),
CoverletOutputName = $"results-{DateTime.UtcNow:dd-MM-yyyy-HH-mm-ss-FFF}"
};
```
Or by using the method on the settings class like this:
```csharp
var coveletSettings = new CoverletSettings {
CollectCoverage = true,
CoverletOutputFormat = CoverletOutputFormat.opencover,
CoverletOutputDirectory = Directory(@".\coverage-results\"),
CoverletOutputName = $"results-{DateTime.UtcNow:dd-MM-yyyy-HH-mm-ss-FFF}"
}.WithFormat(CoverletOutputFormat.covertura);
```
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cake.Core;
using Cake.Core.IO;
using Cake.Coverlet;

namespace Cake.Coverlet
{
internal static class ArgumentsProcessor
{
public static ProcessArgumentBuilder ProcessMSBuildArguments(
CoverletSettings settings,
ICakeEnvironment cakeEnvironment,
ProcessArgumentBuilder builder,
FilePath project)
{
builder.AppendMSBuildProperty(nameof(CoverletSettings.CollectCoverage), settings.CollectCoverage.ToString());
builder.AppendPropertyList(nameof(CoverletSettings.CoverletOutputFormat), SplitFlagEnum(settings.CoverletOutputFormat));

if (settings.Threshold.HasValue)
{
if (settings.Threshold > 100)
{
throw new Exception("Threshold Percentage cannot be set as greater than 100%");
}

builder.AppendMSBuildProperty(nameof(CoverletSettings.Threshold), settings.Threshold.ToString());

if (settings.ThresholdType != ThresholdType.NotSet)
{
builder.AppendPropertyList(nameof(CoverletSettings.ThresholdType), SplitFlagEnum(settings.ThresholdType));
}
}

if (settings.CoverletOutputDirectory != null && string.IsNullOrEmpty(settings.CoverletOutputName))
{
var directoryPath = settings.CoverletOutputDirectory
.MakeAbsolute(cakeEnvironment).FullPath;

builder.AppendMSBuildProperty("CoverletOutput", directoryPath);
}
else if (!string.IsNullOrEmpty(settings.CoverletOutputName))
{
var dir = settings.CoverletOutputDirectory ?? project.GetDirectory();
var directoryPath = dir.MakeAbsolute(cakeEnvironment).FullPath;

var filepath = FilePath.FromString(settings.OutputTransformer(settings.CoverletOutputName, directoryPath));

builder.AppendMSBuildProperty("CoverletOutput", filepath.MakeAbsolute(cakeEnvironment).FullPath);
}

if (settings.ExcludeByFile.Count > 0)
{
builder.AppendPropertyList(nameof(CoverletSettings.ExcludeByFile), settings.ExcludeByFile);
}

if (settings.Exclude.Count > 0)
{
builder.AppendPropertyList(nameof(CoverletSettings.Exclude), settings.Exclude);
}

if (settings.MergeWithFile != null && settings.MergeWithFile.GetExtension() == ".json")
{
builder.AppendMSBuildPropertyQuoted("MergeWith", settings.MergeWithFile.MakeAbsolute(cakeEnvironment).FullPath);
}

return builder;
}

public static ProcessArgumentBuilder ProcessToolArguments(
CoverletSettings settings,
ICakeEnvironment cakeEnvironment,
ProcessArgumentBuilder builder,
FilePath project)
{
builder.AppendSwitch("--format", SplitFlagEnum(settings.CoverletOutputFormat));

if (settings.Threshold.HasValue)
{
if (settings.Threshold > 100)
{
throw new Exception("Threshold Percentage cannot be set as greater than 100%");
}

builder.AppendSwitch(nameof(CoverletSettings.Threshold), settings.Threshold.ToString());

if (settings.ThresholdType != ThresholdType.NotSet)
{
builder.AppendSwitchQuoted("--threshold-type", SplitFlagEnum(settings.ThresholdType));
}
}

if (settings.CoverletOutputDirectory != null && string.IsNullOrEmpty(settings.CoverletOutputName))
{
var directoryPath = settings.CoverletOutputDirectory
.MakeAbsolute(cakeEnvironment).FullPath;

builder.AppendSwitchQuoted("--output", directoryPath);
}
else if (!string.IsNullOrEmpty(settings.CoverletOutputName))
{
var dir = settings.CoverletOutputDirectory ?? project.GetDirectory();
var directoryPath = dir.MakeAbsolute(cakeEnvironment).FullPath;

var filepath = FilePath.FromString(settings.OutputTransformer(settings.CoverletOutputName, directoryPath));

builder.AppendSwitchQuoted("--output", filepath.MakeAbsolute(cakeEnvironment).FullPath);
}

if (settings.ExcludeByFile.Count > 0)
{
builder.AppendSwitchQuoted("--exclude-by-file", settings.ExcludeByFile);
}

if (settings.Exclude.Count > 0)
{
builder.AppendSwitchQuoted("--exclude", settings.Exclude);
}

if (settings.MergeWithFile != null && settings.MergeWithFile.GetExtension() == ".json")
{
builder.AppendSwitchQuoted("--merge-with", settings.MergeWithFile.MakeAbsolute(cakeEnvironment).FullPath);
}

return builder;
}

private static IEnumerable<string> SplitFlagEnum(Enum @enum) => @enum.ToString("g").Split(',').Select(s => s.ToLowerInvariant());
}
}

0 comments on commit 4d86d07

Please sign in to comment.
You can’t perform that action at this time.