From a2f5c45879c6a744424dedcce4dc385a60292788 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Tue, 6 Oct 2020 11:39:22 +0200 Subject: [PATCH 1/9] (GH-43) corrected documentation --- .../{Analysers.md => RecommendedReferences.md} | 0 docs/input/rules/ccg0006.md | 9 ++++----- 2 files changed, 4 insertions(+), 5 deletions(-) rename docs/input/guidelines/{Analysers.md => RecommendedReferences.md} (100%) diff --git a/docs/input/guidelines/Analysers.md b/docs/input/guidelines/RecommendedReferences.md similarity index 100% rename from docs/input/guidelines/Analysers.md rename to docs/input/guidelines/RecommendedReferences.md diff --git a/docs/input/rules/ccg0006.md b/docs/input/rules/ccg0006.md index f3c7e0e..d7eac1b 100644 --- a/docs/input/rules/ccg0006.md +++ b/docs/input/rules/ccg0006.md @@ -4,7 +4,7 @@ Title: CCG0006 Description: Missing recommended configuraion-file --- - > No reference to `.editorconfig` found. Usage of `.editorconfig` is strongly recommended. + > No reference to `[fileName]` found. Usage of `[fileName]` is strongly recommended. @@ -23,12 +23,11 @@ This warning is raised, when a recommended configuration-file (i.e. `stylecop.js ## Description -Code-Formatting and layout should be properly configured. This is done using -blah and blah. +Code-Formatting and layout should be properly configured. This is done using `.editorconfig` and `stylecop.json`. ## How to fix violations -Add a balh and blah to the project. +Add the required files to the project. Example-Files can be found at: @@ -39,4 +38,4 @@ Example-Files can be found at: ## Related guidelines -* [Usage of Analysers](../guidelines/Analysers) \ No newline at end of file +* [Recommended References](../guidelines/RecommendedReferences) \ No newline at end of file From 1f67e44470820d4a00c0541710f0960087ca3452 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Thu, 8 Oct 2020 08:41:22 +0200 Subject: [PATCH 2/9] (maint) fixed two broken links in docs and removed unneeded reference --- docs/input/guidelines/RecommendedReferences.md | 4 ++-- docs/input/rules/ccg0006.md | 4 ++-- src/Tasks.Tests/Tasks.Tests.csproj | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/input/guidelines/RecommendedReferences.md b/docs/input/guidelines/RecommendedReferences.md index c996298..e824a01 100644 --- a/docs/input/guidelines/RecommendedReferences.md +++ b/docs/input/guidelines/RecommendedReferences.md @@ -21,8 +21,8 @@ To have consistency in code-style among the different tools/plugins the use of A Example-Files can be found at: -* [`stylecop.json`](./examples/StyleCopJson.md) -* [`.editorconfig`](./examples/Editorconfig.md) +* [`stylecop.json`](./examples/StyleCopJson) +* [`.editorconfig`](./examples/Editorconfig) ## Related rules diff --git a/docs/input/rules/ccg0006.md b/docs/input/rules/ccg0006.md index d7eac1b..7918565 100644 --- a/docs/input/rules/ccg0006.md +++ b/docs/input/rules/ccg0006.md @@ -31,8 +31,8 @@ Add the required files to the project. Example-Files can be found at: -* [`stylecop.json`](../guidelines/examples/StyleCopJson.md) -* [`.editorconfig`](../guidelines/examples/Editorconfig.md) +* [`stylecop.json`](../guidelines/examples/StyleCopJson) +* [`.editorconfig`](../guidelines/examples/Editorconfig) (Or opt-out of this rule, by setting `CakeContribGuidelinesOmitRecommendedConfigFile`) diff --git a/src/Tasks.Tests/Tasks.Tests.csproj b/src/Tasks.Tests/Tasks.Tests.csproj index b9cb776..3a26c54 100644 --- a/src/Tasks.Tests/Tasks.Tests.csproj +++ b/src/Tasks.Tests/Tasks.Tests.csproj @@ -30,7 +30,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive From c241537770dbc7769d0353cc61d95279a73f6a68 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Tue, 13 Oct 2020 19:55:50 +0200 Subject: [PATCH 3/9] (maint) removed another unneeded reference --- src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj index e97ecb1..c2e0a3f 100644 --- a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj +++ b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj @@ -30,7 +30,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive From d363f3dbf81f8797268a6a6b29e9e4a3a31134dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2020 06:30:08 +0000 Subject: [PATCH 4/9] (maint): Bump Moq from 4.14.6 to 4.14.7 Bumps [Moq](https://github.com/moq/moq4) from 4.14.6 to 4.14.7. - [Release notes](https://github.com/moq/moq4/releases) - [Changelog](https://github.com/moq/moq4/blob/master/CHANGELOG.md) - [Commits](https://github.com/moq/moq4/compare/v4.14.6...v4.14.7) Signed-off-by: dependabot[bot] --- .../Tasks.IntegrationTests.csproj | 100 ++++++++--------- src/Tasks.Tests/Tasks.Tests.csproj | 102 +++++++++--------- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj index c2e0a3f..e3fd6d7 100644 --- a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj +++ b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj @@ -1,51 +1,51 @@ - - - - netcoreapp2.1;netcoreapp3.1; - $(TargetFrameworks);net472 - CakeContrib.Guidelines.Tasks.IntegrationTests - CakeContrib.Guidelines.Tasks.IntegrationTests - false - - - - $(DefineConstants);NETFRAMEWORK - - - $(DefineConstants);NETCORE - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - runtime; build; native; contentfiles; analyzers - all - - - - - - - - - + + + + netcoreapp2.1;netcoreapp3.1; + $(TargetFrameworks);net472 + CakeContrib.Guidelines.Tasks.IntegrationTests + CakeContrib.Guidelines.Tasks.IntegrationTests + false + + + + $(DefineConstants);NETFRAMEWORK + + + $(DefineConstants);NETCORE + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + runtime; build; native; contentfiles; analyzers + all + + + + + + + + + \ No newline at end of file diff --git a/src/Tasks.Tests/Tasks.Tests.csproj b/src/Tasks.Tests/Tasks.Tests.csproj index 3a26c54..884859b 100644 --- a/src/Tasks.Tests/Tasks.Tests.csproj +++ b/src/Tasks.Tests/Tasks.Tests.csproj @@ -1,51 +1,51 @@ - - - - netcoreapp2.1;netcoreapp3.1; - $(TargetFrameworks);net472 - CakeContrib.Guidelines.Tasks.Tests - CakeContrib.Guidelines.Tasks.Tests - false - - - - $(DefineConstants);NETFRAMEWORK - - - $(DefineConstants);NETCORE - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - runtime; build; native; contentfiles; analyzers - all - - - - - - - - - - + + + + netcoreapp2.1;netcoreapp3.1; + $(TargetFrameworks);net472 + CakeContrib.Guidelines.Tasks.Tests + CakeContrib.Guidelines.Tasks.Tests + false + + + + $(DefineConstants);NETFRAMEWORK + + + $(DefineConstants);NETCORE + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + runtime; build; native; contentfiles; analyzers + all + + + + + + + + + + From c212fce00de92a54fcc2aee421150dcaf75c8aa7 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Fri, 23 Oct 2020 17:47:44 +0200 Subject: [PATCH 5/9] (maint) removed some warnings --- .gitignore | 3 +++ src/Tasks.IntegrationTests/E2eTests.cs | 7 ++----- src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs | 3 +-- src/Tasks.Tests/CheckPrivateAssetsOnReferencesTests.cs | 6 +++--- .../Fixtures/RequiredFileStylecopJsonFixture.cs | 2 -- src/Tasks.Tests/RequiredReferencesTests.cs | 4 ++-- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 0b598f7..f007d44 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ docs/input/tasks/* # Wyam related config.wyam.* + +# JetBrains Rider +.idea/ diff --git a/src/Tasks.IntegrationTests/E2eTests.cs b/src/Tasks.IntegrationTests/E2eTests.cs index 32cafe6..86bbd50 100644 --- a/src/Tasks.IntegrationTests/E2eTests.cs +++ b/src/Tasks.IntegrationTests/E2eTests.cs @@ -1,14 +1,11 @@ using System; using System.IO; - -using CakeContrib.Guidelines.Tasks.Tests.Fixtures; - +using CakeContrib.Guidelines.Tasks.IntegrationTests.Fixtures; using FluentAssertions; - using Xunit; using Xunit.Abstractions; -namespace CakeContrib.Guidelines.Tasks.Tests +namespace CakeContrib.Guidelines.Tasks.IntegrationTests { // TODO: Writing things to disk is not deterministic... // TODO: Running Code-Coverage on the integration-tests breaks all tests diff --git a/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs b/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs index 7b814c3..e78e29b 100644 --- a/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs +++ b/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs @@ -3,10 +3,9 @@ using System.Diagnostics; using System.IO; using System.Linq; - using Xunit.Abstractions; -namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures +namespace CakeContrib.Guidelines.Tasks.IntegrationTests.Fixtures { public class E2eTestFixture : IDisposable { diff --git a/src/Tasks.Tests/CheckPrivateAssetsOnReferencesTests.cs b/src/Tasks.Tests/CheckPrivateAssetsOnReferencesTests.cs index 657193f..7597e8a 100644 --- a/src/Tasks.Tests/CheckPrivateAssetsOnReferencesTests.cs +++ b/src/Tasks.Tests/CheckPrivateAssetsOnReferencesTests.cs @@ -45,7 +45,7 @@ public void Should_Error_If_Package_Has_Not_PrivateAssets() { // given var fixture = new CheckPrivateAssetsOnReferencesFixture(); - fixture.WithReferencedPackage("Cake.Core", ""); + fixture.WithReferencedPackage("Cake.Core"); fixture.WithPackageToCheck("Cake.Core"); // when @@ -60,7 +60,7 @@ public void Should_Log_Correct_ErrorCode_On_Error() { // given var fixture = new CheckPrivateAssetsOnReferencesFixture(); - fixture.WithReferencedPackage("Cake.Core", ""); + fixture.WithReferencedPackage("Cake.Core"); fixture.WithPackageToCheck("Cake.Core"); // when @@ -78,7 +78,7 @@ public void Should_Log_Correct_ErrorSourceFile_On_Error_With_Given_ProjectFile() // given const string projectFileName = "some.project.csproj"; var fixture = new CheckPrivateAssetsOnReferencesFixture(); - fixture.WithReferencedPackage("Cake.Core", ""); + fixture.WithReferencedPackage("Cake.Core"); fixture.WithPackageToCheck("Cake.Core"); fixture.WithProjectFile(projectFileName); diff --git a/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs b/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs index 2bb8beb..10c107a 100644 --- a/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs +++ b/src/Tasks.Tests/Fixtures/RequiredFileStylecopJsonFixture.cs @@ -2,8 +2,6 @@ using Microsoft.Build.Framework; -using Moq; - namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures { public class RequiredFileStylecopJsonFixture : BaseBuildFixture diff --git a/src/Tasks.Tests/RequiredReferencesTests.cs b/src/Tasks.Tests/RequiredReferencesTests.cs index 54b98fd..5a4b30b 100644 --- a/src/Tasks.Tests/RequiredReferencesTests.cs +++ b/src/Tasks.Tests/RequiredReferencesTests.cs @@ -35,7 +35,7 @@ public void Should_Warn_If_RequiredPackage_Is_Not_Referenced() fixture.WithRequiredReferences("Some.Analyser"); // when - var actual = fixture.Execute(); + fixture.Execute(); // then fixture.BuildEngine.WarningEvents.Should().HaveCount(1); @@ -54,7 +54,7 @@ public void Should_Not_Warn_If_RequiredPackage_Is_Omitted() fixture.WithOmittedReferences(required); // when - var actual = fixture.Execute(); + fixture.Execute(); // then fixture.BuildEngine.WarningEvents.Should().HaveCount(0); From 77ad36e5ce51a21cb383a11cb1a52f5fc30afc36 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Tue, 27 Oct 2020 23:56:36 +0100 Subject: [PATCH 6/9] (maint) added a workflow for dependabot-cake-action --- .github/workflows/dependabot-cake.yml | 13 ++++ src/Tasks.Tests/Tasks.Tests.csproj | 102 +++++++++++++------------- 2 files changed, 64 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/dependabot-cake.yml diff --git a/.github/workflows/dependabot-cake.yml b/.github/workflows/dependabot-cake.yml new file mode 100644 index 0000000..f34a967 --- /dev/null +++ b/.github/workflows/dependabot-cake.yml @@ -0,0 +1,13 @@ +name: Run dependabot for cake +on: + workflow_dispatch: + schedule: + # run everyday at 6 + - cron: '0 6 * * *' + +jobs: + dependabot-cake: + runs-on: ubuntu-latest # linux, because this is a docker-action + steps: + - name: check/update cake dependencies + uses: nils-org/dependabot-cake-action@v1 \ No newline at end of file diff --git a/src/Tasks.Tests/Tasks.Tests.csproj b/src/Tasks.Tests/Tasks.Tests.csproj index 884859b..fe81bbc 100644 --- a/src/Tasks.Tests/Tasks.Tests.csproj +++ b/src/Tasks.Tests/Tasks.Tests.csproj @@ -1,51 +1,51 @@ - - - - netcoreapp2.1;netcoreapp3.1; - $(TargetFrameworks);net472 - CakeContrib.Guidelines.Tasks.Tests - CakeContrib.Guidelines.Tasks.Tests - false - - - - $(DefineConstants);NETFRAMEWORK - - - $(DefineConstants);NETCORE - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - runtime; build; native; contentfiles; analyzers - all - - - - - - - - - - + + + + netcoreapp2.1;netcoreapp3.1; + $(TargetFrameworks);net472 + CakeContrib.Guidelines.Tasks.Tests + CakeContrib.Guidelines.Tasks.Tests + false + + + + $(DefineConstants);NETFRAMEWORK + + + $(DefineConstants);NETCORE + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + runtime; build; native; contentfiles; analyzers + all + + + + + + + + + + From 1d6061a26603a6bc8ba58b2552571303aadf9365 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2020 22:57:54 +0000 Subject: [PATCH 7/9] Bump Cake.Recipe from 2.0.0 to 2.0.1 Bumps [Cake.Recipe](https://github.com/cake-contrib/Cake.Recipe) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/cake-contrib/Cake.Recipe/releases) - [Changelog](https://github.com/cake-contrib/Cake.Recipe/blob/develop/GitReleaseManager.yaml) - [Commits](https://github.com/cake-contrib/Cake.Recipe/compare/2.0.0...2.0.1) --- recipe.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipe.cake b/recipe.cake index 59360d1..9089caa 100644 --- a/recipe.cake +++ b/recipe.cake @@ -1,4 +1,4 @@ -#load nuget:?package=Cake.Recipe&version=2.0.0 +#load nuget:?package=Cake.Recipe&version=2.0.1 Environment.SetVariableNames(); From 1c82d88a3a779307848a559d8c367eef534053f3 Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Tue, 27 Oct 2020 23:53:23 +0100 Subject: [PATCH 8/9] (GH-48) test for required/suggested targetFramework- versions. (CCG0007 error/warning) --- docs/input/guidelines/TargetFramework.md | 54 +++++ docs/input/rules/ccg0007.md | 43 ++++ src/CakeContrib.Guidelines.sln.DotSettings | 6 + .../build/CakeContrib.Guidelines.targets | 1 + .../build/TargetFrameworkVersions.targets | 21 ++ src/Tasks.IntegrationTests/E2eTests.cs | 33 +++ .../Fixtures/E2eTestFixture.cs | 14 +- src/Tasks.Tests/Extensions/ExtensionTests.cs | 67 ++++++ .../TargetFrameworkVersionsFixture.cs | 61 +++++ .../TargetFrameworkVersionsTests.cs | 107 +++++++++ src/Tasks/Extensions/VersionExtensions.cs | 58 +++++ src/Tasks/TargetFrameworkVersions.cs | 218 ++++++++++++++++++ 12 files changed, 680 insertions(+), 3 deletions(-) create mode 100644 docs/input/guidelines/TargetFramework.md create mode 100644 docs/input/rules/ccg0007.md create mode 100644 src/CakeContrib.Guidelines.sln.DotSettings create mode 100644 src/Guidelines/build/TargetFrameworkVersions.targets create mode 100644 src/Tasks.Tests/Extensions/ExtensionTests.cs create mode 100644 src/Tasks.Tests/Fixtures/TargetFrameworkVersionsFixture.cs create mode 100644 src/Tasks.Tests/TargetFrameworkVersionsTests.cs create mode 100644 src/Tasks/Extensions/VersionExtensions.cs create mode 100644 src/Tasks/TargetFrameworkVersions.cs diff --git a/docs/input/guidelines/TargetFramework.md b/docs/input/guidelines/TargetFramework.md new file mode 100644 index 0000000..e4d7477 --- /dev/null +++ b/docs/input/guidelines/TargetFramework.md @@ -0,0 +1,54 @@ +--- +Order: 4 +Title: Target Frameworks +--- + + + +## Table of Contents + +- [Goals](#goals) +- [Related rules](#related-rules) +- [Usage](#usage) +- [Settings](#settings) + - [Opt-Out](#opt-out) + + + +## Goals + +As .NET Framework < 4.7.2 has issues with running .NET Standard assemblies, and Cake itself can run on .NET Framework 4.6.1 it is suggested to multi-target addins to `netstandard2.0` and `net461` to have the maximum compatibility. + +### Required / Suggested versions + +Depending on the referenced `Cake.Core`-version different target versions are required and/or suggested. +Missing a required target version will raise [CCG0007](../rules/ccg0007) as an error +while missing a suggested target version will raise [CCG0007](../rules/ccg0007) as a warning. + +* Cake.Core <= 0.33.0 + * Required: `netstandard2.0` + * Suggested: `net461` + * alternative: `net46` + +## Related rules + + * [CCG0007](../rules/ccg0007) + +## Usage + +Using this package automatically enables this guideline. + +## Settings + +### Opt-Out + +It it possible to opt-out of the check for target framework using the following setting: + +(*Keep in mind, though that it is not recommended to opt-out of this feature*) + +```xml + + + + +``` diff --git a/docs/input/rules/ccg0007.md b/docs/input/rules/ccg0007.md new file mode 100644 index 0000000..27afffc --- /dev/null +++ b/docs/input/rules/ccg0007.md @@ -0,0 +1,43 @@ +--- +Order: 7 +Title: CCG0007 +Description: Missing recommended target +--- + + > Missing required target: netstandard2.0 + + + +## Table of Contents + +- [Cause](#cause) +- [Description](#description) +- [How to fix violations](#how-to-fix-violations) +- [Related guidelines](#related-guidelines) + + + +## Cause + +This warning is raised, when the addin is not targeted to a recommended target version. +Also, This could be raised as an error, if a required target version is not set. + +## Description + +Addins should be multi-targeted to `netstandard2.0` and `net461` to have the maximum compatibility. + +## How to fix violations + +Add the recommended target(s) to the project: + +```xml + + netstandard2.0;net472 + +``` + +(Or opt-out of this rule, by setting `CakeContribGuidelinesOmitTargetFramework`) + +## Related guidelines + +* [Target Frameworks](../guidelines/TargetFramework) \ No newline at end of file diff --git a/src/CakeContrib.Guidelines.sln.DotSettings b/src/CakeContrib.Guidelines.sln.DotSettings new file mode 100644 index 0000000..61f5d6a --- /dev/null +++ b/src/CakeContrib.Guidelines.sln.DotSettings @@ -0,0 +1,6 @@ + + True + True + True + True + True \ No newline at end of file diff --git a/src/Guidelines/build/CakeContrib.Guidelines.targets b/src/Guidelines/build/CakeContrib.Guidelines.targets index da22dc5..645ec72 100644 --- a/src/Guidelines/build/CakeContrib.Guidelines.targets +++ b/src/Guidelines/build/CakeContrib.Guidelines.targets @@ -9,4 +9,5 @@ + diff --git a/src/Guidelines/build/TargetFrameworkVersions.targets b/src/Guidelines/build/TargetFrameworkVersions.targets new file mode 100644 index 0000000..611d042 --- /dev/null +++ b/src/Guidelines/build/TargetFrameworkVersions.targets @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/Tasks.IntegrationTests/E2eTests.cs b/src/Tasks.IntegrationTests/E2eTests.cs index 86bbd50..07d4f74 100644 --- a/src/Tasks.IntegrationTests/E2eTests.cs +++ b/src/Tasks.IntegrationTests/E2eTests.cs @@ -1,7 +1,10 @@ using System; using System.IO; + using CakeContrib.Guidelines.Tasks.IntegrationTests.Fixtures; + using FluentAssertions; + using Xunit; using Xunit.Abstractions; @@ -191,5 +194,35 @@ public void Missing_file_editorconfig_results_in_CCG0006_warning() result.WarningLines.Should().Contain(l => l.IndexOf("CCG0006", StringComparison.Ordinal) > -1); result.WarningLines.Should().Contain(l => l.IndexOf(".editorconfig", StringComparison.Ordinal) > -1); } + + [Fact] + public void Missing_Required_Target_results_in_CCG0007_error() + { + // given + fixture.WithTargetFrameworks("net47"); + + // when + var result = fixture.Run(); + + // then + result.IsErrorExitCode.Should().BeTrue(); + result.ErrorLines.Should().Contain(l => l.IndexOf("CCG0007", StringComparison.Ordinal) > -1); + result.ErrorLines.Should().Contain(l => l.IndexOf("netstandard2.0", StringComparison.Ordinal) > -1); + } + + [Fact] + public void Missing_Suggested_Target_results_in_CCG0007_warning() + { + // given + fixture.WithTargetFrameworks("netstandard2.0"); + + // when + var result = fixture.Run(); + + // then + result.IsErrorExitCode.Should().BeFalse(); + result.WarningLines.Should().Contain(l => l.IndexOf("CCG0007", StringComparison.Ordinal) > -1); + result.WarningLines.Should().Contain(l => l.IndexOf("net461", StringComparison.Ordinal) > -1); + } } } diff --git a/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs b/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs index e78e29b..aa7aa83 100644 --- a/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs +++ b/src/Tasks.IntegrationTests/Fixtures/E2eTestFixture.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Linq; + using Xunit.Abstractions; namespace CakeContrib.Guidelines.Tasks.IntegrationTests.Fixtures @@ -17,7 +18,8 @@ public class E2eTestFixture : IDisposable private bool hasStylecopJson = true; private bool hasStylecopReference = true; private bool hasEditorConfig = true; - private List customContent = new List(); + private readonly List customContent = new List(); + private string targetFrameworks = "netstandard2.0;net461"; public E2eTestFixture(string tempFolder, ITestOutputHelper logger) { @@ -40,7 +42,7 @@ private string WriteProject() - netstandard2.0 + {5} {2} @@ -94,7 +96,8 @@ private string WriteProject() targets.Item2, string.Join(Environment.NewLine, properties), string.Join(Environment.NewLine, items), - string.Join(Environment.NewLine, customContent))); + string.Join(Environment.NewLine, customContent), + targetFrameworks)); return csproj; } @@ -134,6 +137,11 @@ internal void WithoutFileEditorconfig() hasEditorConfig = false; } + internal void WithTargetFrameworks(string targetFrameworks) + { + this.targetFrameworks = targetFrameworks; + } + private Tuple GetTargetsToImport() { var codeBase = typeof(E2eTestFixture).Assembly.CodeBase; diff --git a/src/Tasks.Tests/Extensions/ExtensionTests.cs b/src/Tasks.Tests/Extensions/ExtensionTests.cs new file mode 100644 index 0000000..07a5693 --- /dev/null +++ b/src/Tasks.Tests/Extensions/ExtensionTests.cs @@ -0,0 +1,67 @@ +using System; + +using CakeContrib.Guidelines.Tasks.Extensions; + +using FluentAssertions; + +using Xunit; + +namespace CakeContrib.Guidelines.Tasks.Tests.Extensions +{ + public class VersionExtensionTests + { + [Fact] + public void GreaterEqual_Is_True_For_Equal_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build); + + a.GreaterEqual(b).Should().BeTrue(); + } + + [Fact] + public void GreaterEqual_Is_True_For_Greater_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build - 1); + + a.GreaterEqual(b).Should().BeTrue(); + } + + [Fact] + public void GreaterEqual_Is_False_For_Lesser_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build + 1); + + a.GreaterEqual(b).Should().BeFalse(); + } + + [Fact] + public void LessEqual_Is_True_For_Equal_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build); + + a.LessEqual(b).Should().BeTrue(); + } + + [Fact] + public void LessEqual_Is_True_For_Lesser_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build + 1); + + a.LessEqual(b).Should().BeTrue(); + } + + [Fact] + public void LessEqual_Is_False_For_Greater_Versions() + { + var a = new Version(1, 2, 3); + var b = new Version(a.Major, a.Minor, a.Build - 1); + + a.LessEqual(b).Should().BeFalse(); + } + } +} diff --git a/src/Tasks.Tests/Fixtures/TargetFrameworkVersionsFixture.cs b/src/Tasks.Tests/Fixtures/TargetFrameworkVersionsFixture.cs new file mode 100644 index 0000000..578bf23 --- /dev/null +++ b/src/Tasks.Tests/Fixtures/TargetFrameworkVersionsFixture.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using System.Linq; + +using Microsoft.Build.Framework; + +using Moq; + +namespace CakeContrib.Guidelines.Tasks.Tests.Fixtures +{ + public class TargetFrameworkVersionsFixture : BaseBuildFixture + { + private readonly List references; + private readonly List targetFrameworks; + private ITaskItem targetFramework; + private readonly List omittedTargets; + + public TargetFrameworkVersionsFixture() + { + references = new List(); + omittedTargets = new List(); + targetFrameworks = new List(); + targetFramework = null; + } + + public override bool Execute() + { + Task.References = references.ToArray(); + Task.TargetFramework = targetFramework; + Task.TargetFrameworks = targetFrameworks.ToArray(); + Task.Omitted = omittedTargets.ToArray(); + return base.Execute(); + } + + public void WithTargetFramwork(string packageName) + { + targetFramework = GetMockTaskItem(packageName).Object; + } + + public void WithTargetFramworks(params string[] packageNames) + { + targetFrameworks.AddRange(packageNames.Select(n => GetMockTaskItem(n).Object)); + } + + public void WithOmittedTargetFramework(string targetFramework) + { + omittedTargets.Add(GetMockTaskItem(targetFramework).Object); + } + + public void WithCakeCoreReference(int major = 0, int minor = 0, int patch = 0) + { + var cakeRef = GetMockTaskItem("Cake.Core"); + cakeRef.Setup(x => x.GetMetadata("Version")).Returns($"{major}.{minor}.{patch}"); + references.Add(cakeRef.Object); + } + + public void WithProjectFile(string fileName) + { + Task.ProjectFile = fileName; + } + } +} diff --git a/src/Tasks.Tests/TargetFrameworkVersionsTests.cs b/src/Tasks.Tests/TargetFrameworkVersionsTests.cs new file mode 100644 index 0000000..d27c38e --- /dev/null +++ b/src/Tasks.Tests/TargetFrameworkVersionsTests.cs @@ -0,0 +1,107 @@ +using System.Linq; + +using CakeContrib.Guidelines.Tasks.Tests.Fixtures; + +using FluentAssertions; + +using Xunit; + +namespace CakeContrib.Guidelines.Tasks.Tests +{ + public class TargetFrameworkVersionsTests + { + private const string NetStandard20 = "netstandard2.0"; + private const string Net46 = "net46"; + private const string Net461 = "net461"; + + [Fact] + public void Should_Error_If_RequiredTargetFramework_Is_Not_Targeted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(1); + fixture.BuildEngine.ErrorEvents.First().Message.Should().Contain(NetStandard20); + } + + [Fact] + public void Should_Not_Error_If_RequiredTargetFramework_Is_Not_Targeted_But_Omitted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + fixture.WithOmittedTargetFramework(NetStandard20); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(0); + } + + [Fact] + public void Should_Warn_If_SuggestedTargetFramework_Is_Not_Targeted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + fixture.WithTargetFramwork(NetStandard20); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(0); + fixture.BuildEngine.WarningEvents.Should().HaveCount(1); + fixture.BuildEngine.WarningEvents.First().Message.Should().Contain(Net46); + } + + [Fact] + public void Should_Not_Warn_If_SuggestedTargetFramework_Is_Not_Targeted_But_Omitted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + fixture.WithTargetFramwork(NetStandard20); + fixture.WithOmittedTargetFramework(Net461); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(0); + fixture.BuildEngine.WarningEvents.Should().HaveCount(0); + } + + [Fact] + public void Should_Not_Warn_If_Required_And_SuggestedTargetFramework_Is_Targeted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + fixture.WithTargetFramworks(NetStandard20, Net461); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(0); + fixture.BuildEngine.WarningEvents.Should().HaveCount(0); + } + + [Fact] + public void Should_Not_Warn_If_Required_And_Alternative_SuggestedTargetFramework_Is_Targeted() + { + // given + var fixture = new TargetFrameworkVersionsFixture(); + fixture.WithTargetFramworks(NetStandard20, Net46); + + // when + fixture.Execute(); + + // then + fixture.BuildEngine.ErrorEvents.Should().HaveCount(0); + fixture.BuildEngine.WarningEvents.Should().HaveCount(0); + } + } +} diff --git a/src/Tasks/Extensions/VersionExtensions.cs b/src/Tasks/Extensions/VersionExtensions.cs new file mode 100644 index 0000000..a84f80a --- /dev/null +++ b/src/Tasks/Extensions/VersionExtensions.cs @@ -0,0 +1,58 @@ +using System; + +namespace CakeContrib.Guidelines.Tasks.Extensions +{ + /// + /// internal extensions to . + /// + internal static class VersionExtensions + { + /// + /// compares two versions. + /// + /// the version that is extended. + /// the version to compare to. + /// + /// true, if is greater or equal to . + /// false, otherwise. + /// + public static bool GreaterEqual(this Version baseVersion, Version compareTo) + { + if (baseVersion == null) + { + throw new ArgumentNullException(nameof(baseVersion)); + } + + if (compareTo == null) + { + throw new ArgumentNullException(nameof(compareTo)); + } + + return baseVersion.CompareTo(compareTo) > -1; + } + + /// + /// compares two versions. + /// + /// the version that is extended. + /// the version to compare to. + /// + /// true, if is less or equal to . + /// false, otherwise. + /// + public static bool LessEqual(this Version baseVersion, Version compareTo) + { + if (baseVersion == null) + { + throw new ArgumentNullException(nameof(baseVersion)); + } + + if (compareTo == null) + { + throw new ArgumentNullException(nameof(compareTo)); + } + + return baseVersion.CompareTo(compareTo) < 1; + } + } +} diff --git a/src/Tasks/TargetFrameworkVersions.cs b/src/Tasks/TargetFrameworkVersions.cs new file mode 100644 index 0000000..144b13c --- /dev/null +++ b/src/Tasks/TargetFrameworkVersions.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using CakeContrib.Guidelines.Tasks.Extensions; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace CakeContrib.Guidelines.Tasks +{ + /// + /// The Task to check for References for the guideline . + /// + public class TargetFrameworkVersions : Task + { + private const string NetStandard20 = "netstandard2.0"; + private const string Net46 = "net46"; + private const string Net461 = "net461"; + + private static readonly Version Zero26 = new Version(0, 26, 0); + + private static readonly TargetsDefinitions DefaultTarget = new TargetsDefinitions + { + RequiredTargets = new[] { TargetsDefinition.From(NetStandard20) }, + SuggestedTargets = new[] { TargetsDefinition.From(Net461, Net46) }, + }; + + private static readonly Dictionary, TargetsDefinitions> SpecificTargets = + new Dictionary, TargetsDefinitions> + { + { + v => v.GreaterEqual(Zero26), + new TargetsDefinitions + { + RequiredTargets = new[] { TargetsDefinition.From(NetStandard20) }, + SuggestedTargets = new[] { TargetsDefinition.From(Net461, Net46) }, + } + }, + }; + + /// + /// Gets or sets the References. + /// + [Required] + public ITaskItem[] References { get; set; } + + /// + /// Gets or sets the TargetFrameworks. + /// + [Required] + public ITaskItem[] TargetFrameworks { get; set; } + + /// + /// Gets or sets the TargetFramework. + /// + [Required] + public ITaskItem TargetFramework { get; set; } + + /// + /// Gets or sets the project file. + /// + public string ProjectFile { get; set; } + + /// + /// Gets or sets Targets to omit. I.e. if those are missing, they will not be reported. + /// + public ITaskItem[] Omitted { get; set; } + + /// + public override bool Execute() + { + // find cake.core version + var cakeCore = + References?.FirstOrDefault(x => x.ToString().Equals("Cake.Core", StringComparison.OrdinalIgnoreCase)); + if (cakeCore == null) + { + Log.LogMessage( + MessageImportance.Low, + "Could not find Cake.Core reference. Using default TargetVersions."); + return Execute(DefaultTarget); + } + + if (!Version.TryParse(cakeCore.GetMetadata("version"), out Version version)) + { + Log.LogWarning( + $"Cake.Core has a version of {cakeCore.GetMetadata("version")} which is not a valid version. Using default TargetVersions."); + return Execute(DefaultTarget); + } + + foreach (var targetsDefinition in SpecificTargets) + { + var match = targetsDefinition.Key(version); + if (!match) + { + continue; + } + + return Execute(targetsDefinition.Value); + } + + Log.LogMessage( + MessageImportance.Low, + $"Could not find a specific TargetVersions-setting for Cake.Core version {version}. Using default TargetVersions."); + return Execute(DefaultTarget); + } + + private bool Execute(TargetsDefinitions targets) + { + var allTargets = new List(); + if (TargetFramework != null) + { + allTargets.Add(TargetFramework.ToString()); + } + + if (TargetFrameworks != null) + { + allTargets.AddRange(TargetFrameworks.Select(x => x.ToString())); + } + + allTargets = allTargets.Distinct().ToList(); + + // first, check required targets + Log.LogMessage( + MessageImportance.Low, + $"Comparing TargetFramework[s] ({string.Join(";", allTargets)}) to required: {string.Join(",", targets.RequiredTargets.Select(x => x.Name))}."); + + foreach (var requiredTarget in targets.RequiredTargets) + { + if (Omitted != null && Omitted.Any(x => x.ToString().Equals(requiredTarget.Name, StringComparison.OrdinalIgnoreCase))) + { + Log.LogMessage(MessageImportance.Low, $"Required TargetFramework '{requiredTarget.Name}' is set to omit."); + continue; + } + + if (allTargets.Any(x => x.Equals(requiredTarget.Name, StringComparison.OrdinalIgnoreCase))) + { + continue; + } + + var found = requiredTarget.Alternatives?.Any(alternative => allTargets.Contains(alternative)); + if (found.GetValueOrDefault(false)) + { + continue; + } + + Log.LogError( + null, + "CCG0007", + string.Empty, + ProjectFile ?? string.Empty, + 0, + 0, + 0, + 0, + "Missing required target: " + requiredTarget.Name); + return false; + } + + // now, check suggested targets + Log.LogMessage( + MessageImportance.Low, + $"Comparing TargetFramework[s] ({string.Join(";", allTargets)}) to suggested: {string.Join(",", targets.SuggestedTargets.Select(x => x.Name))}."); + + foreach (var suggestedTarget in targets.SuggestedTargets) + { + if (Omitted != null && Omitted.Any(x => x.ToString().Equals(suggestedTarget.Name, StringComparison.OrdinalIgnoreCase))) + { + Log.LogMessage(MessageImportance.Low, $"Suggested TargetFramework '{suggestedTarget.Name}' is set to omit."); + continue; + } + + if (allTargets.Any(x => x.Equals(suggestedTarget.Name, StringComparison.OrdinalIgnoreCase))) + { + continue; + } + + var found = suggestedTarget.Alternatives?.Any(alternative => allTargets.Contains(alternative)); + if (found.GetValueOrDefault(false)) + { + continue; + } + + Log.LogWarning( + null, + "CCG0007", + string.Empty, + ProjectFile ?? string.Empty, + 0, + 0, + 0, + 0, + "Missing suggested target: " + suggestedTarget.Name); + } + + return true; + } + + private class TargetsDefinitions + { + public TargetsDefinition[] RequiredTargets { get; set; } + + public TargetsDefinition[] SuggestedTargets { get; set; } + } + + private class TargetsDefinition + { + public string Name { get; private set; } + + public string[] Alternatives { get; private set; } + + public static TargetsDefinition From(string name, params string[] alternatives) + { + return new TargetsDefinition { Name = name, Alternatives = alternatives ?? Array.Empty(), }; + } + } + } +} From fefa21df82dd6b07843d6fae41c74ce5d6350ab6 Mon Sep 17 00:00:00 2001 From: nils-a Date: Tue, 27 Oct 2020 23:07:44 +0000 Subject: [PATCH 9/9] docs: update TOC --- docs/input/guidelines/TargetFramework.md | 1 + .../Tasks.IntegrationTests.csproj | 100 +++++++++--------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/docs/input/guidelines/TargetFramework.md b/docs/input/guidelines/TargetFramework.md index e4d7477..f8bc333 100644 --- a/docs/input/guidelines/TargetFramework.md +++ b/docs/input/guidelines/TargetFramework.md @@ -8,6 +8,7 @@ Title: Target Frameworks ## Table of Contents - [Goals](#goals) + - [Required / Suggested versions](#required--suggested-versions) - [Related rules](#related-rules) - [Usage](#usage) - [Settings](#settings) diff --git a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj index e3fd6d7..aeadf7d 100644 --- a/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj +++ b/src/Tasks.IntegrationTests/Tasks.IntegrationTests.csproj @@ -1,51 +1,51 @@ - - - - netcoreapp2.1;netcoreapp3.1; - $(TargetFrameworks);net472 - CakeContrib.Guidelines.Tasks.IntegrationTests - CakeContrib.Guidelines.Tasks.IntegrationTests - false - - - - $(DefineConstants);NETFRAMEWORK - - - $(DefineConstants);NETCORE - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - runtime; build; native; contentfiles; analyzers - all - - - - - - - - - + + + + netcoreapp2.1;netcoreapp3.1; + $(TargetFrameworks);net472 + CakeContrib.Guidelines.Tasks.IntegrationTests + CakeContrib.Guidelines.Tasks.IntegrationTests + false + + + + $(DefineConstants);NETFRAMEWORK + + + $(DefineConstants);NETCORE + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + runtime; build; native; contentfiles; analyzers + all + + + + + + + + + \ No newline at end of file