diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9ec9a19..084675a 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-reportgenerator-globaltool": { - "version": "4.7.1", + "version": "5.1.10", "commands": [ "reportgenerator" ] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b83a27a..5feb34a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,8 @@ { "name": "RulesEngine Codespace", - "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:0.201.7-3.1", + "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:0-6.0", "settings": { - "terminal.integrated.defaultProfile.linux": "pwsh" + "terminal.integrated.defaultProfile.linux": "bash" }, "extensions": [ "eamodio.gitlens", @@ -12,12 +12,15 @@ "cschleiden.vscode-github-actions", "redhat.vscode-yaml", "bierner.markdown-preview-github-styles", - "ban.spellright", - "jmrog.vscode-nuget-package-manager", "coenraads.bracket-pair-colorizer", "vscode-icons-team.vscode-icons", - "editorconfig.editorconfig" + "editorconfig.editorconfig", + "aliasadidev.nugetpackagemanagergui", + "formulahendry.dotnet-test-explorer" ], "postCreateCommand": "dotnet restore RulesEngine.sln && dotnet build RulesEngine.sln --configuration Release --no-restore && dotnet test RulesEngine.sln --configuration Release --no-build --verbosity minimal", + "features": { + "powershell": "7.1" + }, } // Built with ❤ by [Pipeline Foundation](https://pipeline.foundation) diff --git a/.github/workflows/dotnetcore-build.yml b/.github/workflows/dotnetcore-build.yml index b2e13b2..58359d8 100644 --- a/.github/workflows/dotnetcore-build.yml +++ b/.github/workflows/dotnetcore-build.yml @@ -8,35 +8,13 @@ on: jobs: build: - runs-on: ubuntu-latest - steps: - # extract branch name - - name: Extract branch name - if: github.event_name != 'pull_request' - shell: bash - run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV - id: extract_branch - - # extract branch name on pull request - - name: Extract branch name on pull request - if: github.event_name == 'pull_request' - run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF})" >> $GITHUB_ENV - - # print branch name - - name: Get branch name - run: echo "The branch name is ${{ env.BRANCH_NAME }}" - - - uses: actions/checkout@v3 - name: Setup .NET Core uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.x - - - name: Install minicover - run: dotnet tool install --global minicover --version 3.4.4 - name: Install dependencies run: dotnet restore RulesEngine.sln @@ -44,19 +22,20 @@ jobs: - name: Build run: dotnet build RulesEngine.sln --configuration Release --no-restore - - name: Instrument - run: minicover instrument - - name: Test - run: dotnet test RulesEngine.sln --no-build --configuration Release --verbosity m + run: dotnet test RulesEngine.sln --collect:"XPlat Code Coverage" --no-build --configuration Release --verbosity m + + - name: Generate Report + shell: pwsh + run: ./scripts/generate-coverage-report.ps1 + + - name: Check Coverage + shell: pwsh + run: ./scripts/check-coverage.ps1 -reportPath coveragereport/Cobertura.xml -threshold 96 - - name: Uninstrument - run: minicover uninstrument - - - name: Report - run: minicover report --threshold 95 - if: ${{ github.event_name == 'pull_request' }} - - - name: Report coveralls - run: minicover coverallsreport --repo-token ${{ secrets.COVERALLS_TOKEN }} --branch ${{ env.BRANCH_NAME }} + - name: Coveralls GitHub Action + uses: coverallsapp/github-action@1.1.3 if: ${{ github.event_name == 'push' }} + with: + github-token: ${{ secrets.COVERALLS_TOKEN }} + path-to-lcov: ./coveragereport/lcov.info diff --git a/CHANGELOG.md b/CHANGELOG.md index 832163c..76180ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ All notable changes to this project will be documented in this file. +## [4.0.0] +- RulesEngine is now available in both dotnet 6 and netstandard 2.0 +- Dependency on ILogger, MemoryCache have been removed +- Obsolete Properties and Methods have been removed +### Breaking Changes +- ILogger has been removed from RulesEngine and all its constructors +```diff +- RulesEngine(string[] jsonConfig, ILogger logger = null, ReSettings reSettings = null) ++ RulesEngine(string[] jsonConfig, ReSettings reSettings = null) + +- RulesEngine(Workflow[] Workflows, ILogger logger = null, ReSettings reSettings = null) ++ RulesEngine(Workflow[] Workflows, ReSettings reSettings = null) + +- RulesEngine(ILogger logger = null, ReSettings reSettings = null) ++ RulesEngine(ReSettings reSettings = null) +``` +- Obsolete methods and properties have been removed, from the follow models:- + - RuleResultTree + - `ToResultTreeMessages()` has been removed from `RuleResultTree` model + - `GetMessages()` has been removed from `RuleResultTree` model + - `RuleEvaluatedParams` has been removed from `RuleResultTree` model, Please use `Inputs` instead + + - Workflow + - `WorkflowRulesToInject` has been removed, Please use `WorkflowsToInject` instead + - `ErrorType` has been removed from `Rule` + + - Resettings + - `EnableLocalParams` has been removed from `ReSettings`, Please use `EnableScopedParams` instead + + ## [3.5.0] - `EvaluateRule` action now support custom inputs and filtered inputs - Added `ContainsWorkflow` method in RulesEngine (by @okolobaxa) diff --git a/benchmark/RulesEngineBenchmark/RulesEngineBenchmark.csproj b/benchmark/RulesEngineBenchmark/RulesEngineBenchmark.csproj index e7acc8c..798d5fc 100644 --- a/benchmark/RulesEngineBenchmark/RulesEngineBenchmark.csproj +++ b/benchmark/RulesEngineBenchmark/RulesEngineBenchmark.csproj @@ -6,7 +6,7 @@ - + diff --git a/demo/DemoApp.EFDataExample/DemoApp.EFDataExample.csproj b/demo/DemoApp.EFDataExample/DemoApp.EFDataExample.csproj index 19c8bda..cd75c12 100644 --- a/demo/DemoApp.EFDataExample/DemoApp.EFDataExample.csproj +++ b/demo/DemoApp.EFDataExample/DemoApp.EFDataExample.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -7,8 +7,8 @@ - - + + diff --git a/demo/DemoApp.EFDataExample/RulesEngineContext.cs b/demo/DemoApp.EFDataExample/RulesEngineContext.cs index 35bcd27..ff1b616 100644 --- a/demo/DemoApp.EFDataExample/RulesEngineContext.cs +++ b/demo/DemoApp.EFDataExample/RulesEngineContext.cs @@ -52,7 +52,6 @@ namespace RulesEngine.Data v => JsonSerializer.Deserialize(v, serializationOptions)); entity.Ignore(b => b.WorkflowsToInject); - entity.Ignore(b => b.WorkflowRulesToInject); }); } } diff --git a/global.json b/global.json index 50f074c..fc4a588 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0", + "version": "6.0.0", "rollForward": "latestFeature", "allowPrerelease": false } diff --git a/scripts/check-coverage.ps1 b/scripts/check-coverage.ps1 new file mode 100644 index 0000000..b4306ac --- /dev/null +++ b/scripts/check-coverage.ps1 @@ -0,0 +1,16 @@ +param( + [Parameter(Mandatory=$true)][string] $reportPath, + [Parameter(Mandatory=$true)][decimal] $threshold +) + + +[XML]$report = Get-Content $reportPath; +[decimal]$coverage = [decimal]$report.coverage.'line-rate' * 100; + +if ($coverage -lt $threshold) { + Write-Error "Coverage($coverage) is less than $threshold percent" + exit 1 +} +else{ + Write-Host "Coverage($coverage) is more than $threshold percent" +} diff --git a/scripts/generate-coverage-report.ps1 b/scripts/generate-coverage-report.ps1 new file mode 100644 index 0000000..8a14cad --- /dev/null +++ b/scripts/generate-coverage-report.ps1 @@ -0,0 +1,2 @@ +dotnet tool restore +dotnet reportgenerator "-reports:**/coverage.cobertura.xml" "-targetdir:coveragereport" -reporttypes:"Html;lcov;Cobertura" \ No newline at end of file diff --git a/src/RulesEngine/HelperFunctions/Helpers.cs b/src/RulesEngine/HelperFunctions/Helpers.cs index f96ff50..481ecc2 100644 --- a/src/RulesEngine/HelperFunctions/Helpers.cs +++ b/src/RulesEngine/HelperFunctions/Helpers.cs @@ -74,50 +74,5 @@ namespace RulesEngine.HelperFunctions { return reSettings.IgnoreException ? "" : message; } - - /// - /// To the result tree error messages - /// - /// ruleResultTree - /// ruleResultMessage - [Obsolete] - internal static void ToResultTreeMessages(RuleResultTree ruleResultTree, ref RuleResultMessage ruleResultMessage) - { - if (ruleResultTree.ChildResults != null) - { - GetChildRuleMessages(ruleResultTree.ChildResults, ref ruleResultMessage); - } - else - { - if (!ruleResultTree.IsSuccess) - { - string errMsg = ruleResultTree.Rule.ErrorMessage; - errMsg = string.IsNullOrEmpty(errMsg) ? $"Error message is not configured for {ruleResultTree.Rule.RuleName}" : errMsg; - - if (ruleResultTree.Rule.ErrorType == ErrorType.Error && !ruleResultMessage.ErrorMessages.Contains(errMsg)) - { - ruleResultMessage.ErrorMessages.Add(errMsg); - } - else if (ruleResultTree.Rule.ErrorType == ErrorType.Warning && !ruleResultMessage.WarningMessages.Contains(errMsg)) - { - ruleResultMessage.WarningMessages.Add(errMsg); - } - } - } - } - - /// - /// To get the child error message recursively - /// - /// childResultTree - /// ruleResultMessage - [Obsolete] - private static void GetChildRuleMessages(IEnumerable childResultTree, ref RuleResultMessage ruleResultMessage) - { - foreach (var item in childResultTree) - { - ToResultTreeMessages(item, ref ruleResultMessage); - } - } } } diff --git a/src/RulesEngine/Models/ReSettings.cs b/src/RulesEngine/Models/ReSettings.cs index 51aeedb..7b6d942 100644 --- a/src/RulesEngine/Models/ReSettings.cs +++ b/src/RulesEngine/Models/ReSettings.cs @@ -49,16 +49,6 @@ namespace RulesEngine.Models /// Sets the mode for Nested rule execution, Default: All /// public NestedRuleExecutionMode NestedRuleExecutionMode { get; set; } = NestedRuleExecutionMode.All; - - /// - /// Enables Local params for rules - /// - [Obsolete("Use 'EnableScopedParams' instead. This will be removed in next major version")] - public bool EnableLocalParams { - get { return EnableScopedParams; } - set { EnableScopedParams = value; } - } - public MemCacheConfig CacheConfig { get; set; } } diff --git a/src/RulesEngine/Models/Rule.cs b/src/RulesEngine/Models/Rule.cs index cf08052..13bf225 100644 --- a/src/RulesEngine/Models/Rule.cs +++ b/src/RulesEngine/Models/Rule.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -34,20 +33,9 @@ namespace RulesEngine.Models /// public bool Enabled { get; set; } = true; - [Obsolete("will be removed in next major version")] - [JsonConverter(typeof(StringEnumConverter))] - public ErrorType ErrorType { get; set; } = ErrorType.Warning; - [JsonConverter(typeof(StringEnumConverter))] public RuleExpressionType RuleExpressionType { get; set; } = RuleExpressionType.LambdaExpression; - - [Obsolete("WorkflowRulesToInject is deprecated. Use WorkflowsToInject instead.")] - public IEnumerable WorkflowRulesToInject { - get { return WorkflowsToInject; } - set { WorkflowsToInject = value; } - } public IEnumerable WorkflowsToInject { get; set; } - public IEnumerable Rules { get; set; } public IEnumerable LocalParams { get; set; } public string Expression { get; set; } diff --git a/src/RulesEngine/Models/RuleResultTree.cs b/src/RulesEngine/Models/RuleResultTree.cs index ecaffed..2089fdb 100644 --- a/src/RulesEngine/Models/RuleResultTree.cs +++ b/src/RulesEngine/Models/RuleResultTree.cs @@ -50,29 +50,6 @@ namespace RulesEngine.Models /// public string ExceptionMessage { get; set; } - /// - /// Gets or sets the rule evaluated parameters. - /// - /// - /// The rule evaluated parameters. - /// - [Obsolete("Use `Inputs` field to get details of all input, localParams and globalParams")] - public IEnumerable RuleEvaluatedParams { get; set; } - - /// - /// This method will return all the error and warning messages to caller - /// - /// RuleResultMessage - [ExcludeFromCodeCoverage] - [Obsolete("will be removed in next major version")] - public RuleResultMessage GetMessages() - { - var ruleResultMessage = new RuleResultMessage(); - - Helpers.ToResultTreeMessages(this, ref ruleResultMessage); - - return ruleResultMessage; - } } /// diff --git a/src/RulesEngine/RuleCompiler.cs b/src/RulesEngine/RuleCompiler.cs index 41e40e2..2c3f33a 100644 --- a/src/RulesEngine/RuleCompiler.cs +++ b/src/RulesEngine/RuleCompiler.cs @@ -252,14 +252,6 @@ namespace RulesEngine var extendedInputs = ruleParams.Concat(scopedParams); var result = ruleFunc(extendedInputs.ToArray()); - // To be removed in next major release -#pragma warning disable CS0618 // Type or member is obsolete - if(result.RuleEvaluatedParams == null) - { - result.RuleEvaluatedParams = scopedParams; - } -#pragma warning restore CS0618 // Type or member is obsolete - return result; }; } diff --git a/src/RulesEngine/RulesEngine.cs b/src/RulesEngine/RulesEngine.cs index 6a44b56..1a7d62e 100644 --- a/src/RulesEngine/RulesEngine.cs +++ b/src/RulesEngine/RulesEngine.cs @@ -345,8 +345,8 @@ namespace RulesEngine private string GetCompiledRulesKey(string workflowName, RuleParameter[] ruleParams) { - var ruleParamsHash = string.Join("-", ruleParams.Select(c => $"{c.Name}_{c.Type.Name}")).GetHashCode(); - var key = $"{workflowName}-" + ruleParamsHash; + var ruleParamsKey = string.Join("-", ruleParams.Select(c => $"{c.Name}_{c.Type.Name}")); + var key = $"{workflowName}-" + ruleParamsKey; return key; } diff --git a/src/RulesEngine/RulesEngine.csproj b/src/RulesEngine/RulesEngine.csproj index 67efee5..6140d51 100644 --- a/src/RulesEngine/RulesEngine.csproj +++ b/src/RulesEngine/RulesEngine.csproj @@ -1,8 +1,8 @@ - netstandard2.0 - 4.0.0-preview.1 + net6.0;netstandard2.0 + 4.0.0 Copyright (c) Microsoft Corporation. LICENSE https://github.com/microsoft/RulesEngine @@ -31,8 +31,8 @@ - - + + diff --git a/test/RulesEngine.UnitTest/BusinessRuleEngineTest.cs b/test/RulesEngine.UnitTest/BusinessRuleEngineTest.cs index a4a6afb..48203dc 100644 --- a/test/RulesEngine.UnitTest/BusinessRuleEngineTest.cs +++ b/test/RulesEngine.UnitTest/BusinessRuleEngineTest.cs @@ -238,22 +238,6 @@ namespace RulesEngine.UnitTest Assert.False(string.IsNullOrEmpty(result[0].ExceptionMessage) || string.IsNullOrWhiteSpace(result[0].ExceptionMessage)); } - [Theory] - [InlineData("rules2.json")] - [Obsolete] - public async Task ExecuteRule_ReturnsListOfRuleResultTree_ResultMessage(string ruleFileName) - { - var re = GetRulesEngine(ruleFileName); - - dynamic input1 = GetInput1(); - dynamic input2 = GetInput2(); - dynamic input3 = GetInput3(); - - List result = await re.ExecuteAllRulesAsync("inputWorkflow", input1, input2, input3); - Assert.NotNull(result); - Assert.NotNull(result.First().GetMessages()); - Assert.NotNull(result.First().GetMessages().WarningMessages); - } [Fact] public void RulesEngine_New_IncorrectJSON_ThrowsException() diff --git a/test/RulesEngine.UnitTest/RulesEngine.UnitTest.csproj b/test/RulesEngine.UnitTest/RulesEngine.UnitTest.csproj index 22afccb..0640f59 100644 --- a/test/RulesEngine.UnitTest/RulesEngine.UnitTest.csproj +++ b/test/RulesEngine.UnitTest/RulesEngine.UnitTest.csproj @@ -1,4 +1,4 @@ - + net6.0 True @@ -7,10 +7,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/RulesEngine.UnitTest/ScopedParamsTest.cs b/test/RulesEngine.UnitTest/ScopedParamsTest.cs index f3900e7..5979f2b 100644 --- a/test/RulesEngine.UnitTest/ScopedParamsTest.cs +++ b/test/RulesEngine.UnitTest/ScopedParamsTest.cs @@ -162,10 +162,6 @@ namespace RulesEngine.UnitTest var localParamNames = resultTree.Rule.LocalParams?.Select(c => c.Name) ?? new List(); Assert.All(localParamNames, input => Assert.True(resultTree.Inputs.ContainsKey(input))); -#pragma warning disable CS0618 // Type or member is obsolete - Assert.All(localParamNames, lp => Assert.Contains(resultTree.RuleEvaluatedParams, c => c.Name == lp)); -#pragma warning restore CS0618 // Type or member is obsolete - if (resultTree.ChildResults?.Any() == true) { foreach (var childResultTree in resultTree.ChildResults)