├── .config
└── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── 01-bug_report.md
│ ├── 02-blank-issue-template.md
│ └── config.yml
└── workflows
│ ├── issue-close.yml
│ ├── issue-inactive.yml
│ └── issue-untriaged.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Directory.Build.props
├── Directory.Build.targets
├── Directory.Packages.props
├── Documentation
├── Changelog.md
├── ConsumeNightlyBuild.md
├── DeterministicBuild.md
├── DriversFeatures.md
├── Examples.md
├── Examples
│ ├── .editorconfig
│ ├── MSBuild
│ │ ├── DeterministicBuild
│ │ │ ├── ClassLibrary1
│ │ │ │ ├── Class1.cs
│ │ │ │ └── ClassLibrary1.csproj
│ │ │ ├── DeterministicBuild.sln
│ │ │ ├── Directory.Build.props
│ │ │ ├── Directory.Build.targets
│ │ │ ├── HowTo.md
│ │ │ └── XUnitTestProject1
│ │ │ │ ├── UnitTest1.cs
│ │ │ │ └── XUnitTestProject1.csproj
│ │ └── MergeWith
│ │ │ ├── ClassLibrary1
│ │ │ ├── Class1.cs
│ │ │ └── ClassLibrary1.csproj
│ │ │ ├── ClassLibrary2
│ │ │ ├── Class2.cs
│ │ │ └── ClassLibrary2.csproj
│ │ │ ├── ClassLibrary3
│ │ │ ├── Class3.cs
│ │ │ └── ClassLibrary3.csproj
│ │ │ ├── HowTo.md
│ │ │ ├── MergeWith.sln
│ │ │ ├── XUnitTestProject1
│ │ │ ├── UnitTest1.cs
│ │ │ └── XUnitTestProject1.csproj
│ │ │ ├── XUnitTestProject2
│ │ │ ├── UnitTest2.cs
│ │ │ └── XUnitTestProject2.csproj
│ │ │ └── XUnitTestProject3
│ │ │ ├── UnitTest3.cs
│ │ │ └── XUnitTestProject3.csproj
│ └── VSTest
│ │ ├── DeterministicBuild
│ │ ├── ClassLibrary1
│ │ │ ├── Class1.cs
│ │ │ └── ClassLibrary1.csproj
│ │ ├── DeterministicBuild.sln
│ │ ├── Directory.Build.props
│ │ ├── Directory.Build.targets
│ │ ├── HowTo.md
│ │ └── XUnitTestProject1
│ │ │ ├── UnitTest1.cs
│ │ │ └── XUnitTestProject1.csproj
│ │ └── HelloWorld
│ │ ├── ClassLibrary1
│ │ ├── Class1.cs
│ │ └── ClassLibrary1.csproj
│ │ ├── HelloWorld.sln
│ │ ├── HowTo.md
│ │ └── XUnitTestProject1
│ │ ├── .runsettings
│ │ ├── UnitTest1.cs
│ │ └── XUnitTestProject1.csproj
├── GlobalTool.md
├── KnownIssues.md
├── MSBuildIntegration.md
├── ReleasePlan.md
├── Roadmap.md
├── Troubleshooting.md
├── VSTestIntegration.md
└── images
│ ├── file.png
│ ├── nightly.PNG
│ └── nightlyExample.PNG
├── LICENSE
├── README.md
├── THIRD-PARTY-NOTICES.txt
├── _assets
├── coverlet-icon.png
├── coverlet-icon.svg
├── coverlet.png
├── coverlet@0.5x.png
├── coverlet@0.75x.png
├── coverlet@1.5x.png
├── coverlet@2x.png
├── coverlet@3x.png
└── coverlet@4x.png
├── coverlet.sln
├── eng
├── CheckNugetStatus.yml
├── azure-pipelines-nightly.yml
├── azure-pipelines.yml
├── build.sh
├── build.yml
├── publish-coverage-results.yml
├── publish-coverlet-result-files.yml
└── signclient.json
├── global.json
├── src
├── coverlet.collector
│ ├── DataCollection
│ │ ├── AttachmentManager.cs
│ │ ├── CoverageManager.cs
│ │ ├── CoverageWrapper.cs
│ │ ├── CoverletCoverageCollector.cs
│ │ ├── CoverletLogger.cs
│ │ ├── CoverletSettings.cs
│ │ └── CoverletSettingsParser.cs
│ ├── InProcDataCollection
│ │ └── CoverletInProcDataCollector.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Utilities
│ │ ├── CountDownEvent.cs
│ │ ├── CoverletConstants.cs
│ │ ├── CoverletDataCollectorException.cs
│ │ ├── DirectoryHelper.cs
│ │ ├── FileHelper.cs
│ │ ├── Interfaces
│ │ │ ├── ICountDown.cs
│ │ │ ├── ICoverageWrapper.cs
│ │ │ ├── IDirectoryHelper.cs
│ │ │ └── IFileHelper.cs
│ │ ├── TestPlatformEqtTrace.cs
│ │ └── TestPlatformLogger.cs
│ ├── build
│ │ └── coverlet.collector.targets
│ ├── coverlet.collector.csproj
│ └── coverlet.collector.snk
├── coverlet.console
│ ├── ExitCodes.cs
│ ├── Logging
│ │ ├── ConsoleLogger.cs
│ │ └── LogLevel.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.console.csproj
│ ├── coverlet.console.snk
│ └── runtimeconfig.template.json
├── coverlet.core
│ ├── Abstractions
│ │ ├── IAssemblyAdapter.cs
│ │ ├── ICecilSymbolHelper.cs
│ │ ├── IConsole.cs
│ │ ├── IFileSystem.cs
│ │ ├── IInstrumentationHelper.cs
│ │ ├── ILogger.cs
│ │ ├── IProcessExitHandler.cs
│ │ ├── IReporter.cs
│ │ ├── IRetryHelper.cs
│ │ └── ISourceRootTranslator.cs
│ ├── Attributes
│ │ ├── DoesNotReturnAttribute.cs
│ │ └── ExcludeFromCoverage.cs
│ ├── ConsoleTables
│ │ ├── .editorconfig
│ │ └── ConsoleTable.cs
│ ├── Coverage.cs
│ ├── CoverageDetails.cs
│ ├── CoveragePrepareResult.cs
│ ├── CoverageResult.cs
│ ├── CoverageSummary.cs
│ ├── Enums
│ │ ├── AssemblySearchType.cs
│ │ ├── ThresholdStatistic.cs
│ │ └── ThresholdTypeFlags.cs
│ ├── Exceptions.cs
│ ├── Extensions
│ │ └── HelperExtensions.cs
│ ├── Helpers
│ │ ├── AssemblyAdapter.cs
│ │ ├── Console.cs
│ │ ├── FileSystem.cs
│ │ ├── InstrumentationHelper.cs
│ │ ├── ProcessExitHandler.cs
│ │ ├── RetryHelper.cs
│ │ └── SourceRootTranslator.cs
│ ├── Instrumentation
│ │ ├── CecilAssemblyResolver.cs
│ │ ├── Instrumenter.cs
│ │ ├── InstrumenterResult.cs
│ │ ├── ModuleTrackerTemplate.cs
│ │ └── ReachabilityHelper.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Reporters
│ │ ├── CoberturaReporter.cs
│ │ ├── JsonReporter.cs
│ │ ├── LcovReporter.cs
│ │ ├── OpenCoverReporter.cs
│ │ ├── ReporterFactory.cs
│ │ └── TeamCityReporter.cs
│ ├── Symbols
│ │ ├── BranchPoint.cs
│ │ └── CecilSymbolHelper.cs
│ ├── coverlet.core.csproj
│ └── coverlet.core.snk
└── coverlet.msbuild.tasks
│ ├── BaseTask.cs
│ ├── CoverageResultTask.cs
│ ├── InstrumentationTask.cs
│ ├── MSBuildLogger.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── ReportWriter.cs
│ ├── coverlet.msbuild.props
│ ├── coverlet.msbuild.targets
│ ├── coverlet.msbuild.tasks.csproj
│ └── coverlet.msbuild.tasks.snk
├── test
├── .gitignore
├── Directory.Build.props
├── Directory.Build.targets
├── coverlet.collector.tests
│ ├── AttachmentManagerTests.cs
│ ├── CoverletCoverageDataCollectorTests.cs
│ ├── CoverletInProcDataCollectorTests.cs
│ ├── CoverletSettingsParserTests.cs
│ ├── CoverletSettingsTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.collector.tests.csproj
│ └── coverlet.collector.tests.snk
├── coverlet.core.coverage.tests
│ ├── Coverage
│ │ ├── CoverageTests.AsyncAwait.cs
│ │ ├── CoverageTests.AsyncAwaitValueTask.cs
│ │ ├── CoverageTests.AsyncForeach.cs
│ │ ├── CoverageTests.AsyncIterator.cs
│ │ ├── CoverageTests.AutoProps.cs
│ │ ├── CoverageTests.AwaitUsing.cs
│ │ ├── CoverageTests.CatchBlock.cs
│ │ ├── CoverageTests.DoesNotReturn.cs
│ │ ├── CoverageTests.ExcludeFromCoverageAttribute.cs
│ │ ├── CoverageTests.Filters.cs
│ │ ├── CoverageTests.GenericAsyncIterator.cs
│ │ ├── CoverageTests.Lambda.cs
│ │ ├── CoverageTests.SelectionStatements.cs
│ │ ├── CoverageTests.Yield.cs
│ │ ├── InstrumenterHelper.Assertions.cs
│ │ └── InstrumenterHelper.cs
│ ├── Instrumentation
│ │ └── ModuleTrackerTemplateTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Samples
│ │ ├── .editorconfig
│ │ ├── Instrumentation.AsyncAwait.cs
│ │ ├── Instrumentation.AsyncAwaitValueTask.cs
│ │ ├── Instrumentation.AsyncForeach.cs
│ │ ├── Instrumentation.AsyncIterator.cs
│ │ ├── Instrumentation.AutoProps.cs
│ │ ├── Instrumentation.AwaitUsing.cs
│ │ ├── Instrumentation.CatchBlock.cs
│ │ ├── Instrumentation.DoesNotReturn.cs
│ │ ├── Instrumentation.ExcludeFilter.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.Issue1302.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.Issue670.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.Issue809.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.NestedStateMachines.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.cs
│ │ ├── Instrumentation.GenericAsyncIterator.cs
│ │ ├── Instrumentation.Lambda.cs
│ │ ├── Instrumentation.SelectionStatements.cs
│ │ └── Instrumentation.Yield.cs
│ ├── coverlet.core.coverage.tests.csproj
│ └── coverlet.core.coverage.tests.snk
├── coverlet.core.performancetest
│ ├── .editorconfig
│ ├── PerformanceTest.cs
│ └── coverlet.core.performancetest.csproj
├── coverlet.core.tests.samples.netstandard
│ ├── .editorconfig
│ ├── Instrumentation.AsyncAwait.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.core.tests.samples.netstandard.csproj
│ └── coverlet.core.tests.samples.netstandard.snk
├── coverlet.core.tests
│ ├── .gitignore
│ ├── ConsoleTable
│ │ └── ConsoleTableTests.cs
│ ├── Coverage
│ │ ├── CoverageMergeTests.cs
│ │ ├── CoverageSummaryTests.cs
│ │ ├── CoverageTests.ExcludeFromCoverageAttribute.cs
│ │ ├── CoverageTests.IntegerOverflow.cs
│ │ ├── CoverageTests.cs
│ │ ├── InstrumenterHelper.Assertions.cs
│ │ └── InstrumenterHelper.cs
│ ├── CoverageResultTests.cs
│ ├── Helpers
│ │ ├── FileSystemTests.cs
│ │ ├── InstrumentationHelperTests.cs
│ │ ├── RetryHelperTests.cs
│ │ └── SourceRootTranslatorTests.cs
│ ├── Instrumentation
│ │ ├── InstrumenterResultTests.cs
│ │ └── InstrumenterTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Reporters
│ │ ├── CoberturaReporterTests.cs
│ │ ├── JsonReporterTests.cs
│ │ ├── LcovReporterTests.cs
│ │ ├── OpenCoverReporterTests.cs
│ │ ├── ReporterFactoryTests.cs
│ │ └── TeamCityReporter.cs
│ ├── Samples
│ │ ├── .editorconfig
│ │ ├── Instrumentation.DoesNotReturn.cs
│ │ └── Samples.cs
│ ├── Symbols
│ │ └── CecilSymbolHelperTests.cs
│ ├── TestAssets
│ │ ├── 75d9f96508d74def860a568f426ea4a4.dll
│ │ ├── 75d9f96508d74def860a568f426ea4a4.pdb
│ │ ├── CoverletSourceRootsMappingTest
│ │ ├── MergeWith.coverage.json
│ │ ├── System.Private.CoreLib.dll
│ │ ├── System.Private.CoreLib.pdb
│ │ ├── multiple.frameworks.runtimeconfig.json
│ │ └── single.framework.runtimeconfig.json
│ ├── coverlet.core.tests.csproj
│ └── coverlet.core.tests.snk
├── coverlet.integration.determisticbuild
│ ├── .editorconfig
│ ├── DeepThought.cs
│ ├── TemplateTest.cs
│ └── coverlet.integration.determisticbuild.csproj
├── coverlet.integration.template
│ ├── .editorconfig
│ ├── DeepThought.cs
│ ├── TemplateTest.cs
│ ├── coverlet.integration.template.csproj
│ └── nuget.config
├── coverlet.integration.tests
│ ├── AssertHelper.cs
│ ├── BaseTest.cs
│ ├── Collectors.cs
│ ├── DeterministicBuild.cs
│ ├── DotnetTool.cs
│ ├── Msbuild.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── WpfResolverTests.cs
│ ├── coverlet.integration.tests.csproj
│ └── coverlet.integration.tests.snk
├── coverlet.msbuild.tasks.tests
│ ├── CoverageResultTaskTests.cs
│ ├── InstrumentationTaskTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Reporters.cs
│ ├── TestAssets
│ │ ├── InstrumenterState.ItemSpec.data1.xml
│ │ ├── System.Private.CoreLib.dll
│ │ └── System.Private.CoreLib.pdb
│ ├── coverlet.msbuild.tasks.tests.csproj
│ └── coverlet.msbuild.tasks.tests.snk
├── coverlet.tests.projectsample.aspmvcrazor.tests
│ ├── AssemblyInfo.cs
│ ├── ResolverTests.cs
│ ├── coverlet.tests.projectsample.aspmvcrazor.tests.csproj
│ └── coverlet.tests.projectsample.aspmvcrazor.tests.snk
├── coverlet.tests.projectsample.aspmvcrazor
│ ├── Class.cs
│ ├── Program.cs
│ ├── appsettings.json
│ └── coverlet.tests.projectsample.aspmvcrazor.csproj
├── coverlet.tests.projectsample.aspnet8.tests
│ ├── AssemblyInfo.cs
│ ├── ResolverTests.cs
│ ├── coverlet.tests.projectsample.aspnet8.tests.csproj
│ └── coverlet.tests.projectsample.aspnet8.tests.snk
├── coverlet.tests.projectsample.aspnet8
│ ├── Program.cs
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── coverlet.tests.projectsample.aspnet8.csproj
├── coverlet.tests.projectsample.empty
│ ├── .editorconfig
│ ├── Class1.cs
│ └── coverlet.tests.projectsample.empty.csproj
├── coverlet.tests.projectsample.excludedbyattribute
│ ├── .editorconfig
│ ├── SampleClass.cs
│ └── coverlet.tests.projectsample.excludedbyattribute.csproj
├── coverlet.tests.projectsample.fsharp
│ ├── Library.fs
│ └── coverlet.tests.projectsample.fsharp.fsproj
├── coverlet.tests.projectsample.netframework
│ ├── .editorconfig
│ ├── AsyncAwaitStateMachineNetFramework.cs
│ └── coverlet.tests.projectsample.netframework.csproj
├── coverlet.tests.projectsample.vbmynamespace
│ ├── SampleVbClass.vb
│ └── coverlet.tests.projectsample.vbmynamespace.vbproj
├── coverlet.tests.projectsample.wpf8.selfcontained
│ ├── .editorconfig
│ ├── Program.cs
│ ├── TestClass.cs
│ └── coverlet.tests.projectsample.wpf8.selfcontained.csproj
├── coverlet.tests.projectsample.wpf8
│ ├── .editorconfig
│ ├── Program.cs
│ ├── TestClass.cs
│ └── coverlet.tests.projectsample.wpf8.csproj
├── coverlet.tests.remoteexecutor
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── RemoteExecutor.cs
│ ├── coverlet.tests.remoteexecutor.csproj
│ └── coverlet.tests.remoteexecutor.snk
├── coverlet.tests.utils
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── TestUtils.cs
│ ├── coverlet.test.utils.snk
│ └── coverlet.tests.utils.csproj
└── coverlet.testsubject
│ ├── .editorconfig
│ ├── BigClass.cs
│ └── coverlet.testsubject.csproj
└── version.json
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "dotnet-reportgenerator-globaltool": {
6 | "version": "5.4.3",
7 | "commands": [
8 | "reportgenerator"
9 | ],
10 | "rollForward": false
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/01-bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | Please share a clear and concise description of the problem.
12 |
13 | **To Reproduce**
14 | Please include minimal steps to reproduce the problem if possible. E.g.: the smallest possible code snippet; or a small project, with steps to run it. If possible include text as text rather than screenshots (so it shows up in searches).
15 |
16 | **Expected behavior**
17 | Provide a description of the expected behavior.
18 |
19 | **Actual behavior**
20 | Provide a description of the actual behavior observed. If applicable please include any error messages, exception stacktraces or memory dumps.
21 |
22 | **Configuration (please complete the following information):**
23 | Please provide more information on your .NET configuration:
24 | * Which coverlet package and version was used?
25 | * Which version of .NET is the code running on?
26 | * What OS and version, and what distro if applicable?
27 | * What is the architecture (x64, x86, ARM, ARM64)?
28 | * Do you know whether it is specific to that configuration?
29 |
30 | **Additional context**
31 | Add any other context about the problem here.
32 |
33 | > :exclamation: Please also read [Known Issues](https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/KnownIssues.md)
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/02-blank-issue-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Blank issue template
3 | about: Create a report for questions or feature requests
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/workflows/issue-close.yml:
--------------------------------------------------------------------------------
1 | name: Close inactive issues
2 | on:
3 | schedule:
4 | - cron: "0 1 * * 0"
5 | workflow_dispatch:
6 |
7 | env:
8 | DAYS_BEFORE_ISSUE_CLOSE: 275
9 |
10 | jobs:
11 | close-issues:
12 | runs-on: ubuntu-latest
13 | permissions:
14 | issues: write
15 | pull-requests: write
16 | steps:
17 | - uses: actions/stale@v9
18 | with:
19 | exempt-issue-labels: "bug,tracking-external-issue,Known Issue"
20 | days-before-issue-close: ${{ env.DAYS_BEFORE_ISSUE_CLOSE }}
21 | close-issue-message: "This issue was closed because it has been inactive for ${{ env.DAYS_BEFORE_ISSUE_CLOSE }} days since being marked as stale."
22 | days-before-pr-stale: -1
23 | days-before-pr-close: -1
24 | operations-per-run: 100
25 | repo-token: ${{ secrets.GITHUB_TOKEN }}
26 |
--------------------------------------------------------------------------------
/.github/workflows/issue-inactive.yml:
--------------------------------------------------------------------------------
1 | name: Label inactive issues
2 | on:
3 | schedule:
4 | - cron: "0 1 * * 0"
5 | workflow_dispatch:
6 |
7 | env:
8 | DAYS_BEFORE_ISSUE_STALE: 90
9 |
10 | jobs:
11 | close-issues:
12 | runs-on: ubuntu-latest
13 | permissions:
14 | issues: write
15 | pull-requests: write
16 | steps:
17 | - uses: actions/stale@v9
18 | with:
19 | exempt-issue-labels: "bug,tracking-external-issue,Known Issue,stale"
20 | days-before-issue-stale: ${{ env.DAYS_BEFORE_ISSUE_STALE }}
21 | stale-issue-label: "stale"
22 | stale-issue-message: "This issue is stale because it has been open for ${{ env.DAYS_BEFORE_ISSUE_STALE }} days with no activity."
23 | days-before-pr-stale: -1
24 | days-before-pr-close: -1
25 | operations-per-run: 100
26 | repo-token: ${{ secrets.GITHUB_TOKEN }}
27 |
--------------------------------------------------------------------------------
/.github/workflows/issue-untriaged.yml:
--------------------------------------------------------------------------------
1 | # current list of labels: untriaged|duplicate|invalid|bug|enhancement|feature-request|documentation|question|wontfix|Known issue|up-for-grabs|in progress|with repo|needs repo|tracking-external-issue
2 | # https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/Roadmap.md
3 |
4 | name: Label issues
5 | on:
6 | issues:
7 | types:
8 | - reopened
9 | - opened
10 | jobs:
11 | label_issues:
12 | runs-on: ubuntu-latest
13 | permissions:
14 | issues: write
15 | steps:
16 | - uses: actions/github-script@v6
17 | with:
18 | script: |
19 | github.rest.issues.addLabels({
20 | issue_number: context.issue.number,
21 | owner: context.repo.owner,
22 | repo: context.repo.repo,
23 | labels: ["untriaged"]
24 | })
25 |
26 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 |
3 | This project has adopted the code of conduct defined by the Contributor Covenant
4 | to clarify expected behavior in our community.
5 |
6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are highly welcome, however, except for very small changes, kindly file an issue and let's have a discussion before you open a pull request.
4 |
5 | ## Requirements
6 |
7 | [.NET SDK 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
8 | [.NET SDK 7.0](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
9 | [.NET SDK 8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
10 |
11 | ## Building the Project
12 |
13 | Clone this repo:
14 |
15 | git clone https://github.com/coverlet-coverage/coverlet.git
16 | cd coverlet
17 |
18 | Building, testing, and packing use all the standard dotnet commands:
19 |
20 | dotnet restore
21 | dotnet build --no-restore
22 | dotnet pack -c Debug
23 | dotnet test --no-build /p:CollectCoverage=true /p:Include=\"[coverlet.collector]*,[coverlet.core]*,[coverlet.msbuild.tasks]*\" /p:Exclude=\"[coverlet.core.tests.samples.netstandard]*,[coverlet.tests.xunit.extensions]*\"
24 |
25 | NB. You need to `pack` before testing because we have some integration testing that consume packages
26 |
27 | ## Performance testing
28 |
29 | There is a simple performance test for the hit counting instrumentation in the test project `coverlet.core.performancetest`. Build the project with the msbuild step above and then run:
30 |
31 | dotnet test /p:CollectCoverage=true test/coverlet.core.performancetest/
32 |
33 | The duration of the test can be tweaked by changing the number of iterations in the `[InlineData]` in the `PerformanceTest` class.
34 |
35 | For more realistic testing it is recommended to try out any changes to the hit counting code paths on large, realistic projects. If you don't have any handy https://github.com/dotnet/corefx is an excellent candidate. [This page](https://github.com/dotnet/corefx/blob/master/Documentation/building/code-coverage.md) describes how to run code coverage tests for both the full solution and for individual projects with coverlet from nuget. Suitable projects (listed in order of escalating test durations):
36 |
37 | * System.Collections.Concurrent.Tests
38 | * System.Collections.Tests
39 | * System.Reflection.Metadata.Tests
40 | * System.Xml.Linq.Events.Tests
41 | * System.Runtime.Serialization.Formatters.Tests
42 |
43 | Change to the directory of the library and run the msbuild code coverage command:
44 |
45 | dotnet test /p:Coverage=true
46 |
47 | To run with a development version of coverlet call `dotnet run` instead of the installed coverlet version, e.g.:
48 |
49 | dotnet test /p:Coverage=true /p:CoverageExecutablePath="dotnet run -p C:\...\coverlet\src\coverlet.console\coverlet.console.csproj"
50 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Documentation/ConsumeNightlyBuild.md:
--------------------------------------------------------------------------------
1 | # Consume nightly build
2 |
3 | To consume nightly builds, create a `NuGet.Config` in your root solution directory and add the following content:
4 |
5 | ```xml
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ```
18 |
19 | ## Install packages
20 |
21 | ### Visual Studio
22 |
23 | \
24 | Example:\
25 | 
26 |
27 | ### NuGet (Package Manager console)
28 |
29 | ```powershell
30 | PM> Install-Package coverlet.msbuild -Version X.X.X-preview.X.XXX -Source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
31 | ```
32 |
33 | Example:
34 |
35 | ```powershell
36 | PM> Install-Package coverlet.msbuild -Version 6.0.4-preview.4.g5de0ad7d60 -Source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
37 | ```
38 |
39 | ### .NET CLI
40 |
41 | ```bash
42 | dotnet add package coverlet.msbuild --version X.X.X-preview.X.XXX --source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
43 | ```
44 |
45 | Example:
46 |
47 | ```bash
48 | dotnet add package coverlet.msbuild --version 6.0.4-preview.4.g5de0ad7d60 --source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
49 | ```
50 |
51 | ### MSBuild project file
52 |
53 | ```xml
54 |
55 | ```
56 |
57 | Example:
58 |
59 | ```xml
60 |
61 | ```
62 |
--------------------------------------------------------------------------------
/Documentation/DeterministicBuild.md:
--------------------------------------------------------------------------------
1 | # Deterministic build
2 |
3 | Support for deterministic builds is available **only** in the `msbuild` (`/p:CollectCoverage=true`) and `collectors` (`--collect:"XPlat Code Coverage"`) drivers. Deterministic builds are important because they enable verification that the resulting binary was built from the specified sources. For more information on how to enable deterministic builds, I recommend you to take a look at [Claire Novotny](https://github.com/clairernovotny)'s [guide](https://github.com/clairernovotny/DeterministicBuilds).
4 |
5 | From a coverage perspective, deterministic builds create some challenges because coverage tools usually need access to complete source file metadata (ie. local path) during instrumentation and report generation. These files are reported inside the `.pdb` files, where debugging information is stored.
6 |
7 | In local (non-CI) builds, metadata emitted to pdbs are not "deterministic", which means that source files are reported with their full paths. For example, when we build the same project on different machines we'll have different paths emitted inside pdbs, hence, builds are "non deterministic".
8 |
9 | As explained above, to improve the level of security of generated artifacts (for instance, DLLs inside the NuGet package), we need to apply some signature (signing with certificate) and validate before usage to avoid possible security issues like tampering.
10 |
11 | Finally, thanks to deterministic CI builds (with the `ContinuousIntegrationBuild` property set to `true`) plus signature we can validate artifacts and be sure that the binary was built from specific sources (because there is no hard-coded variable metadata, like paths from different build machines).
12 |
13 | ## Deterministic report
14 |
15 | Coverlet supports also deterministic reports(for now only for __Cobertura__ coverage format).
16 | If you include `DeterministicReport` parameters for `msbuild` and `collectors` integrations resulting report will be like:
17 |
18 | ```xml
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | ...
28 | ```
29 |
30 | As you can see we have empty `` element and the `filename` start with well known deterministic fragment `/_/...`
31 |
32 | You can follow our [step-by-step sample](Examples.md)
33 |
34 | Feel free to file an issue in case you run into any trouble!
35 |
--------------------------------------------------------------------------------
/Documentation/DriversFeatures.md:
--------------------------------------------------------------------------------
1 | # Driver feature differences
2 |
3 | All Coverlet drivers share the same coverage engine. Since version 3.0.0, we've consolidated versioning across drivers, so for every new release, all drivers will have the same version number.
4 |
5 | We think that keeping the versions in sync better expresses the set of features every release will have. This does not mean that all drivers will support every functionality/feature or have the same behaviours, since they are limited by the context they're running in.
6 |
7 | In the table below we keep track of main differences:
8 |
9 | | Feature | MSBuild | .NET Tool | DataCollectors |
10 | |:-----------------------------------|:--------------|--------------|------------------|
11 | | .NET Core support(>= 6.0) | Yes | Yes | Yes |
12 | | .NET Framework support(>= 4.7.2) | Yes | Yes | Yes(since 3.0.0) |
13 | | Show result on console | Yes | Yes | No |
14 | | Deterministic reports output folder| Yes | Yes | No |
15 | | Merge reports | Yes | Yes | No |
16 | | Coverage threshold validation | Yes | Yes | No |
17 | | Deterministic build support | Yes | No | Yes |
18 |
19 | When possible, we advice you to use the collectors integration (VSTest engine integration), since it is fully integrated inside the test pipeline and does not suffer from the [known issues](KnownIssues.md) of the other drivers.
20 |
--------------------------------------------------------------------------------
/Documentation/Examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | ## MSBuild Integration
4 |
5 | * Using `/p:MergeWith` feature `Documentation/Examples/MSBuild/MergeWith/MergeWith.sln`
6 | * Deterministic build feature `Documentation/Examples/MSBuild/DeterministicBuild/DeterministicBuild.sln`
7 |
8 | ## VSTest Integration
9 |
10 | * HelloWorld sample `Documentation/Examples/VSTest/HelloWorld/HelloWorld.sln`
11 | * Deterministic build feature `Documentation/Examples/VSTest/DeterministicBuild/DeterministicBuild.sln`
12 |
--------------------------------------------------------------------------------
/Documentation/Examples/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | namespace ClassLibrary1
2 | {
3 | public class Class1
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://api.nuget.org/v3/index.json;
6 | ..\..\..\..\..\bin\$(Configuration)\Packages
7 |
8 |
9 |
10 |
11 |
12 | all
13 | runtime; build; native; contentfiles; analyzers
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 | all
14 | runtime; build; native; contentfiles; analyzers
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | namespace ClassLibrary1
2 | {
3 | public class Class1
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary2/Class2.cs:
--------------------------------------------------------------------------------
1 | namespace ClassLibrary2
2 | {
3 | public class Class2
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary2/ClassLibrary2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary3/Class3.cs:
--------------------------------------------------------------------------------
1 | namespace ClassLibrary3
2 | {
3 | public class Class3
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary3/ClassLibrary3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/HowTo.md:
--------------------------------------------------------------------------------
1 | **Run from solution root sln**
2 |
3 | To merge report together you need to run separate test and merge in one `json` format file.
4 | Last command will join and create final needed format file.
5 |
6 | ```shell
7 | dotnet test XUnitTestProject1\XUnitTestProject1.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/
8 | dotnet test XUnitTestProject2\XUnitTestProject2.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json"
9 | dotnet test XUnitTestProject3\XUnitTestProject3.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat="opencover"
10 | ```
11 |
12 | You can merge also running `dotnet test` and merge with single command from a solution file, but you need to ensure that tests will run sequentially(`-m:1`). This slow down testing but avoid invalid coverage result.
13 |
14 | ```shell
15 | dotnet test /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat=\"opencover,json\" -m:1
16 | ```
17 |
18 | N.B. You need to specify `json` format plus another format(the final one), because Coverlet can only merge proprietary format. At the end you can delete temporary `coverage.json` file.
19 |
20 | You can also merge the coverage result and generate another valid format to export the content than opencover, like cobertura.
21 |
22 | ```shell
23 | dotnet test /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat=\"cobertura,json\" -m:1
24 | ```
25 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace XUnitTestProject1
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 | new ClassLibrary1.Class1().Method();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 | all
12 | runtime; build; native; contentfiles; analyzers; buildtransitive
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject2/UnitTest2.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace XUnitTestProject2
4 | {
5 | public class UnitTest2
6 | {
7 | [Fact]
8 | public void Test2()
9 | {
10 | new ClassLibrary2.Class2().Method();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject2/XUnitTestProject2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 | all
12 | runtime; build; native; contentfiles; analyzers; buildtransitive
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject3/UnitTest3.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace XUnitTestProject3
4 | {
5 | public class UnitTest3
6 | {
7 | [Fact]
8 | public void Test3()
9 | {
10 | new ClassLibrary3.Class3().Method();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject3/XUnitTestProject3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 | all
12 | runtime; build; native; contentfiles; analyzers; buildtransitive
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | public class Class1
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://api.nuget.org/v3/index.json;
6 | ..\..\..\..\..\bin\$(Configuration)\Packages
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 | all
14 | runtime; build; native; contentfiles; analyzers
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | namespace ClassLibrary1
2 | {
3 | public class Class1
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/HowTo.md:
--------------------------------------------------------------------------------
1 | **Run from XUnitTestProject1 folder**
2 |
3 | ```shell
4 | dotnet test --collect:"XPlat Code Coverage"
5 | ```
6 |
7 | With custom runsettings file
8 |
9 | ```shell
10 | dotnet test --collect:"XPlat Code Coverage" --settings runsettings.xml
11 | ```
12 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/.runsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | lcov,cobertura
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace XUnitTestProject1
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 | new ClassLibrary1.Class1().Method();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 | $(MSBuildThisFileDirectory).runsettings
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers
16 |
17 |
18 | all
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Documentation/Roadmap.md:
--------------------------------------------------------------------------------
1 | # Roadmap
2 |
3 | This document describes the roadmap for coverlet showing priorities.
4 | Maintain coverlet means like any other project two things, answer/resolve soon as possible new issues that are blocking our users an second improve product with new features and enhancements in different areas.
5 | All coverlet issues are labeled and categorized to better support this activities.
6 |
7 | As soon as an issue is open is labeled with `untriaged` if not immediately solvable(we need to do some debugging/PoC to understand where is the issue).
8 | After triage a final correct label is applied and will be taken into account depending on priority order.
9 | We use `needs more info` if we're waiting for answers.
10 |
11 | Default priority order "should" be:
12 |
13 | 1) Bugs: we should fix bugs as soon as possible and for first bugs related to coverage because this is the goal of coverlet.
14 |
15 | Coverage bugs:
16 | Other bugs:
17 |
18 | 2) New features: analyze and add new features, we have three drivers so features could be related to one of these.
19 |
20 | Feature requests:
21 |
22 | 3) Performance: we never worked on performance aspect of coverlet, it makes sense for a "new project with some hope", but today coverlet is the facto the dotnet coverage tool, so we HAVE TO approach this aspect.
23 |
24 | Performance issues:
25 |
26 | Some new features have got a `Discussion` label if we don't have and agreement yet on semantics.
27 | Discussions:
28 |
29 | ## New features roadmap
30 |
31 | This is the list of features we should develop soon as possible:
32 |
33 | ### High priority
34 |
35 | - Allow merge reports solution wide on all flavours
36 |
37 | - Some perf improvements
38 |
39 | ### Low priority
40 |
41 | - Rethink hits reports strategy
42 |
43 | ## Maintainers discussion channel
44 |
45 | [As maintainers we should try to find a way to keep in synch, we could use a chat where we can "take note" of progress and if possible answer to questions/doubt, I know this is OSS, but it's hard keep project at high level without "more ideas".]
46 |
--------------------------------------------------------------------------------
/Documentation/images/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/Documentation/images/file.png
--------------------------------------------------------------------------------
/Documentation/images/nightly.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/Documentation/images/nightly.PNG
--------------------------------------------------------------------------------
/Documentation/images/nightlyExample.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/Documentation/images/nightlyExample.PNG
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Toni Solarin-Sodara
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/THIRD-PARTY-NOTICES.txt:
--------------------------------------------------------------------------------
1 | coverlet uses third-party libraries or other resources that may be
2 | distributed under licenses different than the coverlet software.
3 |
4 | In the event that we accidentally failed to list a required notice, please
5 | bring it to our attention by posting an issue.
6 |
7 | The attached notices are provided for information only.
8 |
9 |
10 | License notice for ConsoleTables
11 | --------------------------------
12 |
13 | The MIT License (MIT)
14 |
15 | Copyright (c) 2012 Khalid Abuhakmeh
16 |
17 | Permission is hereby granted, free of charge, to any person obtaining a copy
18 | of this software and associated documentation files (the "Software"), to deal
19 | in the Software without restriction, including without limitation the rights
20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 | copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 |
24 | The above copyright notice and this permission notice shall be included in all
25 | copies or substantial portions of the Software.
26 |
27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 | SOFTWARE.
34 |
--------------------------------------------------------------------------------
/_assets/coverlet-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet-icon.png
--------------------------------------------------------------------------------
/_assets/coverlet-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_assets/coverlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet.png
--------------------------------------------------------------------------------
/_assets/coverlet@0.5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@0.5x.png
--------------------------------------------------------------------------------
/_assets/coverlet@0.75x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@0.75x.png
--------------------------------------------------------------------------------
/_assets/coverlet@1.5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@1.5x.png
--------------------------------------------------------------------------------
/_assets/coverlet@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@2x.png
--------------------------------------------------------------------------------
/_assets/coverlet@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@3x.png
--------------------------------------------------------------------------------
/_assets/coverlet@4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/_assets/coverlet@4x.png
--------------------------------------------------------------------------------
/eng/azure-pipelines-nightly.yml:
--------------------------------------------------------------------------------
1 | pool:
2 | vmImage: 'windows-latest'
3 |
4 | steps:
5 | - task: UseDotNet@2
6 | inputs:
7 | version: 6.0.428
8 | displayName: Install .NET Core SDK 6.0.428
9 |
10 | - task: UseDotNet@2
11 | inputs:
12 | useGlobalJson: true
13 | displayName: Install .NET Core SDK 8.0.113
14 |
15 | - task: NuGetAuthenticate@1
16 | displayName: Authenticate with NuGet feeds
17 |
18 | - script: dotnet pack -c Release /p:PublicRelease=false
19 | displayName: Create NuGet packages
20 |
21 | - task: NuGetCommand@2
22 | inputs:
23 | command: push
24 | packagesToPush: $(Build.SourcesDirectory)\artifacts\package\release\*.nupkg
25 | nuGetFeedType: internal
26 | publishVstsFeed: coverlet/coverlet-nightly
27 | displayName: Publish NuGet packages
28 |
29 | - task: NuGetCommand@2
30 | inputs:
31 | command: push
32 | packagesToPush: $(Build.SourcesDirectory)\artifacts\package\release\*.snupkg
33 | nuGetFeedType: internal
34 | publishVstsFeed: coverlet/coverlet-nightly
35 | displayName: Publish NuGet symbol packages
36 |
--------------------------------------------------------------------------------
/eng/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | branches:
3 | include: ["master", "*_validate"]
4 | paths:
5 | exclude: [".github", "Documentation", "*.md"]
6 |
7 | variables:
8 | system.debug: false
9 |
10 | jobs:
11 | - job: Windows
12 | displayName: Windows
13 | continueOnError: 'true'
14 | timeoutInMinutes: 30
15 | cancelTimeoutInMinutes: 5
16 | strategy:
17 | matrix:
18 | Debug:
19 | buildConfiguration: "debug"
20 | Release:
21 | buildConfiguration: "release"
22 | pool:
23 | vmImage: 'windows-latest'
24 | steps:
25 | - template: build.yml
26 | - task: CopyFiles@2
27 | displayName: Collect packages
28 | inputs:
29 | SourceFolder: artifacts\package\$(buildConfiguration)
30 | Contents: |
31 | *.nupkg
32 | *.snupkg
33 | TargetFolder: $(Build.ArtifactStagingDirectory)\Packages
34 | condition: eq(variables['buildConfiguration'], 'release')
35 | - task: PublishBuildArtifacts@1
36 | displayName: Publish packages as build artifacts
37 | inputs:
38 | PathtoPublish: $(Build.ArtifactStagingDirectory)\Packages
39 | ArtifactName: Packages
40 | publishLocation: Container
41 | condition: eq(variables['buildConfiguration'], 'release')
42 | - task: PublishBuildArtifacts@1
43 | displayName: Publish tests artifacts
44 | inputs:
45 | PathtoPublish: $(Build.SourcesDirectory)\artifacts\publish
46 | ArtifactName: PublishedTests
47 | publishLocation: Container
48 | condition: eq(variables['buildConfiguration'], 'debug')
49 | - template: CheckNugetStatus.yml
50 | parameters:
51 | sourcePath: '$(Build.SourcesDirectory)/src'
52 | breakBuild: false
53 | # nugetConfig: '$(Build.SourcesDirectory)/nuget.config'
54 |
55 | - job: macOS
56 | displayName: macOS
57 | continueOnError: 'true'
58 | timeoutInMinutes: 30
59 | cancelTimeoutInMinutes: 5
60 | strategy:
61 | matrix:
62 | Debug:
63 | buildConfiguration: "debug"
64 | Release:
65 | buildConfiguration: "release"
66 | pool:
67 | vmImage: 'macOS-latest'
68 | steps:
69 | - template: build.yml
70 |
71 | - job: Linux
72 | displayName: Linux
73 | continueOnError: 'true'
74 | timeoutInMinutes: 30
75 | cancelTimeoutInMinutes: 5
76 | strategy:
77 | matrix:
78 | Debug:
79 | buildConfiguration: "debug"
80 | Release:
81 | buildConfiguration: "release"
82 | pool:
83 | vmImage: 'ubuntu-latest'
84 | steps:
85 | - template: build.yml
86 |
--------------------------------------------------------------------------------
/eng/publish-coverage-results.yml:
--------------------------------------------------------------------------------
1 | # File: publish-coverage-results.yml
2 | # uses reportgenerator task to create a code coverage report and aggregates available cobertura XML files. The results are publishes as a build artifact.
3 |
4 | parameters:
5 | condition: 'succeeded()'
6 | reports: ''
7 | assemblyfilters: '-xunit*'
8 | classfilters: ''
9 | breakBuild: false
10 | minimumLineCoverage: 90
11 |
12 | steps:
13 | - task: Powershell@2
14 | displayName: ReportGenerator
15 | condition: ${{parameters.condition}}
16 | inputs:
17 | targetType: inline
18 | pwsh: true
19 | script: |
20 | dotnet tool restore --add-source https://api.nuget.org/v3/index.json
21 | dotnet tool list
22 | dotnet reportgenerator -reports:"${{parameters.reports}}" -targetdir:"$(Build.SourcesDirectory)\artifacts\CoverageReport" -reporttypes:"HtmlInline_AzurePipelines_Dark;Cobertura" -assemblyfilters:"${{parameters.assemblyfilters}}" -classfilters:"${{parameters.classfilters}}" -verbosity:Verbose --minimumCoverageThresholds:lineCoverage=${{parameters.minimumLineCoverage}}
23 |
24 | - publish: '$(Build.SourcesDirectory)/artifacts/CoverageReport'
25 | displayName: 'Publish CoverageReport Artifact'
26 | artifact: CoverageResults_$(Agent.Os)_$(BuildConfiguration)
27 | condition: ${{parameters.condition}}
28 |
29 | - task: PublishCodeCoverageResults@1
30 | displayName: 'Publish code coverage'
31 | condition: ${{parameters.condition}}
32 | inputs:
33 | codeCoverageTool: Cobertura
34 | summaryFileLocation: '$(Build.SourcesDirectory)/artifacts/CoverageReport/Cobertura.xml'
35 | reportDirectory: '$(Build.SourcesDirectory)/artifacts/CoverageReport'
36 | failIfCoverageEmpty: ${{parameters.breakBuild}}
37 |
--------------------------------------------------------------------------------
/eng/publish-coverlet-result-files.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - task: CopyFiles@2
3 | displayName: Copy test results
4 | continueOnError: true
5 | condition: always()
6 | inputs:
7 | SourceFolder: '$(Build.SourcesDirectory)/artifacts'
8 | Contents: |
9 | **/*.trx
10 | **/*.html
11 | **/*.opencover.xml
12 | **/*.cobertura.xml
13 | **/*.coverage.json
14 | **/*.diag.log
15 | **/log.txt
16 | **/log.datacollector.*.txt
17 | **/log.host.*.txt
18 | TargetFolder: '$(Build.SourcesDirectory)/artifacts/TestLogs'
19 |
20 | - task: CopyFiles@2
21 | displayName: Copy trx files
22 | condition: always()
23 | inputs:
24 | SourceFolder: '$(Agent.TempDirectory)'
25 | Contents: |
26 | **/*.trx
27 | **/coverage.opencover.xml
28 | **/coverage.cobertura.xml
29 | **/coverage.json
30 | TargetFolder: '$(Build.SourcesDirectory)/artifacts/TestLogs'
31 |
32 | - task: CopyFiles@2
33 | displayName: Copy binlog files
34 | condition: always()
35 | inputs:
36 | SourceFolder: '$(Build.SourcesDirectory)'
37 | Contents: '**/*.binlog'
38 | TargetFolder: '$(Build.SourcesDirectory)/artifacts/TestLogs'
39 |
40 | - task: PublishPipelineArtifact@1
41 | displayName: Publish Coverlet logs
42 | continueOnError: true
43 | condition: always()
44 | inputs:
45 | path: artifacts/TestLogs
46 | artifactName: TestLogs_$(Agent.Os)_$(BuildConfiguration)
47 |
--------------------------------------------------------------------------------
/eng/signclient.json:
--------------------------------------------------------------------------------
1 | {
2 | "SignClient": {
3 | "AzureAd": {
4 | "AADInstance": "https://login.microsoftonline.com/",
5 | "ClientId": "c248d68a-ba6f-4aa9-8a68-71fe872063f8",
6 | "TenantId": "16076fdc-fcc1-4a15-b1ca-32c9a255900e"
7 | },
8 | "Service": {
9 | "Url": "https://codesign.dotnetfoundation.org/",
10 | "ResourceId": "https://SignService/3c30251f-36f3-490b-a955-520addb85001"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.407"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/coverlet.collector/DataCollection/CoverletLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Collector.Utilities;
6 | using Coverlet.Core.Abstractions;
7 |
8 | namespace Coverlet.Collector.DataCollection
9 | {
10 | ///
11 | /// Coverlet logger
12 | ///
13 | internal class CoverletLogger : ILogger
14 | {
15 | private readonly TestPlatformEqtTrace _eqtTrace;
16 | private readonly TestPlatformLogger _logger;
17 |
18 | public CoverletLogger(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger)
19 | {
20 | _eqtTrace = eqtTrace;
21 | _logger = logger;
22 | }
23 |
24 | ///
25 | /// Logs error
26 | ///
27 | /// Error message
28 | public void LogError(string message)
29 | {
30 | _logger.LogWarning(message);
31 | }
32 |
33 | ///
34 | /// Logs error
35 | ///
36 | /// Exception to log
37 | public void LogError(Exception exception)
38 | {
39 | _logger.LogWarning(exception.ToString());
40 | }
41 |
42 | ///
43 | /// Logs information
44 | ///
45 | /// Information message
46 | /// importance
47 | public void LogInformation(string message, bool important = false)
48 | {
49 | _eqtTrace.Info(message);
50 | }
51 |
52 | ///
53 | /// Logs verbose
54 | ///
55 | /// Verbose message
56 | public void LogVerbose(string message)
57 | {
58 | _eqtTrace.Verbose(message);
59 | }
60 |
61 | ///
62 | /// Logs warning
63 | ///
64 | /// Warning message
65 | public void LogWarning(string message)
66 | {
67 | _eqtTrace.Warning(message);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 | using System.Runtime.CompilerServices;
6 |
7 | [assembly: AssemblyKeyFile("coverlet.collector.snk")]
8 | [assembly: InternalsVisibleTo("coverlet.collector.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed0ed6af9693182615b8dcadc83c918b8d36312f86cefc69539d67d4189cd1b89420e7c3871802ffef7f5ca7816c68ad856c77bf7c230cc07824d96aa5d1237eebd30e246b9a14e22695fb26b40c800f74ea96619092cbd3a5d430d6c003fc7a82e8ccd1e315b935105d9232fe9e99e8d7ff54bba6f191959338d4a3169df9b3")]
9 | // Needed to mock internal type https://github.com/Moq/moq4/wiki/Quickstart#advanced-features
10 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
11 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CountDownEvent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Threading;
6 | using Coverlet.Collector.Utilities.Interfaces;
7 |
8 | namespace Coverlet.Collector.Utilities
9 | {
10 | internal class CollectorCountdownEventFactory : ICountDownEventFactory
11 | {
12 | public ICountDownEvent Create(int count, TimeSpan waitTimeout)
13 | {
14 | return new CollectorCountdownEvent(count, waitTimeout);
15 | }
16 | }
17 |
18 | internal class CollectorCountdownEvent : ICountDownEvent
19 | {
20 | private readonly CountdownEvent _countDownEvent;
21 | private readonly TimeSpan _waitTimeout;
22 |
23 | public CollectorCountdownEvent(int count, TimeSpan waitTimeout)
24 | {
25 | _countDownEvent = new CountdownEvent(count);
26 | _waitTimeout = waitTimeout;
27 | }
28 |
29 | public void Signal()
30 | {
31 | _countDownEvent.Signal();
32 | }
33 |
34 | public void Wait()
35 | {
36 | if (!_countDownEvent.Wait(_waitTimeout))
37 | {
38 | throw new TimeoutException($"CollectorCountdownEvent timeout after {_waitTimeout}");
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CoverletConstants.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities
5 | {
6 | internal static class CoverletConstants
7 | {
8 | public const string FriendlyName = "XPlat code coverage";
9 | public const string DefaultUri = @"datacollector://Microsoft/CoverletCodeCoverage/1.0";
10 | public const string DataCollectorName = "CoverletCoverageDataCollector";
11 | public const string DefaultReportFormat = "cobertura";
12 | public const string DefaultFileName = "coverage";
13 | public const string IncludeFiltersElementName = "Include";
14 | public const string IncludeDirectoriesElementName = "IncludeDirectory";
15 | public const string ExcludeFiltersElementName = "Exclude";
16 | public const string ExcludeSourceFilesElementName = "ExcludeByFile";
17 | public const string ExcludeAttributesElementName = "ExcludeByAttribute";
18 | public const string MergeWithElementName = "MergeWith";
19 | public const string UseSourceLinkElementName = "UseSourceLink";
20 | public const string SingleHitElementName = "SingleHit";
21 | public const string IncludeTestAssemblyElementName = "IncludeTestAssembly";
22 | public const string TestSourcesPropertyName = "TestSources";
23 | public const string ReportFormatElementName = "Format";
24 | public const string DefaultExcludeFilter = "[coverlet.*]*";
25 | public const string InProcDataCollectorName = "CoverletInProcDataCollector";
26 | public const string SkipAutoProps = "SkipAutoProps";
27 | public const string DoesNotReturnAttributesElementName = "DoesNotReturnAttribute";
28 | public const string DeterministicReport = "DeterministicReport";
29 | public const string ExcludeAssembliesWithoutSources = "ExcludeAssembliesWithoutSources";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CoverletDataCollectorException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | internal class CoverletDataCollectorException : Exception
9 | {
10 | public CoverletDataCollectorException(string message) : base(message)
11 | {
12 | }
13 |
14 | public CoverletDataCollectorException(string message, Exception innerException) : base(message, innerException)
15 | {
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/DirectoryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Collector.Utilities.Interfaces;
6 |
7 | namespace Coverlet.Collector.Utilities
8 | {
9 | ///
10 | internal class DirectoryHelper : IDirectoryHelper
11 | {
12 | ///
13 | public bool Exists(string path)
14 | {
15 | return Directory.Exists(path);
16 | }
17 |
18 | ///
19 | public void CreateDirectory(string path)
20 | {
21 | Directory.CreateDirectory(path);
22 | }
23 |
24 | ///
25 | public void Delete(string path, bool recursive)
26 | {
27 | Directory.Delete(path, recursive);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/FileHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Collector.Utilities.Interfaces;
6 |
7 | namespace Coverlet.Collector.Utilities
8 | {
9 | ///
10 | internal class FileHelper : IFileHelper
11 | {
12 | ///
13 | public bool Exists(string path)
14 | {
15 | return File.Exists(path);
16 | }
17 |
18 | ///
19 | public void WriteAllText(string path, string contents)
20 | {
21 | File.WriteAllText(path, contents);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/ICountDown.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Collector.Utilities.Interfaces
7 | {
8 |
9 | ///
10 | /// Factory for ICountDownEvent
11 | ///
12 | internal interface ICountDownEventFactory
13 | {
14 | ///
15 | /// Create ICountDownEvent instance
16 | ///
17 | /// count of CountDownEvent
18 | /// max wait
19 | ///
20 | ICountDownEvent Create(int count, TimeSpan waitTimeout);
21 | }
22 |
23 | ///
24 | /// Wrapper interface for CountDownEvent
25 | ///
26 | internal interface ICountDownEvent
27 | {
28 | ///
29 | /// Signal event
30 | ///
31 | void Signal();
32 |
33 | ///
34 | /// Wait for event
35 | ///
36 | void Wait();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/ICoverageWrapper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Coverlet.Collector.DataCollection;
5 | using Coverlet.Core;
6 | using Coverlet.Core.Abstractions;
7 |
8 | namespace Coverlet.Collector.Utilities.Interfaces
9 | {
10 | ///
11 | /// Wrapper interface for Coverage class in coverlet.core
12 | /// Since the class is not testable, this interface is used to abstract methods for mocking in unit tests.
13 | ///
14 | internal interface ICoverageWrapper
15 | {
16 | ///
17 | /// Creates a coverage object from given coverlet settings
18 | ///
19 | /// Coverlet settings
20 | /// Coverlet logger
21 | /// Coverlet instrumentationHelper
22 | /// Coverlet fileSystem
23 | /// Coverlet sourceRootTranslator
24 | ///
25 | /// Coverage object
26 | Coverage CreateCoverage(CoverletSettings settings, ILogger logger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper);
27 |
28 | ///
29 | /// Gets the coverage result from provided coverage object
30 | ///
31 | /// Coverage
32 | /// The coverage result
33 | CoverageResult GetCoverageResult(Coverage coverage);
34 |
35 | ///
36 | /// Prepares modules for getting coverage.
37 | /// Wrapper over coverage.PrepareModules
38 | ///
39 | ///
40 | void PrepareModules(Coverage coverage);
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/IDirectoryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities.Interfaces
5 | {
6 | interface IDirectoryHelper
7 | {
8 | ///
9 | /// Determines whether the specified directory exists.
10 | ///
11 | /// The directory to check.
12 | /// true if the caller has the required permissions and path contains the name of an existing directory; otherwise, false.
13 | /// This method also returns false if path is null, an invalid path, or a zero-length string.
14 | /// If the caller does not have sufficient permissions to read the specified file,
15 | /// no exception is thrown and the method returns false regardless of the existence of path.
16 | bool Exists(string path);
17 |
18 | ///
19 | /// Creates all directories and subdirectories in the specified path unless they already exist.
20 | ///
21 | /// The directory to create.
22 | void CreateDirectory(string directory);
23 |
24 | ///
25 | /// Deletes the specified directory and, if indicated, any subdirectories and files in the directory.
26 | ///
27 | /// The name of the directory to remove.
28 | /// true to remove directories, subdirectories, and files in path; otherwise, false.
29 | void Delete(string path, bool recursive);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/IFileHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities.Interfaces
5 | {
6 | internal interface IFileHelper
7 | {
8 | ///
9 | /// Determines whether the specified file exists.
10 | ///
11 | /// The file to check.
12 | /// true if the caller has the required permissions and path contains the name of an existing file; otherwise, false.
13 | /// This method also returns false if path is null, an invalid path, or a zero-length string.
14 | /// If the caller does not have sufficient permissions to read the specified file,
15 | /// no exception is thrown and the method returns false regardless of the existence of path.
16 | bool Exists(string path);
17 |
18 | ///
19 | /// Creates a new file, writes the specified string to the file, and then closes the file.
20 | /// If the target file already exists, it is overwritten.
21 | ///
22 | /// The file to write to.
23 | /// The string to write to the file.
24 | void WriteAllText(string path, string contents);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.VisualStudio.TestPlatform.ObjectModel;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | ///
9 | /// Test platform eqttrace
10 | ///
11 | internal class TestPlatformEqtTrace
12 | {
13 | public bool IsInfoEnabled => EqtTrace.IsInfoEnabled;
14 | public bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled;
15 |
16 | ///
17 | /// Verbose logger
18 | ///
19 | /// Format
20 | /// Args
21 | public void Verbose(string format, params object[] args)
22 | {
23 | EqtTrace.Verbose($"[coverlet]{format}", args);
24 | }
25 |
26 | ///
27 | /// Warning logger
28 | ///
29 | /// Format
30 | /// Args
31 | public void Warning(string format, params object[] args)
32 | {
33 | EqtTrace.Warning($"[coverlet]{format}", args);
34 | }
35 |
36 | ///
37 | /// Info logger
38 | ///
39 | /// Format
40 | /// Args
41 | public void Info(string format, params object[] args)
42 | {
43 | EqtTrace.Info($"[coverlet]{format}", args);
44 | }
45 |
46 | ///
47 | /// Error logger
48 | ///
49 | /// Format
50 | /// Args
51 | public void Error(string format, params object[] args)
52 | {
53 | EqtTrace.Error($"[coverlet]{format}", args);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/TestPlatformLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | ///
9 | /// Test platform logger
10 | ///
11 | internal class TestPlatformLogger
12 | {
13 | private readonly DataCollectionLogger _logger;
14 | private readonly DataCollectionContext _dataCollectionContext;
15 |
16 | public TestPlatformLogger(DataCollectionLogger logger, DataCollectionContext dataCollectionContext)
17 | {
18 | _logger = logger;
19 | _dataCollectionContext = dataCollectionContext;
20 | }
21 |
22 | ///
23 | /// Log warning
24 | ///
25 | /// Warning message
26 | public void LogWarning(string warning)
27 | {
28 | _logger.LogWarning(_dataCollectionContext, $"[coverlet]{warning}");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/coverlet.collector/coverlet.collector.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/src/coverlet.collector/coverlet.collector.snk
--------------------------------------------------------------------------------
/src/coverlet.console/ExitCodes.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | ///
7 | /// Exit Codes returned from Coverlet console process.
8 | ///
9 | [Flags]
10 | internal enum CommandExitCodes
11 | {
12 | ///
13 | /// Indicates successful run of dotnet test without any test failure and coverage percentage above threshold if provided.
14 | ///
15 | Success = 0,
16 |
17 | ///
18 | /// Indicates test failure by dotnet test.
19 | ///
20 | TestFailed = 1,
21 |
22 | ///
23 | /// Indicates coverage percentage is below given threshold for one or more threshold type.
24 | ///
25 | CoverageBelowThreshold = 2,
26 |
27 | ///
28 | /// Indicates exception occurred during Coverlet process.
29 | ///
30 | Exception = 101,
31 |
32 | ///
33 | /// Indicates missing options or empty arguments for Coverlet process.
34 | ///
35 | CommandParsingException = 102
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/src/coverlet.console/Logging/ConsoleLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 | using static System.Console;
7 |
8 | namespace Coverlet.Console.Logging
9 | {
10 | class ConsoleLogger : ILogger
11 | {
12 | private static readonly object s_sync = new();
13 |
14 | public LogLevel Level { get; set; } = LogLevel.Normal;
15 |
16 | public void LogError(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Red);
17 |
18 | public void LogError(Exception exception) => LogError(exception.ToString());
19 |
20 | public void LogInformation(string message, bool important = false) => Log(important ? LogLevel.Minimal : LogLevel.Normal, message, ForegroundColor);
21 |
22 | public void LogVerbose(string message) => Log(LogLevel.Detailed, message, ForegroundColor);
23 |
24 | public void LogWarning(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Yellow);
25 |
26 | private void Log(LogLevel level, string message, ConsoleColor color)
27 | {
28 | if (level < Level) return;
29 |
30 | lock (s_sync)
31 | {
32 | ConsoleColor currentForegroundColor;
33 | if (color != (currentForegroundColor = ForegroundColor))
34 | {
35 | ForegroundColor = color;
36 | WriteLine(message);
37 | ForegroundColor = currentForegroundColor;
38 | }
39 | else
40 | {
41 | WriteLine(message);
42 | }
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/coverlet.console/Logging/LogLevel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Console.Logging
5 | {
6 | ///
7 | /// Defines logging severity levels.
8 | ///
9 | enum LogLevel
10 | {
11 | ///
12 | /// Logs that track the general flow of the application. These logs should have long-term value.
13 | ///
14 | Detailed = 0,
15 |
16 | ///
17 | /// Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the
18 | /// application execution to stop.
19 | ///
20 | Normal = 1,
21 |
22 | ///
23 | /// Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a
24 | /// failure in the current activity, not an application-wide failure.
25 | ///
26 | Minimal = 2,
27 |
28 | ///
29 | /// Not used for writing log messages. Specifies that a logging category should not write any messages except warning and errors.
30 | ///
31 | Quiet = 3
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/coverlet.console/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: System.Reflection.AssemblyKeyFileAttribute("coverlet.console.snk")]
7 | [assembly: InternalsVisibleTo("coverlet.integration.tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001d24efbe9cbc2dc49b7a3d2ae34ca37cfb69b4f450acd768a22ce5cd021c8a38ae7dc68b2809a1ac606ad531b578f192a5690b2986990cbda4dd84ec65a3a4c1c36f6d7bb18f08592b93091535eaee2f0c8e48763ed7f190db2008e1f9e0facd5c0df5aaab74febd3430e09a428a72e5e6b88357f92d78e47512d46ebdc3cbb")]
8 |
9 |
--------------------------------------------------------------------------------
/src/coverlet.console/coverlet.console.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | coverlet
7 | true
8 | coverlet.console
9 |
10 |
11 |
12 |
13 | $(AssemblyTitle)
14 | tonerdo
15 | Coverlet is a cross platform code coverage tool for .NET, with support for line, branch and method coverage.
16 | coverage;testing;unit-test;lcov;opencover;quality
17 | GlobalTool.md
18 | https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/Changelog.md
19 | https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true
20 | coverlet-icon.png
21 | https://github.com/coverlet-coverage/coverlet
22 | MIT
23 | git
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | true
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/coverlet.console/coverlet.console.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coverlet-coverage/coverlet/0a2024d31a4c0948fabe7d1bfe8c4e1f0725cab2/src/coverlet.console/coverlet.console.snk
--------------------------------------------------------------------------------
/src/coverlet.console/runtimeconfig.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "rollForwardOnNoCandidateFx": 2
3 | }
4 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IAssemblyAdapter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IAssemblyAdapter
7 | {
8 | string GetAssemblyName(string assemblyPath);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ICecilSymbolHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using Coverlet.Core.Symbols;
6 | using Mono.Cecil;
7 | using Mono.Cecil.Cil;
8 |
9 | namespace Coverlet.Core.Abstractions
10 | {
11 | internal interface ICecilSymbolHelper
12 | {
13 | IReadOnlyList GetBranchPoints(MethodDefinition methodDefinition);
14 | bool SkipNotCoverableInstruction(MethodDefinition methodDefinition, Instruction instruction);
15 | bool SkipInlineAssignedAutoProperty(bool skipAutoProps, MethodDefinition methodDefinition, Instruction instruction);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IConsole.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IConsole
7 | {
8 | public void WriteLine(string value);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IFileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IFileSystem
9 | {
10 | bool Exists(string path);
11 |
12 | void WriteAllText(string path, string contents);
13 |
14 | string ReadAllText(string path);
15 |
16 | Stream OpenRead(string path);
17 |
18 | void Copy(string sourceFileName, string destFileName, bool overwrite);
19 |
20 | void Delete(string path);
21 |
22 | Stream NewFileStream(string path, FileMode mode);
23 |
24 | Stream NewFileStream(string path, FileMode mode, FileAccess access);
25 |
26 | string[] ReadAllLines(string path);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IInstrumentationHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using Coverlet.Core.Enums;
6 |
7 | namespace Coverlet.Core.Abstractions
8 | {
9 | internal interface IInstrumentationHelper
10 | {
11 | void BackupOriginalModule(string module, string identifier);
12 | void DeleteHitsFile(string path);
13 | string[] GetCoverableModules(string module, string[] directories, bool includeTestAssembly);
14 | bool HasPdb(string module, out bool embedded);
15 | IEnumerable SelectModules(IEnumerable modules, string[] includeFilters, string[] excludeFilters);
16 | bool IsValidFilterExpression(string filter);
17 | bool IsTypeExcluded(string module, string type, string[] excludeFilters);
18 | bool IsTypeIncluded(string module, string type, string[] includeFilters);
19 | void RestoreOriginalModule(string module, string identifier);
20 | bool EmbeddedPortablePdbHasLocalSource(string module, AssemblySearchType excludeAssembliesWithoutSources);
21 | bool PortablePdbHasLocalSource(string module, AssemblySearchType excludeAssembliesWithoutSources);
22 | bool IsLocalMethod(string method);
23 | void SetLogger(ILogger logger);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ILogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface ILogger
9 | {
10 | void LogVerbose(string message);
11 | void LogInformation(string message, bool important = false);
12 | void LogWarning(string message);
13 | void LogError(string message);
14 | void LogError(Exception exception);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IProcessExitHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IProcessExitHandler
9 | {
10 | void Add(EventHandler handler);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IReporter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IReporter
7 | {
8 | ReporterOutputType OutputType { get; }
9 | string Format { get; }
10 | string Extension { get; }
11 | string Report(CoverageResult result, ISourceRootTranslator sourceRootTranslator);
12 | }
13 |
14 | internal enum ReporterOutputType
15 | {
16 | File,
17 | Console,
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IRetryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IRetryHelper
9 | {
10 | void Retry(Action action, Func backoffStrategy, int maxAttemptCount = 3);
11 | T Do(Func action, Func backoffStrategy, int maxAttemptCount = 3);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ISourceRootTranslator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using Coverlet.Core.Helpers;
6 |
7 | namespace Coverlet.Core.Abstractions
8 | {
9 | internal interface ISourceRootTranslator
10 | {
11 | bool AddMappingInCache(string originalFileName, string targetFileName);
12 | string ResolveFilePath(string originalFileName);
13 | string ResolveDeterministicPath(string originalFileName);
14 | IReadOnlyList ResolvePathRoot(string pathRoot);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Attributes/DoesNotReturnAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Attributes
7 | {
8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class)]
9 | internal class DoesNotReturnAttribute : Attribute { }
10 | }
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/Attributes/ExcludeFromCoverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Attributes
7 | {
8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class)]
9 | internal sealed class ExcludeFromCoverageAttribute : Attribute { }
10 | }
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/ConsoleTables/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/src/coverlet.core/CoverageDetails.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core
7 | {
8 | internal class CoverageDetails
9 | {
10 | private double _averageModulePercent;
11 |
12 | public Modules Modules { get; internal set; }
13 | public double Covered { get; internal set; }
14 | public int Total { get; internal set; }
15 | public double Percent
16 | {
17 | get
18 | {
19 | if (Modules?.Count == 0) return 0;
20 | return Total == 0 ? 100D : Math.Floor((Covered / Total) * 10000) / 100;
21 | }
22 | }
23 |
24 | public double AverageModulePercent
25 | {
26 | get { return Math.Floor(_averageModulePercent * 100) / 100; }
27 | internal set { _averageModulePercent = value; }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/coverlet.core/CoveragePrepareResult.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using System.Runtime.Serialization;
6 | using Coverlet.Core.Instrumentation;
7 |
8 | namespace Coverlet.Core
9 | {
10 | // Followed safe serializer guide, will emit xml format
11 | // https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2300-do-not-use-insecure-deserializer-binaryformatter?view=vs-2019
12 | // https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2301-do-not-call-binaryformatter-deserialize-without-first-setting-binaryformatter-binder?view=vs-2019
13 | [DataContract]
14 | internal class CoveragePrepareResult
15 | {
16 | [DataMember]
17 | public string Identifier { get; set; }
18 | [DataMember]
19 | public string ModuleOrDirectory { get; set; }
20 | [DataMember]
21 | public string MergeWith { get; set; }
22 | [DataMember]
23 | public bool UseSourceLink { get; set; }
24 | [DataMember]
25 | public InstrumenterResult[] Results { get; set; }
26 | [DataMember]
27 | public CoverageParameters Parameters { get; set; }
28 |
29 | public static CoveragePrepareResult Deserialize(Stream serializedInstrumentState)
30 | {
31 | return (CoveragePrepareResult)new DataContractSerializer(typeof(CoveragePrepareResult)).ReadObject(serializedInstrumentState);
32 | }
33 |
34 | public static Stream Serialize(CoveragePrepareResult instrumentState)
35 | {
36 | var ms = new MemoryStream();
37 | new DataContractSerializer(typeof(CoveragePrepareResult)).WriteObject(ms, instrumentState);
38 | ms.Position = 0;
39 | return ms;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/coverlet.core/Enums/AssemblySearchType.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Enums
5 | {
6 | internal enum AssemblySearchType
7 | {
8 | MissingAny,
9 | MissingAll,
10 | None
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/coverlet.core/Enums/ThresholdStatistic.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Enums
5 | {
6 | internal enum ThresholdStatistic
7 | {
8 | Minimum,
9 | Average,
10 | Total
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/coverlet.core/Enums/ThresholdTypeFlags.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Enums
7 | {
8 | [Flags]
9 | internal enum ThresholdTypeFlags
10 | {
11 | None = 0,
12 | Line = 2,
13 | Branch = 4,
14 | Method = 8
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Exceptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Exceptions
7 | {
8 | [Serializable]
9 | public class CoverletException : Exception
10 | {
11 | public CoverletException() { }
12 | public CoverletException(string message) : base(message) { }
13 | public CoverletException(string message, System.Exception inner) : base(message, inner) { }
14 | protected CoverletException(
15 | System.Runtime.Serialization.SerializationInfo info,
16 | System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
17 | }
18 |
19 | [Serializable]
20 | internal class CecilAssemblyResolutionException : CoverletException
21 | {
22 | public CecilAssemblyResolutionException() { }
23 | public CecilAssemblyResolutionException(string message) : base(message) { }
24 | public CecilAssemblyResolutionException(string message, System.Exception inner) : base(message, inner) { }
25 | protected CecilAssemblyResolutionException(
26 | System.Runtime.Serialization.SerializationInfo info,
27 | System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/coverlet.core/Extensions/HelperExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Attributes;
6 |
7 | namespace Coverlet.Core.Extensions
8 | {
9 | internal static class HelperExtensions
10 | {
11 | [ExcludeFromCoverage]
12 | public static TRet Maybe(this T value, Func action, TRet defValue = default)
13 | where T : class
14 | {
15 | return (value != null) ? action(value) : defValue;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/AssemblyAdapter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | internal class AssemblyAdapter : IAssemblyAdapter
10 | {
11 | public string GetAssemblyName(string assemblyPath)
12 | {
13 | return AssemblyName.GetAssemblyName(assemblyPath).Name;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/Console.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | public class SystemConsole : IConsole
10 | {
11 | public void WriteLine(string value)
12 | {
13 | Console.WriteLine(value);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/FileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | internal class FileSystem : IFileSystem
10 | {
11 | // We need to partial mock this method on tests
12 | public virtual bool Exists(string path)
13 | {
14 | return File.Exists(path);
15 | }
16 |
17 | public void WriteAllText(string path, string contents)
18 | {
19 | File.WriteAllText(path, contents);
20 | }
21 |
22 | public string ReadAllText(string path)
23 | {
24 | return File.ReadAllText(path);
25 | }
26 |
27 | // We need to partial mock this method on tests
28 | public virtual Stream OpenRead(string path)
29 | {
30 | return File.OpenRead(path);
31 | }
32 |
33 | public void Copy(string sourceFileName, string destFileName, bool overwrite)
34 | {
35 | File.Copy(sourceFileName, destFileName, overwrite);
36 | }
37 |
38 | public void Delete(string path)
39 | {
40 | File.Delete(path);
41 | }
42 |
43 | // We need to partial mock this method on tests
44 | public virtual Stream NewFileStream(string path, FileMode mode)
45 | {
46 | return new FileStream(path, mode);
47 | }
48 |
49 | // We need to partial mock this method on tests
50 | public virtual Stream NewFileStream(string path, FileMode mode, FileAccess access)
51 | {
52 | return new FileStream(path, mode, access);
53 | }
54 |
55 | public string[] ReadAllLines(string path)
56 | {
57 | return File.ReadAllLines(path);
58 | }
59 |
60 | // Escape format characters in file names
61 | internal static string EscapeFileName(string fileName)
62 | {
63 | return fileName?.Replace("{", "{{").Replace("}", "}}");
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/ProcessExitHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | internal class ProcessExitHandler : IProcessExitHandler
10 | {
11 | public void Add(EventHandler handler)
12 | {
13 | AppDomain.CurrentDomain.ProcessExit += handler;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/RetryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Threading;
8 | using Coverlet.Core.Abstractions;
9 |
10 | namespace Coverlet.Core.Helpers
11 | {
12 | // A slightly amended version of the code found here: https://stackoverflow.com/a/1563234/186184
13 | // This code allows for varying backoff strategies through the use of Func.
14 | internal class RetryHelper : IRetryHelper
15 | {
16 | ///
17 | /// Retry a void method.
18 | ///
19 | /// The action to perform
20 | /// A function returning a Timespan defining the backoff strategy to use.
21 | /// The maximum number of retries before bailing out. Defaults to 3.
22 | public void Retry(
23 | Action action,
24 | Func backoffStrategy,
25 | int maxAttemptCount = 3)
26 | {
27 | Do