[![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet/)
+ [![MyGet](https://img.shields.io/myget/benchmarkdotnet/vpre/benchmarkdotnet?label=myget)](https://www.myget.org/feed/Packages/benchmarkdotnet)
[![Downloads](https://img.shields.io/nuget/dt/benchmarkdotnet.svg)](https://www.nuget.org/packages/BenchmarkDotNet/)
[![Stars](https://img.shields.io/github/stars/dotnet/BenchmarkDotNet?color=brightgreen)](https://github.com/dotnet/BenchmarkDotNet/stargazers)
![License](https://img.shields.io/badge/license-MIT-blue.svg)
From e85fe2874f67153de3af018ad1bf7602f9123d68 Mon Sep 17 00:00:00 2001
From: Tim Cassell <35501420+timcassell@users.noreply.github.com>
Date: Mon, 10 Jul 2023 03:45:28 -0400
Subject: [PATCH 59/73] Fix netcoreapp3.0 builds (#2359)
* Fix netcoreapp3.0 builds for real
* Use same nuget package versions for all targets.
* Add comment
* Fix tests.
---
src/BenchmarkDotNet/BenchmarkDotNet.csproj | 9 +++------
...hmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj | 2 +-
.../BenchmarkDotNet.IntegrationTests.CustomPaths.csproj | 2 +-
...kDotNet.IntegrationTests.DisabledOptimizations.csproj | 2 +-
...rkDotNet.IntegrationTests.EnabledOptimizations.csproj | 2 +-
.../BenchmarkDotNet.IntegrationTests.Static.csproj | 2 +-
.../BenchmarkDotNet.IntegrationTests.csproj | 2 +-
tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj | 2 +-
8 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/src/BenchmarkDotNet/BenchmarkDotNet.csproj b/src/BenchmarkDotNet/BenchmarkDotNet.csproj
index 09d920b3ce..58a33c64f9 100644
--- a/src/BenchmarkDotNet/BenchmarkDotNet.csproj
+++ b/src/BenchmarkDotNet/BenchmarkDotNet.csproj
@@ -24,6 +24,9 @@
+
+
+
@@ -31,12 +34,6 @@
-
-
-
-
-
-
diff --git a/tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj b/tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj
index e559ace0a9..70ca871259 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj
@@ -14,7 +14,7 @@
-
+
\ No newline at end of file
diff --git a/tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj b/tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj
index 95eb54181b..cb4df7361e 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj b/tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj
index 15723e07e5..aad9d6ac33 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj
@@ -16,7 +16,7 @@
-
+
\ No newline at end of file
diff --git a/tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj b/tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj
index 593dbbae16..da7558c82e 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj
@@ -16,7 +16,7 @@
-
+
\ No newline at end of file
diff --git a/tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj b/tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj
index 8ff856ecb5..4a52743deb 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj
@@ -14,7 +14,7 @@
-
+
\ No newline at end of file
diff --git a/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj b/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
index 5bc42e3dff..5d70626536 100644
--- a/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj
@@ -46,7 +46,7 @@
-
+
diff --git a/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj b/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
index eda55784ad..02e5169197 100755
--- a/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
+++ b/tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
@@ -25,7 +25,7 @@
-
+
From c9347c9b319852e9e608182024f14583bc96ba60 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Tue, 11 Jul 2023 14:34:24 +0400
Subject: [PATCH 60/73] Set next BenchmarkDotNet version: 0.13.7
---
build/common.props | 2 +-
build/versions.txt | 3 ++-
docs/_changelog/footer/v0.13.6.md | 2 +-
.../.template.config/template.json | 2 +-
.../.template.config/template.json | 2 +-
.../.template.config/template.json | 2 +-
6 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/build/common.props b/build/common.props
index f88bc9435e..7037f3bed9 100644
--- a/build/common.props
+++ b/build/common.props
@@ -37,7 +37,7 @@
- 0.13.6
+ 0.13.7
diff --git a/build/versions.txt b/build/versions.txt
index 70df4068ca..12a1f57f12 100644
--- a/build/versions.txt
+++ b/build/versions.txt
@@ -50,4 +50,5 @@
0.13.3
0.13.4
0.13.5
-0.13.6
\ No newline at end of file
+0.13.6
+0.13.7
\ No newline at end of file
diff --git a/docs/_changelog/footer/v0.13.6.md b/docs/_changelog/footer/v0.13.6.md
index f78501ac1d..7235cd2302 100644
--- a/docs/_changelog/footer/v0.13.6.md
+++ b/docs/_changelog/footer/v0.13.6.md
@@ -1,4 +1,4 @@
-_Date: TBA_
+_Date: July 11, 2023_
_Milestone: [v0.13.6](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone%3Av0.13.6)_
([List of commits](https://github.com/dotnet/BenchmarkDotNet/compare/v0.13.5...v0.13.6))
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
index 3e6fd1107c..b4051ccbf4 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.6",
+ "defaultValue": "0.13.7",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
index aeb5503a79..20d49ec024 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.6",
+ "defaultValue": "0.13.7",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
index 72d361290a..1fe705443d 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.6",
+ "defaultValue": "0.13.7",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
From df4cedd86c1135b7a8fdcf25125f7c683bd9cd74 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Tue, 11 Jul 2023 14:46:01 +0400
Subject: [PATCH 61/73] Fix generate-gh-pages.yaml
---
.github/workflows/generate-gh-pages.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/generate-gh-pages.yaml b/.github/workflows/generate-gh-pages.yaml
index a0f6218d4e..41bc3f9b59 100644
--- a/.github/workflows/generate-gh-pages.yaml
+++ b/.github/workflows/generate-gh-pages.yaml
@@ -39,7 +39,7 @@ jobs:
deploy:
concurrency: ci-${{ github.ref }}
- needs: [build]
+ needs: [generate]
runs-on: ubuntu-latest
steps:
From 142a89e11d17add923501368d9f46e514f8e0ade Mon Sep 17 00:00:00 2001
From: Ankit Jain
Date: Tue, 11 Jul 2023 02:25:34 -0400
Subject: [PATCH 62/73] DotNetCliCommand.cs: Fail the build if no-dependencies
retry build fails
Issue: https://github.com/dotnet/BenchmarkDotNet/issues/2311
---
src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs
index 77401f022e..31546d3112 100644
--- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs
+++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs
@@ -90,6 +90,9 @@ public BuildResult RestoreThenBuild()
buildResult = BuildNoRestoreNoDependencies();
}
+ if (!buildResult.IsSuccess)
+ return BuildResult.Failure(GenerateResult, buildResult.AllInformation);
+
return buildResult.ToBuildResult(GenerateResult);
}
From c0311bf687c754ef828928771e205e125ab54db5 Mon Sep 17 00:00:00 2001
From: Ankit Jain
Date: Tue, 11 Jul 2023 20:50:36 -0400
Subject: [PATCH 63/73] MonoAOTLLVMCsProj.txt: Add auto-imports for extension
props/targets
Automatically import any `$projectName.Mono.props`, and
`$projectName.Mono.targets` files, if found.
- This allows the actual project to control settings for the generated
project, eg, for modifying the build to add a property like
`SelfContained=true`.
Wasm projects have the same extension mechanism in
`src/BenchmarkDotNet/Templates/WasmCsProj.txt` .
---
src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
index a0ad858c54..3f28937a3f 100644
--- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
@@ -1,5 +1,8 @@
+ $CSPROJPATH$
+ $([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.props'))
+ $([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.targets'))
Exe
bin
$TFM$
@@ -13,6 +16,8 @@
BenchmarkDotNet.Autogenerated.UniqueProgramName
+
+
@@ -75,4 +80,5 @@
+
From f42b9757dd6af5db562cd4ca250558ab0001213d Mon Sep 17 00:00:00 2001
From: Ankit Jain
Date: Wed, 12 Jul 2023 08:01:17 -0400
Subject: [PATCH 64/73] MonoAOTLLVMCsProj.txt: Imports the props file early
enough to allow
.. setting properties early.
---
src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
index 3f28937a3f..7c658970bd 100644
--- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
@@ -3,6 +3,11 @@
$CSPROJPATH$
$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.props'))
$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.targets'))
+
+
+
+
+
Exe
bin
$TFM$
@@ -16,8 +21,6 @@
BenchmarkDotNet.Autogenerated.UniqueProgramName
-
-
From f6bc29bfc75b49387098ddd77ff5aeb096d6fdc2 Mon Sep 17 00:00:00 2001
From: Ankit Jain
Date: Wed, 12 Jul 2023 08:02:11 -0400
Subject: [PATCH 65/73] MonoAOTLLVMCsProj.txt: Add SelfContained=true
---
src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
index 7c658970bd..1db40072d1 100644
--- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
@@ -19,6 +19,7 @@
false
true
BenchmarkDotNet.Autogenerated.UniqueProgramName
+ true
From e4c4f6f4a189e964f8dad4b92573662104355d32 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 11:59:25 +0400
Subject: [PATCH 66/73] [build] Specify NuGet source to PushNupkg
---
build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
index 44a2377d0b..10873340ef 100644
--- a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
@@ -119,7 +119,8 @@ private void PushNupkg()
var settings = new DotNetNuGetPushSettings
{
ApiKey = nuGetToken,
- SymbolApiKey = nuGetToken
+ SymbolApiKey = nuGetToken,
+ Source = "https://api.nuget.org/v3/index.json"
};
foreach (var file in files)
From 7de12a1d3ee2b37351465ff2175d03d2898f045e Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 16:01:38 +0400
Subject: [PATCH 67/73] [build] rework command line argument parsing
---
.github/workflows/generate-changelog.yaml | 3 +-
.github/workflows/generate-gh-pages.yaml | 3 +-
build/BenchmarkDotNet.Build/BuildContext.cs | 12 +-
.../BenchmarkDotNet.Build/ChangeLogBuilder.cs | 11 +-
.../CommandLineParser.cs | 157 +++++++++---------
build/BenchmarkDotNet.Build/HelpInfo.cs | 5 +-
.../Options/BoolOption.cs | 20 +++
.../BenchmarkDotNet.Build/Options/IOption.cs | 8 +
.../Options/KnownOptions.cs | 37 +++++
build/BenchmarkDotNet.Build/Options/Option.cs | 40 +++++
.../Options/StringOption.cs | 19 +++
build/BenchmarkDotNet.Build/Program.cs | 24 ++-
.../Runners/DocumentationRunner.cs | 50 ++++--
.../.template.config/template.json | 2 +-
.../.template.config/template.json | 2 +-
.../.template.config/template.json | 2 +-
16 files changed, 277 insertions(+), 118 deletions(-)
create mode 100644 build/BenchmarkDotNet.Build/Options/BoolOption.cs
create mode 100644 build/BenchmarkDotNet.Build/Options/IOption.cs
create mode 100644 build/BenchmarkDotNet.Build/Options/KnownOptions.cs
create mode 100644 build/BenchmarkDotNet.Build/Options/Option.cs
create mode 100644 build/BenchmarkDotNet.Build/Options/StringOption.cs
diff --git a/.github/workflows/generate-changelog.yaml b/.github/workflows/generate-changelog.yaml
index 9589b92fc8..54dd5c2250 100644
--- a/.github/workflows/generate-changelog.yaml
+++ b/.github/workflows/generate-changelog.yaml
@@ -20,9 +20,8 @@ jobs:
ref: master
- name: Download changelog
- run: ./build.cmd DocsUpdate /p:Depth=1
+ run: ./build.cmd DocsUpdate --depth 1 --preview
env:
- GITHUB_PRODUCT: ChangelogBuilder
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Push changelog
diff --git a/.github/workflows/generate-gh-pages.yaml b/.github/workflows/generate-gh-pages.yaml
index 41bc3f9b59..868fa49c5c 100644
--- a/.github/workflows/generate-gh-pages.yaml
+++ b/.github/workflows/generate-gh-pages.yaml
@@ -23,9 +23,8 @@ jobs:
run: ./build.cmd Build
- name: Download changelog
- run: ./build.cmd DocsUpdate /p:Depth=1
+ run: ./build.cmd DocsUpdate --depth 1 --preview
env:
- GITHUB_PRODUCT: ChangelogBuilder
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build documentation
diff --git a/build/BenchmarkDotNet.Build/BuildContext.cs b/build/BenchmarkDotNet.Build/BuildContext.cs
index d7b12205f9..d20e5891e7 100644
--- a/build/BenchmarkDotNet.Build/BuildContext.cs
+++ b/build/BenchmarkDotNet.Build/BuildContext.cs
@@ -16,7 +16,6 @@
using Cake.Core.IO;
using Cake.FileHelpers;
using Cake.Frosting;
-using Cake.Git;
namespace BenchmarkDotNet.Build;
@@ -24,7 +23,6 @@ public class BuildContext : FrostingContext
{
public string BuildConfiguration { get; set; } = "Release";
public DotNetVerbosity BuildVerbosity { get; set; } = DotNetVerbosity.Minimal;
- public int Depth { get; set; }
public bool VersionStable { get; }
public string NextVersion { get; }
public bool PushMode { get; }
@@ -85,7 +83,6 @@ public BuildContext(ICakeContext context)
MsBuildSettingsBuild.WithProperty("UseSharedCompilation", "false");
}
- Depth = -1;
VersionStable = false;
NextVersion = "";
PushMode = false;
@@ -113,9 +110,6 @@ public BuildContext(ICakeContext context)
BuildVerbosity = parsedVerbosity.Value;
}
- if (name.Equals("depth", StringComparison.OrdinalIgnoreCase))
- Depth = int.Parse(value);
-
if (name.Equals("VersionStable", StringComparison.OrdinalIgnoreCase) && value != "")
VersionStable = true;
@@ -160,14 +154,18 @@ public void GenerateFile(FilePath filePath, StringBuilder content)
GenerateFile(filePath, content.ToString());
}
- public void GenerateFile(FilePath filePath, string content)
+ public void GenerateFile(FilePath filePath, string content, bool reportNoChanges = false)
{
var relativePath = RootDirectory.GetRelativePath(filePath);
if (this.FileExists(filePath))
{
var oldContent = this.FileReadText(filePath);
if (content == oldContent)
+ {
+ if (reportNoChanges)
+ this.Information("[NoChanges] " + relativePath);
return;
+ }
this.FileWriteText(filePath, content);
this.Information("[Updated] " + relativePath);
diff --git a/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs b/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
index 046c5fc728..a7537c51c6 100644
--- a/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
+++ b/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
-using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Build.Helpers;
using BenchmarkDotNet.Build.Meta;
+using Cake.Common.Diagnostics;
using Cake.Core.IO;
using Octokit;
@@ -174,17 +174,18 @@ private void AppendList(string title, IReadOnlyList items, Func
}
}
- public static async Task Run(DirectoryPath path, string currentVersion, string previousVersion, string lastCommit)
+ public static void Run(BuildContext context, DirectoryPath path,
+ string currentVersion, string previousVersion, string lastCommit)
{
try
{
var config = new Config(currentVersion, previousVersion, lastCommit);
- var releaseNotes = await MarkdownBuilder.Build(config);
- await File.WriteAllTextAsync(path.Combine($"v{config.CurrentVersion}.md").FullPath, releaseNotes);
+ var releaseNotes = MarkdownBuilder.Build(config).Result;
+ context.GenerateFile(path.Combine($"v{config.CurrentVersion}.md").FullPath, releaseNotes, true);
}
catch (Exception e)
{
- await Console.Error.WriteLineAsync(e.ToString());
+ context.Error(e.ToString());
}
}
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/CommandLineParser.cs b/build/BenchmarkDotNet.Build/CommandLineParser.cs
index 95dc065875..5e797e6375 100644
--- a/build/BenchmarkDotNet.Build/CommandLineParser.cs
+++ b/build/BenchmarkDotNet.Build/CommandLineParser.cs
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Runtime.InteropServices;
+using BenchmarkDotNet.Build.Options;
using Cake.Frosting;
namespace BenchmarkDotNet.Build;
@@ -10,6 +12,9 @@ public class CommandLineParser
{
private const string ScriptName = "build.cmd";
+ private static readonly string CallScriptName =
+ (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? ScriptName : "./" + ScriptName;
+
public static readonly CommandLineParser Instance = new();
public string[]? Parse(string[]? args)
@@ -53,63 +58,32 @@ public class CommandLineParser
{
var arg = argsToProcess.Dequeue();
- var matched = false;
- foreach (var option in options)
- {
- if (Is(arg, option.ShortName, option.FullName))
- {
- matched = true;
- cakeArgs.Add(option.CakeOption);
- if (option.Arg != "")
- {
- if (!argsToProcess.Any())
- {
- PrintError(option.FullName + " is not specified");
- return null;
- }
-
- cakeArgs.Add(argsToProcess.Dequeue());
- }
- }
- }
-
if (arg.StartsWith("/p:"))
{
- matched = true;
cakeArgs.Add("--msbuild");
cakeArgs.Add(arg[3..]);
+ continue;
}
- if (!matched)
+ if (arg.StartsWith('-'))
{
- PrintError("Unknown option: " + arg);
- return null;
+ cakeArgs.Add(arg);
+ if (argsToProcess.Any() && !argsToProcess.Peek().StartsWith('-'))
+ cakeArgs.Add(argsToProcess.Dequeue());
+ continue;
}
+
+ PrintError("Unknown option: " + arg);
+ return null;
}
return cakeArgs.ToArray();
}
- private record Option(string ShortName, string FullName, string Arg, string Description, string CakeOption);
-
- private readonly Option[] options =
+ private readonly IOption[] baseOptions =
{
- new("-v",
- "--verbosity",
- "",
- "Specifies the amount of information to be displayed\n(Quiet, Minimal, Normal, Verbose, Diagnostic)",
- "--verbosity"),
- new("-e",
- "--exclusive",
- "",
- "Executes the target task without any dependencies",
- "--exclusive"),
- new("-h",
- "--help",
- "",
- "Prints help information for the target task",
- "")
+ KnownOptions.Verbosity, KnownOptions.Exclusive, KnownOptions.Help
};
private void PrintHelp()
@@ -127,7 +101,7 @@ private void PrintHelp()
WriteHeader("Usage:");
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask(" ");
WriteOption("[OPTIONS]");
WriteLine();
@@ -137,12 +111,12 @@ private void PrintHelp()
WriteHeader("Examples:");
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask("restore");
WriteLine();
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask("build ");
WriteOption("/p:");
WriteArg("Configuration");
@@ -151,7 +125,7 @@ private void PrintHelp()
WriteLine();
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask("pack ");
WriteOption("/p:");
WriteArg("VersionPrefix");
@@ -164,27 +138,29 @@ private void PrintHelp()
WriteLine();
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask("unittests ");
WriteOption("--exclusive --verbosity ");
WriteArg("Diagnostic");
WriteLine();
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask("docs-update ");
- WriteOption("/p:");
- WriteArg("Depth");
- WriteOption("=");
+ WriteOption("--depth ");
WriteArg("3");
WriteLine();
+ WritePrefix();
+ Write(CallScriptName + " ");
+ WriteTask("docs-build ");
+ WriteOption("--preview ");
WriteLine();
- PrintCommonOptions();
-
WriteLine();
+ PrintOptions(baseOptions);
+
WriteHeader("Tasks:");
var taskWidth = GetTaskNames().Max(name => name.Length) + 3;
foreach (var (taskName, taskDescription) in GetTasks())
@@ -207,29 +183,47 @@ private void PrintHelp()
}
}
- private void PrintCommonOptions()
+ private void PrintOptions(IOption[] options)
{
+ const string valuePlaceholder = "";
+
WriteLine("Options:", ConsoleColor.DarkCyan);
- var shortNameWidth = options.Max(it => it.ShortName.Length);
- var targetWidth = options.Max(it => it.FullName.Length + it.Arg.Length);
+ int GetWidth(IOption option)
+ {
+ int width = option.CommandLineName.Length;
+ foreach (var alias in option.Aliases)
+ width += 1 + alias.Length;
+ if (option is StringOption)
+ width += 1 + valuePlaceholder.Length;
+ return width;
+ }
- foreach (var (shortName, fullName, arg, description, _) in options)
+ const int descriptionGap = 3;
+ var maxWidth = options.Max(GetWidth) + descriptionGap;
+
+ foreach (var option in options)
{
+ var allNames = option.Aliases.Append(option.CommandLineName).OrderBy(name => name.Length);
+ var joinName = string.Join(',', allNames);
+
WritePrefix();
- WriteOption(shortName.PadRight(shortNameWidth));
- WriteOption(shortName != "" ? "," : " ");
- WriteOption(fullName);
- Write(" ");
- WriteArg(arg);
- Write(new string(' ', targetWidth - fullName.Length - arg.Length + 3));
- var descriptionLines = description.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
+ WriteOption(joinName);
+ if (option is StringOption)
+ {
+ Write(" ");
+ WriteArg(valuePlaceholder);
+ }
+
+ Write(new string(' ',
+ maxWidth - joinName.Length - (option is StringOption ? valuePlaceholder.Length + 1 : 0)));
+ var descriptionLines = option.Description.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
Write(descriptionLines.FirstOrDefault() ?? "");
for (int i = 1; i < descriptionLines.Length; i++)
{
WriteLine();
WritePrefix();
- Write(new string(' ', shortNameWidth + 2 + targetWidth + 3));
+ Write(new string(' ', maxWidth));
Write(descriptionLines[i]);
}
@@ -240,10 +234,12 @@ private void PrintCommonOptions()
WriteOption("/p:");
WriteArg("");
WriteOption("=");
- WriteArg("");
- Write(new string(' ', targetWidth + shortNameWidth - 11));
+ WriteArg(valuePlaceholder);
+ Write(new string(' ', maxWidth - "/p:=".Length - valuePlaceholder.Length));
Write("Passes custom properties to MSBuild");
WriteLine();
+
+ WriteLine();
}
private void PrintTaskHelp(string taskName)
@@ -267,18 +263,19 @@ private void PrintTaskHelp(string taskName)
WriteLine(taskDescription);
}
- foreach (var line in helpInfo.Description)
- {
- WritePrefix();
- WriteLine(line);
- }
+ if (string.IsNullOrWhiteSpace(helpInfo.Description))
+ foreach (var line in helpInfo.Description.Split('\n', StringSplitOptions.RemoveEmptyEntries))
+ {
+ WritePrefix();
+ WriteLine(line.Trim());
+ }
WriteLine();
WriteHeader("Usage:");
WritePrefix();
- Write(ScriptName + " ");
+ Write(CallScriptName + " ");
WriteTask(taskName + " ");
WriteOption("[OPTIONS]");
WriteLine();
@@ -309,7 +306,19 @@ private void PrintTaskHelp(string taskName)
WriteLine();
- PrintCommonOptions();
+ PrintOptions(helpInfo.Options.Concat(baseOptions).ToArray());
+
+ if (helpInfo.EnvironmentVariables.Any())
+ {
+ WriteHeader("Environment variables:");
+ foreach (var variable in helpInfo.EnvironmentVariables)
+ {
+ WritePrefix();
+ WriteOption(variable);
+ }
+
+ WriteLine();
+ }
}
private static HashSet GetTaskNames()
diff --git a/build/BenchmarkDotNet.Build/HelpInfo.cs b/build/BenchmarkDotNet.Build/HelpInfo.cs
index 8f93af63f9..868299677b 100644
--- a/build/BenchmarkDotNet.Build/HelpInfo.cs
+++ b/build/BenchmarkDotNet.Build/HelpInfo.cs
@@ -1,8 +1,11 @@
using System;
+using BenchmarkDotNet.Build.Options;
namespace BenchmarkDotNet.Build;
public class HelpInfo
{
- public string[] Description { get; init; } = Array.Empty();
+ public string Description { get; init; } = "";
+ public IOption[] Options { get; init; } = Array.Empty();
+ public string[] EnvironmentVariables { get; init; } = Array.Empty();
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/BoolOption.cs b/build/BenchmarkDotNet.Build/Options/BoolOption.cs
new file mode 100644
index 0000000000..5a437d8095
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Options/BoolOption.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace BenchmarkDotNet.Build.Options;
+
+public class BoolOption : Option
+{
+ public BoolOption(string commandLineName) : base(commandLineName)
+ {
+ }
+
+ public override bool Resolve(BuildContext context)
+ {
+ if (!HasArgument(context))
+ return false;
+ var value = GetArgument(context);
+ if (value == null)
+ return true;
+ return !value.Equals(false.ToString(), StringComparison.OrdinalIgnoreCase);
+ }
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/IOption.cs b/build/BenchmarkDotNet.Build/Options/IOption.cs
new file mode 100644
index 0000000000..0a2046816e
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Options/IOption.cs
@@ -0,0 +1,8 @@
+namespace BenchmarkDotNet.Build.Options;
+
+public interface IOption
+{
+ string CommandLineName { get; }
+ string Description { get; }
+ string[] Aliases { get; }
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/KnownOptions.cs b/build/BenchmarkDotNet.Build/Options/KnownOptions.cs
new file mode 100644
index 0000000000..19467c09c3
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Options/KnownOptions.cs
@@ -0,0 +1,37 @@
+namespace BenchmarkDotNet.Build.Options;
+
+public static class KnownOptions
+{
+ public static readonly StringOption Verbosity = new("--verbosity"
+ )
+ {
+ Description = "Specifies the amount of information to be displayed\n" +
+ "(Quiet, Minimal, Normal, Verbose, Diagnostic)",
+ Aliases = new[] { "-v" }
+ };
+
+ public static readonly BoolOption Exclusive = new("--exclusive")
+ {
+ Description = "Executes the target task without any dependencies",
+ Aliases = new[] { "-e" }
+ };
+
+ public static readonly BoolOption DocsPreview = new("--preview")
+ {
+ Description = "When specified, documentation changelog includes the upcoming version",
+ Aliases = new[] { "-p" }
+ };
+
+ public static readonly StringOption DocsDepth = new("--depth")
+ {
+ Description = "The number of last stable versions that requires changelog regenerations\n" +
+ "Use 'all' for all values. The default is zero.",
+ Aliases = new[] { "-d" }
+ };
+
+ public static readonly BoolOption Help = new("--help")
+ {
+ Description = "Prints help information",
+ Aliases = new[] { "-h" }
+ };
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/Option.cs b/build/BenchmarkDotNet.Build/Options/Option.cs
new file mode 100644
index 0000000000..4840af7ad2
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Options/Option.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Cake.Common;
+using Cake.Core;
+
+namespace BenchmarkDotNet.Build.Options;
+
+public abstract class Option : IOption
+{
+ public string CommandLineName { get; }
+ public string Description { get; init; } = "";
+ public string[] Aliases { get; init; } = Array.Empty();
+
+ private IEnumerable AllNames
+ {
+ get
+ {
+ yield return CommandLineName;
+ foreach (var alias in Aliases)
+ yield return alias;
+ }
+ }
+
+ private IEnumerable AllStrippedNames => AllNames.Select(name => name.TrimStart('-'));
+
+ protected Option(string commandLineName)
+ {
+ CommandLineName = commandLineName;
+ }
+
+ public abstract T Resolve(BuildContext context);
+
+ protected bool HasArgument(BuildContext context) => AllStrippedNames.Any(context.HasArgument);
+
+ protected string? GetArgument(BuildContext context) => AllStrippedNames
+ .Where(context.HasArgument)
+ .Select(name => context.Arguments.GetArgument(name))
+ .FirstOrDefault();
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/StringOption.cs b/build/BenchmarkDotNet.Build/Options/StringOption.cs
new file mode 100644
index 0000000000..66a3bc375b
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Options/StringOption.cs
@@ -0,0 +1,19 @@
+namespace BenchmarkDotNet.Build.Options;
+
+public class StringOption : Option
+{
+ public StringOption(string commandLineName) : base(commandLineName)
+ {
+ }
+
+
+ public override string Resolve(BuildContext context)
+ {
+ if (!HasArgument(context))
+ return "";
+ var value = GetArgument(context);
+ if (value == null || string.IsNullOrWhiteSpace(value))
+ return "";
+ return value.Trim();
+ }
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Program.cs b/build/BenchmarkDotNet.Build/Program.cs
index 42cc824d1a..2717e9b20a 100644
--- a/build/BenchmarkDotNet.Build/Program.cs
+++ b/build/BenchmarkDotNet.Build/Program.cs
@@ -1,4 +1,5 @@
using BenchmarkDotNet.Build.Meta;
+using BenchmarkDotNet.Build.Options;
using Cake.Common;
using Cake.Frosting;
@@ -92,19 +93,25 @@ public HelpInfo GetHelp()
{
return new HelpInfo
{
- Description = new[]
- {
- $"Requires environment variable '{GitHubCredentials.TokenVariableName}'"
- }
+ Options = new IOption[] { KnownOptions.DocsPreview, KnownOptions.DocsDepth },
+ EnvironmentVariables = new[] { GitHubCredentials.TokenVariableName }
};
}
}
[TaskName("DocsPrepare")]
[TaskDescription("Prepare auxiliary documentation files")]
-public class DocsPrepareTask : FrostingTask
+public class DocsPrepareTask : FrostingTask, IHelpProvider
{
public override void Run(BuildContext context) => context.DocumentationRunner.Prepare();
+
+ public HelpInfo GetHelp()
+ {
+ return new HelpInfo
+ {
+ Options = new IOption[] { KnownOptions.DocsPreview }
+ };
+ }
}
// In order to work around xref issues in DocFx, BenchmarkDotNet and BenchmarkDotNet.Annotations must be build
@@ -114,9 +121,14 @@ public class DocsPrepareTask : FrostingTask
[TaskName("DocsBuild")]
[TaskDescription("Build final documentation")]
[IsDependentOn(typeof(DocsPrepareTask))]
-public class DocsBuildTask : FrostingTask
+public class DocsBuildTask : FrostingTask, IHelpProvider
{
public override void Run(BuildContext context) => context.DocumentationRunner.Build();
+
+ public HelpInfo GetHelp() => new()
+ {
+ Options = new IOption[] { KnownOptions.DocsPreview }
+ };
}
[TaskName("Release")]
diff --git a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
index a7cf31b1bd..7b59d223fc 100644
--- a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Text;
using BenchmarkDotNet.Build.Meta;
+using BenchmarkDotNet.Build.Options;
using Cake.Common.Diagnostics;
using Cake.Common.IO;
using Cake.Core.IO;
@@ -14,6 +15,8 @@ namespace BenchmarkDotNet.Build.Runners;
public class DocumentationRunner
{
private readonly BuildContext context;
+ private readonly bool preview;
+ private readonly string depth;
public DirectoryPath ChangelogDirectory { get; }
public DirectoryPath ChangelogSrcDirectory { get; }
@@ -32,6 +35,8 @@ public class DocumentationRunner
public DocumentationRunner(BuildContext context)
{
this.context = context;
+ preview = KnownOptions.DocsPreview.Resolve(context);
+ depth = KnownOptions.DocsDepth.Resolve(context);
var docsDirectory = context.RootDirectory.Combine("docs");
ChangelogDirectory = docsDirectory.Combine("changelog");
@@ -61,39 +66,43 @@ public void Update()
throw new Exception($"Environment variable '{GitHubCredentials.TokenVariableName}' is not specified!");
var history = context.VersionHistory;
- var depth = context.Depth;
var stableVersionCount = history.StableVersions.Length;
- if (depth == 0)
+ if (depth.Equals("all", StringComparison.OrdinalIgnoreCase))
{
DocfxChangelogDownload(
history.StableVersions.First(),
history.FirstCommit);
- for (int i = 1; i < stableVersionCount; i++)
+ for (var i = 1; i < stableVersionCount; i++)
DocfxChangelogDownload(
history.StableVersions[i],
history.StableVersions[i - 1]);
}
- else if (depth > 0)
+ else if (depth != "")
{
- for (int i = Math.Max(stableVersionCount - depth, 1); i < stableVersionCount; i++)
+ if (!int.TryParse(depth, CultureInfo.InvariantCulture, out var depthValue))
+ throw new InvalidDataException($"Failed to parse the depth value: '{depth}'");
+
+ for (var i = Math.Max(stableVersionCount - depthValue, 1); i < stableVersionCount; i++)
DocfxChangelogDownload(
history.StableVersions[i],
history.StableVersions[i - 1]);
}
- DocfxChangelogDownload(
- history.CurrentVersion,
- history.StableVersions.Last(),
- "HEAD");
+ if (preview)
+ DocfxChangelogDownload(
+ history.CurrentVersion,
+ history.StableVersions.Last(),
+ "HEAD");
}
public void Prepare()
{
foreach (var version in context.VersionHistory.StableVersions)
DocfxChangelogGenerate(version);
- DocfxChangelogGenerate(context.VersionHistory.CurrentVersion);
+ if (preview)
+ DocfxChangelogGenerate(context.VersionHistory.CurrentVersion);
GenerateIndexMd();
GenerateChangelogIndex();
@@ -133,9 +142,12 @@ private void GenerateChangelogToc()
{
var content = new StringBuilder();
- content.AppendLine($"- name: v{context.VersionHistory.CurrentVersion}");
- content.AppendLine($" href: v{context.VersionHistory.CurrentVersion}.md");
-
+ if (preview)
+ {
+ content.AppendLine($"- name: v{context.VersionHistory.CurrentVersion}");
+ content.AppendLine($" href: v{context.VersionHistory.CurrentVersion}.md");
+ }
+
foreach (var version in context.VersionHistory.StableVersions.Reverse())
{
content.AppendLine($"- name: v{version}");
@@ -157,8 +169,9 @@ private void GenerateChangelogFull()
content.AppendLine("");
content.AppendLine("# Full ChangeLog");
content.AppendLine("");
- content.AppendLine(
- $"[!include[v{context.VersionHistory.CurrentVersion}](v{context.VersionHistory.CurrentVersion}.md)]");
+ if (preview)
+ content.AppendLine(
+ $"[!include[v{context.VersionHistory.CurrentVersion}](v{context.VersionHistory.CurrentVersion}.md)]");
foreach (var version in context.VersionHistory.StableVersions.Reverse())
content.AppendLine($"[!include[v{version}](v{version}.md)]");
@@ -174,7 +187,8 @@ private void GenerateChangelogIndex()
content.AppendLine("");
content.AppendLine("# ChangeLog");
content.AppendLine("");
- content.AppendLine($"* @changelog.v{context.VersionHistory.CurrentVersion}");
+ if (preview)
+ content.AppendLine($"* @changelog.v{context.VersionHistory.CurrentVersion}");
foreach (var version in context.VersionHistory.StableVersions.Reverse())
content.AppendLine($"* @changelog.v{version}");
content.AppendLine("* @changelog.full");
@@ -238,8 +252,8 @@ private void EnsureChangelogDetailsExist(bool forceClean = false)
private void DocfxChangelogDownload(string version, string versionPrevious, string lastCommit = "")
{
EnsureChangelogDetailsExist();
- context.Information("DocfxChangelogDownload: " + version);
- ChangeLogBuilder.Run(changelogDetailsDirectory, version, versionPrevious, lastCommit).Wait();
+ context.Information($"Downloading changelog details for v{version}");
+ ChangeLogBuilder.Run(context, changelogDetailsDirectory, version, versionPrevious, lastCommit);
}
private void GenerateRedirects()
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
index b4051ccbf4..c0c4e6c182 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.7",
+ "defaultValue": "0.1.1729",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
index 20d49ec024..4158c6bc0f 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.7",
+ "defaultValue": "0.1.1729",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
diff --git a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
index 1fe705443d..103d38332b 100644
--- a/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
+++ b/templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json
@@ -144,7 +144,7 @@
"type": "parameter",
"datatype": "string",
"description": "Version of BenchmarkDotNet that will be referenced.",
- "defaultValue": "0.13.7",
+ "defaultValue": "0.1.1729",
"replaces": "$(BenchmarkDotNetVersion)"
}
},
From 3f890fd4a87dad5718a84a19a0ecff734413a278 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 16:15:43 +0400
Subject: [PATCH 68/73] [build] Rename tasks
---
.github/workflows/generate-changelog.yaml | 2 +-
.github/workflows/generate-gh-pages.yaml | 6 +-
.github/workflows/run-tests.yaml | 40 ++++-----
.../CommandLineParser.cs | 29 ++-----
build/BenchmarkDotNet.Build/Program.cs | 85 +++----------------
docs/articles/contributing/documentation.md | 4 +-
6 files changed, 45 insertions(+), 121 deletions(-)
diff --git a/.github/workflows/generate-changelog.yaml b/.github/workflows/generate-changelog.yaml
index 54dd5c2250..71592e4d46 100644
--- a/.github/workflows/generate-changelog.yaml
+++ b/.github/workflows/generate-changelog.yaml
@@ -20,7 +20,7 @@ jobs:
ref: master
- name: Download changelog
- run: ./build.cmd DocsUpdate --depth 1 --preview
+ run: ./build.cmd docs-update --depth 1 --preview
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/generate-gh-pages.yaml b/.github/workflows/generate-gh-pages.yaml
index 868fa49c5c..cb01860995 100644
--- a/.github/workflows/generate-gh-pages.yaml
+++ b/.github/workflows/generate-gh-pages.yaml
@@ -20,15 +20,15 @@ jobs:
ref: docs-stable
- name: Build BenchmarkDotNet
- run: ./build.cmd Build
+ run: ./build.cmd build
- name: Download changelog
- run: ./build.cmd DocsUpdate --depth 1 --preview
+ run: ./build.cmd docs-update --depth 1 --preview
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build documentation
- run: ./build.cmd DocsBuild
+ run: ./build.cmd docs-build
- name: Upload Artifacts
uses: actions/upload-artifact@v1
diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml
index 66326dbc34..58a248382d 100644
--- a/.github/workflows/run-tests.yaml
+++ b/.github/workflows/run-tests.yaml
@@ -18,16 +18,16 @@ jobs:
run: Set-MpPreference -DisableRealtimeMonitoring $true
shell: powershell
- uses: actions/checkout@v3
- - name: Run task 'Build'
+ - name: Run task 'build'
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- ./build.cmd Build
- - name: Run task 'InTestsCore'
+ ./build.cmd build
+ - name: Run task 'in-tests-core'
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- ./build.cmd InTestsCore -e
+ ./build.cmd in-tests-core -e
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
@@ -42,16 +42,16 @@ jobs:
run: Set-MpPreference -DisableRealtimeMonitoring $true
shell: powershell
- uses: actions/checkout@v3
- - name: Run task 'Build'
+ - name: Run task 'build'
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- ./build.cmd Build
- - name: Run task 'InTestsFull'
+ ./build.cmd build
+ - name: Run task 'in-tests-full'
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- ./build.cmd InTestsFull -e
+ ./build.cmd in-tests-full -e
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
@@ -70,12 +70,12 @@ jobs:
platform: x64
- name: Set up zlib-static
run: sudo apt-get install -y libkrb5-dev
- - name: Run task 'Build'
- run: ./build.cmd Build
- - name: Run task 'UnitTests'
- run: ./build.cmd UnitTests -e
- - name: Run task 'InTestsCore'
- run: ./build.cmd InTestsCore -e
+ - name: Run task 'build'
+ run: ./build.cmd build
+ - name: Run task 'unit-tests'
+ run: ./build.cmd unit-tests -e
+ - name: Run task 'in-tests-core'
+ run: ./build.cmd in-tests-core -e
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
@@ -87,12 +87,12 @@ jobs:
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- - name: Run task 'Build'
- run: ./build.cmd Build
- - name: Run task 'UnitTests'
- run: ./build.cmd UnitTests -e
- - name: Run task 'InTestsCore'
- run: ./build.cmd InTestsCore -e
+ - name: Run task 'build'
+ run: ./build.cmd build
+ - name: Run task 'unit-tests'
+ run: ./build.cmd unit-tests -e
+ - name: Run task 'in-tests-core'
+ run: ./build.cmd in-tests-core -e
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
diff --git a/build/BenchmarkDotNet.Build/CommandLineParser.cs b/build/BenchmarkDotNet.Build/CommandLineParser.cs
index 5e797e6375..50dd344811 100644
--- a/build/BenchmarkDotNet.Build/CommandLineParser.cs
+++ b/build/BenchmarkDotNet.Build/CommandLineParser.cs
@@ -34,15 +34,18 @@ public class CommandLineParser
if (Is(taskName, "-t", "--target") && argsToProcess.Any())
taskName = argsToProcess.Dequeue();
- taskName = taskName.Replace("-", "");
-
var taskNames = GetTaskNames();
- if (!taskNames.Contains(taskName))
+ var matchedTaskName = taskNames
+ .FirstOrDefault(name => string.Equals(name.Replace("-", ""), taskName.Replace("-", ""),
+ StringComparison.OrdinalIgnoreCase));
+ if (matchedTaskName == null)
{
PrintError($"'{taskName}' is not a task");
return null;
}
+ taskName = matchedTaskName;
+
if (argsToProcess.Count == 1 && Is(argsToProcess.Peek(), "-h", "--help"))
{
PrintTaskHelp(taskName);
@@ -93,9 +96,6 @@ private void PrintHelp()
WritePrefix();
WriteLine("BenchmarkDotNet build script");
- WritePrefix();
- WriteLine("Task names are case-insensitive, dashes are ignored");
-
WriteLine();
WriteHeader("Usage:");
@@ -139,7 +139,7 @@ private void PrintHelp()
WritePrefix();
Write(CallScriptName + " ");
- WriteTask("unittests ");
+ WriteTask("unit-tests ");
WriteOption("--exclusive --verbosity ");
WriteArg("Diagnostic");
WriteLine();
@@ -289,21 +289,6 @@ private void PrintTaskHelp(string taskName)
WriteTask(taskName);
WriteLine();
- if (taskName.StartsWith("docs", StringComparison.OrdinalIgnoreCase))
- {
- WritePrefix();
- Write(ScriptName + " ");
- WriteTask("docs-" + taskName[4..].ToLowerInvariant());
- WriteLine();
- }
- else
- {
- WritePrefix();
- Write(ScriptName + " ");
- WriteTask(taskName.ToLowerInvariant());
- WriteLine();
- }
-
WriteLine();
PrintOptions(helpInfo.Options.Concat(baseOptions).ToArray());
diff --git a/build/BenchmarkDotNet.Build/Program.cs b/build/BenchmarkDotNet.Build/Program.cs
index 2717e9b20a..a0ab546188 100644
--- a/build/BenchmarkDotNet.Build/Program.cs
+++ b/build/BenchmarkDotNet.Build/Program.cs
@@ -16,14 +16,14 @@ public static int Main(string[] args)
}
}
-[TaskName("Restore")]
+[TaskName("restore")]
[TaskDescription("Restore NuGet packages")]
public class RestoreTask : FrostingTask
{
public override void Run(BuildContext context) => context.BuildRunner.Restore();
}
-[TaskName("Build")]
+[TaskName("build")]
[TaskDescription("Build BenchmarkDotNet.sln solution")]
[IsDependentOn(typeof(RestoreTask))]
public class BuildTask : FrostingTask
@@ -31,7 +31,7 @@ public class BuildTask : FrostingTask
public override void Run(BuildContext context) => context.BuildRunner.Build();
}
-[TaskName("UnitTests")]
+[TaskName("unit-tests")]
[TaskDescription("Run unit tests (fast)")]
[IsDependentOn(typeof(BuildTask))]
public class UnitTestsTask : FrostingTask
@@ -39,7 +39,7 @@ public class UnitTestsTask : FrostingTask
public override void Run(BuildContext context) => context.UnitTestRunner.RunUnitTests();
}
-[TaskName("InTestsFull")]
+[TaskName("in-tests-full")]
[TaskDescription("Run integration tests using .NET Framework 4.6.2+ (slow)")]
[IsDependentOn(typeof(BuildTask))]
public class InTestsFullTask : FrostingTask
@@ -49,7 +49,7 @@ public class InTestsFullTask : FrostingTask
public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests("net462");
}
-[TaskName("InTestsCore")]
+[TaskName("in-tests-core")]
[TaskDescription("Run integration tests using .NET 7 (slow)")]
[IsDependentOn(typeof(BuildTask))]
public class InTestsCoreTask : FrostingTask
@@ -57,7 +57,7 @@ public class InTestsCoreTask : FrostingTask
public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests("net7.0");
}
-[TaskName("AllTests")]
+[TaskName("all-tests")]
[TaskDescription("Run all unit and integration tests (slow)")]
[IsDependentOn(typeof(UnitTestsTask))]
[IsDependentOn(typeof(InTestsFullTask))]
@@ -66,7 +66,7 @@ public class AllTestsTask : FrostingTask
{
}
-[TaskName("Pack")]
+[TaskName("pack")]
[TaskDescription("Pack Nupkg packages")]
[IsDependentOn(typeof(BuildTask))]
public class PackTask : FrostingTask
@@ -74,16 +74,7 @@ public class PackTask : FrostingTask
public override void Run(BuildContext context) => context.BuildRunner.Pack();
}
-[TaskName("CI")]
-[TaskDescription("Perform all CI-related tasks: Restore, Build, AllTests, Pack")]
-[IsDependentOn(typeof(BuildTask))]
-[IsDependentOn(typeof(AllTestsTask))]
-[IsDependentOn(typeof(PackTask))]
-public class CiTask : FrostingTask
-{
-}
-
-[TaskName("DocsUpdate")]
+[TaskName("docs-update")]
[TaskDescription("Update generated documentation files")]
public class DocsUpdateTask : FrostingTask, IHelpProvider
{
@@ -99,7 +90,7 @@ public HelpInfo GetHelp()
}
}
-[TaskName("DocsPrepare")]
+[TaskName("docs-prepare")]
[TaskDescription("Prepare auxiliary documentation files")]
public class DocsPrepareTask : FrostingTask, IHelpProvider
{
@@ -114,11 +105,7 @@ public HelpInfo GetHelp()
}
}
-// In order to work around xref issues in DocFx, BenchmarkDotNet and BenchmarkDotNet.Annotations must be build
-// before running the DocFX_Build target. However, including a dependency on BuildTask here may have unwanted
-// side effects (CleanTask).
-// TODO: Define dependencies when a CI workflow scenario for using the "DocFX_Build" target exists.
-[TaskName("DocsBuild")]
+[TaskName("docs-build")]
[TaskDescription("Build final documentation")]
[IsDependentOn(typeof(DocsPrepareTask))]
public class DocsBuildTask : FrostingTask, IHelpProvider
@@ -127,11 +114,12 @@ public class DocsBuildTask : FrostingTask, IHelpProvider
public HelpInfo GetHelp() => new()
{
+ Description = "The 'build' task should be run manually to build api docs",
Options = new IOption[] { KnownOptions.DocsPreview }
};
}
-[TaskName("Release")]
+[TaskName("release")]
[TaskDescription("Release new version")]
[IsDependentOn(typeof(BuildTask))]
[IsDependentOn(typeof(PackTask))]
@@ -140,53 +128,4 @@ public class DocsBuildTask : FrostingTask, IHelpProvider
public class ReleaseTask : FrostingTask
{
public override void Run(BuildContext context) => context.ReleaseRunner.Run();
-}
-
-[TaskName("FastTests")]
-[TaskDescription("OBSOLETE: use 'UnitTests'")]
-[IsDependentOn(typeof(UnitTestsTask))]
-public class FastTestsTask : FrostingTask
-{
-}
-
-[TaskName("SlowFullFrameworkTests")]
-[TaskDescription("OBSOLETE: use 'InTestsFull'")]
-[IsDependentOn(typeof(InTestsFullTask))]
-public class SlowFullFrameworkTestsTask : FrostingTask
-{
-}
-
-[TaskName("SlowTestsNetCore")]
-[TaskDescription("OBSOLETE: use 'InTestsCore'")]
-[IsDependentOn(typeof(InTestsCoreTask))]
-public class SlowTestsNetCoreTask : FrostingTask
-{
-}
-
-[TaskName("DocFX_Changelog_Download")]
-[TaskDescription("OBSOLETE: use 'DocsUpdate'")]
-[IsDependentOn(typeof(DocsUpdateTask))]
-public class DocFxChangelogDownloadTask : FrostingTask
-{
-}
-
-[TaskName("DocFX_Changelog_Generate")]
-[TaskDescription("OBSOLETE: use 'DocsPrepare'")]
-[IsDependentOn(typeof(DocsPrepareTask))]
-public class DocfxChangelogGenerateTask : FrostingTask
-{
-}
-
-[TaskName("DocFX_Generate_Redirects")]
-[TaskDescription("OBSOLETE: use 'DocsBuild'")]
-[IsDependentOn(typeof(DocsBuildTask))]
-public class DocfxGenerateRedirectsTask : FrostingTask
-{
-}
-
-[TaskName("DocFX_Build")]
-[TaskDescription("OBSOLETE: use 'DocsBuild'")]
-[IsDependentOn(typeof(DocsBuildTask))]
-public class DocfxBuildTask : FrostingTask
-{
}
\ No newline at end of file
diff --git a/docs/articles/contributing/documentation.md b/docs/articles/contributing/documentation.md
index a0f23dd2d2..73854e928b 100644
--- a/docs/articles/contributing/documentation.md
+++ b/docs/articles/contributing/documentation.md
@@ -49,10 +49,10 @@ It will be transformed to:
## Building documentation locally
-You can build documentation locally with the help of the `DocsBuild` build task:
+You can build documentation locally with the help of the `docs-build` build task:
```
-build.cmd DocsBuild
+build.cmd docs-build
```
## See also
From c780b3cc6cd3f0e2c398956e49430afa47366061 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 16:50:30 +0400
Subject: [PATCH 69/73] [build] Rework examples
---
.../CommandLineParser.cs | 189 ++++++++----------
build/BenchmarkDotNet.Build/Example.cs | 38 ++++
build/BenchmarkDotNet.Build/HelpInfo.cs | 1 +
build/BenchmarkDotNet.Build/Program.cs | 132 ++++++++++--
4 files changed, 229 insertions(+), 131 deletions(-)
create mode 100644 build/BenchmarkDotNet.Build/Example.cs
diff --git a/build/BenchmarkDotNet.Build/CommandLineParser.cs b/build/BenchmarkDotNet.Build/CommandLineParser.cs
index 50dd344811..c80535a40f 100644
--- a/build/BenchmarkDotNet.Build/CommandLineParser.cs
+++ b/build/BenchmarkDotNet.Build/CommandLineParser.cs
@@ -108,78 +108,73 @@ private void PrintHelp()
WriteLine();
- WriteHeader("Examples:");
+ PrintExamples(GetTasks().SelectMany(task => task.HelpInfo.Examples));
- WritePrefix();
- Write(CallScriptName + " ");
- WriteTask("restore");
- WriteLine();
+ PrintOptions(baseOptions);
- WritePrefix();
- Write(CallScriptName + " ");
- WriteTask("build ");
- WriteOption("/p:");
- WriteArg("Configuration");
- WriteOption("=");
- WriteArg("Debug");
- WriteLine();
+ WriteHeader("Tasks:");
+ var taskWidth = GetTaskNames().Max(name => name.Length) + 3;
+ foreach (var (taskName, taskDescription, _) in GetTasks())
+ {
+ if (taskName.Equals("Default", StringComparison.OrdinalIgnoreCase))
+ continue;
- WritePrefix();
- Write(CallScriptName + " ");
- WriteTask("pack ");
- WriteOption("/p:");
- WriteArg("VersionPrefix");
- WriteOption("=");
- WriteArg("0.1.1729");
- WriteOption(" /p:");
- WriteArg("VersionSuffix");
- WriteOption("=");
- WriteArg("preview");
- WriteLine();
+ WriteTask(" " + taskName.PadRight(taskWidth));
+ Write(taskDescription);
- WritePrefix();
- Write(CallScriptName + " ");
- WriteTask("unit-tests ");
- WriteOption("--exclusive --verbosity ");
- WriteArg("Diagnostic");
- WriteLine();
+ WriteLine();
+ }
+ }
+
+ private void PrintTaskHelp(string taskName)
+ {
+ var taskType = typeof(BuildContext).Assembly
+ .GetTypes()
+ .Where(type => type.IsSubclassOf(typeof(FrostingTask)) && !type.IsAbstract)
+ .First(type => Is(type.GetCustomAttribute()?.Name, taskName));
+ taskName = taskType.GetCustomAttribute()!.Name;
+ var taskDescription = taskType.GetCustomAttribute()?.Description ?? "";
+ var helpInfo = GetHelpInfo(taskType);
+
+ WriteHeader("Description:");
WritePrefix();
- Write(CallScriptName + " ");
- WriteTask("docs-update ");
- WriteOption("--depth ");
- WriteArg("3");
+ WriteLine(!string.IsNullOrWhiteSpace(taskDescription)
+ ? $"Task '{taskName}': {taskDescription}"
+ : $"Task '{taskName}'");
+
+ if (string.IsNullOrWhiteSpace(helpInfo.Description))
+ foreach (var line in helpInfo.Description.Split('\n', StringSplitOptions.RemoveEmptyEntries))
+ {
+ WritePrefix();
+ WriteLine(line.Trim());
+ }
+
WriteLine();
+ WriteHeader("Usage:");
+
WritePrefix();
Write(CallScriptName + " ");
- WriteTask("docs-build ");
- WriteOption("--preview ");
+ WriteTask(taskName + " ");
+ WriteOption("[OPTIONS]");
WriteLine();
WriteLine();
- PrintOptions(baseOptions);
+ PrintExamples(helpInfo.Examples);
- WriteHeader("Tasks:");
- var taskWidth = GetTaskNames().Max(name => name.Length) + 3;
- foreach (var (taskName, taskDescription) in GetTasks())
- {
- if (taskName.Equals("Default", StringComparison.OrdinalIgnoreCase))
- continue;
+ PrintOptions(helpInfo.Options.Concat(baseOptions).ToArray());
- if (taskDescription.StartsWith("OBSOLETE", StringComparison.OrdinalIgnoreCase))
- {
- WriteObsolete(" " + taskName.PadRight(taskWidth));
- WriteObsolete(taskDescription);
- }
- else
+ if (helpInfo.EnvironmentVariables.Any())
+ {
+ WriteHeader("Environment variables:");
+ foreach (var variable in helpInfo.EnvironmentVariables)
{
- WriteTask(" " + taskName.PadRight(taskWidth));
- Write(taskDescription);
+ WritePrefix();
+ WriteOption(variable);
+ WriteLine();
}
-
- WriteLine();
}
}
@@ -242,68 +237,36 @@ int GetWidth(IOption option)
WriteLine();
}
- private void PrintTaskHelp(string taskName)
+ private void PrintExamples(IEnumerable examples)
{
- var taskType = typeof(BuildContext).Assembly
- .GetTypes()
- .Where(type => type.IsSubclassOf(typeof(FrostingTask)) && !type.IsAbstract)
- .First(type => Is(type.GetCustomAttribute()?.Name, taskName));
- taskName = taskType.GetCustomAttribute()!.Name;
- var taskDescription = taskType.GetCustomAttribute()?.Description ?? "";
- var taskInstance = Activator.CreateInstance(taskType);
- var helpInfo = taskInstance is IHelpProvider helpProvider ? helpProvider.GetHelp() : new HelpInfo();
-
- WriteHeader("Description:");
-
- WritePrefix();
- WriteLine($"Task '{taskName}'");
- if (!string.IsNullOrWhiteSpace(taskDescription))
- {
- WritePrefix();
- WriteLine(taskDescription);
- }
-
- if (string.IsNullOrWhiteSpace(helpInfo.Description))
- foreach (var line in helpInfo.Description.Split('\n', StringSplitOptions.RemoveEmptyEntries))
- {
- WritePrefix();
- WriteLine(line.Trim());
- }
-
- WriteLine();
-
- WriteHeader("Usage:");
-
- WritePrefix();
- Write(CallScriptName + " ");
- WriteTask(taskName + " ");
- WriteOption("[OPTIONS]");
- WriteLine();
-
- WriteLine();
-
WriteHeader("Examples:");
- WritePrefix();
- Write(ScriptName + " ");
- WriteTask(taskName);
- WriteLine();
-
- WriteLine();
-
- PrintOptions(helpInfo.Options.Concat(baseOptions).ToArray());
-
- if (helpInfo.EnvironmentVariables.Any())
+ foreach (var example in examples)
{
- WriteHeader("Environment variables:");
- foreach (var variable in helpInfo.EnvironmentVariables)
+ WritePrefix();
+ Write(CallScriptName + " ");
+ WriteTask(example.TaskName + " ");
+ foreach (var (name, value, isMsBuild) in example.Arguments)
{
- WritePrefix();
- WriteOption(variable);
+ if (isMsBuild)
+ {
+ WriteOption("/p:");
+ WriteArg(name);
+ WriteOption("=");
+ WriteArg(value + " ");
+ }
+ else
+ {
+ WriteOption(name + " ");
+ if (value != null)
+ WriteArg(value + " ");
+ }
}
WriteLine();
}
+
+ WriteLine();
}
private static HashSet GetTaskNames()
@@ -311,19 +274,27 @@ private static HashSet GetTaskNames()
return GetTasks().Select(task => task.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
}
- private static List<(string Name, string Description)> GetTasks()
+ private static List<(string Name, string Description, HelpInfo HelpInfo)> GetTasks()
{
return typeof(BuildContext).Assembly
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(FrostingTask)) && !type.IsAbstract)
.Select(type => (
Name: type.GetCustomAttribute()?.Name ?? "",
- Description: type.GetCustomAttribute()?.Description ?? ""
+ Description: type.GetCustomAttribute()?.Description ?? "",
+ HelpInfo: GetHelpInfo(type)
))
.Where(task => task.Name != "")
.ToList();
}
+ private static HelpInfo GetHelpInfo(Type taskType)
+ {
+ return Activator.CreateInstance(taskType) is IHelpProvider helpProvider
+ ? helpProvider.GetHelp()
+ : new HelpInfo();
+ }
+
private static bool Is(string? arg, params string[] values) =>
values.Any(value => value.Equals(arg, StringComparison.OrdinalIgnoreCase));
diff --git a/build/BenchmarkDotNet.Build/Example.cs b/build/BenchmarkDotNet.Build/Example.cs
new file mode 100644
index 0000000000..831def85d3
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/Example.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using BenchmarkDotNet.Build.Options;
+
+namespace BenchmarkDotNet.Build;
+
+public class Example
+{
+ private readonly List arguments = new();
+
+ public string TaskName { get; }
+ public IReadOnlyCollection Arguments => arguments;
+
+ public Example(string taskName)
+ {
+ TaskName = taskName;
+ }
+
+ public Example WithArgument(string name, string? value = null)
+ {
+ arguments.Add(new Argument(name, value, false));
+ return this;
+ }
+
+ public Example WithMsBuildArgument(string name, string value)
+ {
+ arguments.Add(new Argument(name, value, true));
+ return this;
+ }
+
+ public Example WithArgument(IOption option, string? value = null)
+ {
+ arguments.Add(new Argument(option.CommandLineName, value, false));
+ return this;
+ }
+
+
+ public record Argument(string Name, string? Value, bool IsMsBuild);
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/HelpInfo.cs b/build/BenchmarkDotNet.Build/HelpInfo.cs
index 868299677b..c7718cd7f5 100644
--- a/build/BenchmarkDotNet.Build/HelpInfo.cs
+++ b/build/BenchmarkDotNet.Build/HelpInfo.cs
@@ -8,4 +8,5 @@ public class HelpInfo
public string Description { get; init; } = "";
public IOption[] Options { get; init; } = Array.Empty();
public string[] EnvironmentVariables { get; init; } = Array.Empty();
+ public Example[] Examples { get; init; } = Array.Empty();
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Program.cs b/build/BenchmarkDotNet.Build/Program.cs
index a0ab546188..1f431d17c7 100644
--- a/build/BenchmarkDotNet.Build/Program.cs
+++ b/build/BenchmarkDotNet.Build/Program.cs
@@ -16,68 +16,130 @@ public static int Main(string[] args)
}
}
-[TaskName("restore")]
+[TaskName(Name)]
[TaskDescription("Restore NuGet packages")]
-public class RestoreTask : FrostingTask
+public class RestoreTask : FrostingTask, IHelpProvider
{
+ private const string Name = "restore";
+
public override void Run(BuildContext context) => context.BuildRunner.Restore();
+
+ public HelpInfo GetHelp()
+ {
+ return new HelpInfo
+ {
+ Examples = new[]
+ {
+ new Example(Name)
+ }
+ };
+ }
}
-[TaskName("build")]
+[TaskName(Name)]
[TaskDescription("Build BenchmarkDotNet.sln solution")]
[IsDependentOn(typeof(RestoreTask))]
-public class BuildTask : FrostingTask
+public class BuildTask : FrostingTask, IHelpProvider
{
+ private const string Name = "build";
public override void Run(BuildContext context) => context.BuildRunner.Build();
+
+ public HelpInfo GetHelp()
+ {
+ return new HelpInfo
+ {
+ Examples = new[]
+ {
+ new Example(Name).WithMsBuildArgument("Configuration", "Debug")
+ }
+ };
+ }
}
-[TaskName("unit-tests")]
+[TaskName(Name)]
[TaskDescription("Run unit tests (fast)")]
[IsDependentOn(typeof(BuildTask))]
-public class UnitTestsTask : FrostingTask
+public class UnitTestsTask : FrostingTask, IHelpProvider
{
+ private const string Name = "unit-tests";
public override void Run(BuildContext context) => context.UnitTestRunner.RunUnitTests();
+
+ public HelpInfo GetHelp()
+ {
+ return new HelpInfo
+ {
+ Examples = new[]
+ {
+ new Example(Name)
+ .WithArgument(KnownOptions.Exclusive)
+ .WithArgument(KnownOptions.Verbosity, "Diagnostic")
+ }
+ };
+ }
}
-[TaskName("in-tests-full")]
+[TaskName(Name)]
[TaskDescription("Run integration tests using .NET Framework 4.6.2+ (slow)")]
[IsDependentOn(typeof(BuildTask))]
-public class InTestsFullTask : FrostingTask
+public class InTestsFullTask : FrostingTask, IHelpProvider
{
+ private const string Name = "in-tests-full";
+
public override bool ShouldRun(BuildContext context) => context.IsRunningOnWindows();
public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests("net462");
+
+ public HelpInfo GetHelp() => new();
}
-[TaskName("in-tests-core")]
+[TaskName(Name)]
[TaskDescription("Run integration tests using .NET 7 (slow)")]
[IsDependentOn(typeof(BuildTask))]
-public class InTestsCoreTask : FrostingTask
+public class InTestsCoreTask : FrostingTask, IHelpProvider
{
+ private const string Name = "in-tests-core";
public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests("net7.0");
+ public HelpInfo GetHelp() => new();
}
-[TaskName("all-tests")]
+[TaskName(Name)]
[TaskDescription("Run all unit and integration tests (slow)")]
[IsDependentOn(typeof(UnitTestsTask))]
[IsDependentOn(typeof(InTestsFullTask))]
[IsDependentOn(typeof(InTestsCoreTask))]
-public class AllTestsTask : FrostingTask
+public class AllTestsTask : FrostingTask, IHelpProvider
{
+ private const string Name = "all-tests";
+ public HelpInfo GetHelp() => new();
}
-[TaskName("pack")]
+[TaskName(Name)]
[TaskDescription("Pack Nupkg packages")]
[IsDependentOn(typeof(BuildTask))]
-public class PackTask : FrostingTask
+public class PackTask : FrostingTask, IHelpProvider
{
+ private const string Name = "pack";
public override void Run(BuildContext context) => context.BuildRunner.Pack();
+
+ public HelpInfo GetHelp()
+ {
+ return new HelpInfo
+ {
+ Examples = new[]
+ {
+ new Example(Name)
+ .WithMsBuildArgument("VersionPrefix", "0.1.1729")
+ .WithMsBuildArgument("VersionSuffix", "preview")
+ }
+ };
+ }
}
-[TaskName("docs-update")]
+[TaskName(Name)]
[TaskDescription("Update generated documentation files")]
public class DocsUpdateTask : FrostingTask, IHelpProvider
{
+ private const string Name = "docs-update";
public override void Run(BuildContext context) => context.DocumentationRunner.Update();
public HelpInfo GetHelp()
@@ -85,47 +147,73 @@ public HelpInfo GetHelp()
return new HelpInfo
{
Options = new IOption[] { KnownOptions.DocsPreview, KnownOptions.DocsDepth },
- EnvironmentVariables = new[] { GitHubCredentials.TokenVariableName }
+ EnvironmentVariables = new[] { GitHubCredentials.TokenVariableName },
+ Examples = new[]
+ {
+ new Example(Name)
+ .WithArgument(KnownOptions.DocsDepth, "3")
+ .WithArgument(KnownOptions.DocsPreview)
+ }
};
}
}
-[TaskName("docs-prepare")]
+[TaskName(Name)]
[TaskDescription("Prepare auxiliary documentation files")]
public class DocsPrepareTask : FrostingTask, IHelpProvider
{
+ private const string Name = "docs-prepare";
public override void Run(BuildContext context) => context.DocumentationRunner.Prepare();
public HelpInfo GetHelp()
{
return new HelpInfo
{
- Options = new IOption[] { KnownOptions.DocsPreview }
+ Options = new IOption[] { KnownOptions.DocsPreview },
+ Examples = new[]
+ {
+ new Example(Name).WithArgument(KnownOptions.DocsPreview)
+ }
};
}
}
-[TaskName("docs-build")]
+[TaskName(Name)]
[TaskDescription("Build final documentation")]
[IsDependentOn(typeof(DocsPrepareTask))]
public class DocsBuildTask : FrostingTask, IHelpProvider
{
+ private const string Name = "docs-build";
public override void Run(BuildContext context) => context.DocumentationRunner.Build();
public HelpInfo GetHelp() => new()
{
Description = "The 'build' task should be run manually to build api docs",
- Options = new IOption[] { KnownOptions.DocsPreview }
+ Options = new IOption[] { KnownOptions.DocsPreview },
+ Examples = new[]
+ {
+ new Example(Name).WithArgument(KnownOptions.DocsPreview)
+ }
};
}
-[TaskName("release")]
+[TaskName(Name)]
[TaskDescription("Release new version")]
[IsDependentOn(typeof(BuildTask))]
[IsDependentOn(typeof(PackTask))]
[IsDependentOn(typeof(DocsUpdateTask))]
[IsDependentOn(typeof(DocsBuildTask))]
-public class ReleaseTask : FrostingTask
+public class ReleaseTask : FrostingTask, IHelpProvider
{
+ private const string Name = "release";
public override void Run(BuildContext context) => context.ReleaseRunner.Run();
+
+ public HelpInfo GetHelp() => new()
+ {
+ EnvironmentVariables = new[]
+ {
+ GitHubCredentials.TokenVariableName,
+ "NUGET_TOKEN"
+ }
+ };
}
\ No newline at end of file
From 398ae6545ec77aaf395a753d333299c59ab1f591 Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 17:55:27 +0400
Subject: [PATCH 70/73] [build] Rework ReleaseTask
---
build/BenchmarkDotNet.Build/BuildContext.cs | 35 ++++---
.../BenchmarkDotNet.Build/ChangeLogBuilder.cs | 2 +-
.../CommandLineParser.cs | 12 ++-
build/BenchmarkDotNet.Build/EnvVar.cs | 23 +++++
build/BenchmarkDotNet.Build/Example.cs | 10 +-
build/BenchmarkDotNet.Build/HelpInfo.cs | 2 +-
build/BenchmarkDotNet.Build/Helpers/Utils.cs | 13 +++
.../Meta/GitHubCredentials.cs | 20 ----
.../Options/BoolOption.cs | 7 ++
.../Options/KnownOptions.cs | 17 ++++
.../Options/StringOption.cs | 10 ++
build/BenchmarkDotNet.Build/Program.cs | 16 ++--
.../Runners/DocumentationRunner.cs | 7 +-
.../Runners/GitRunner.cs | 6 +-
.../Runners/ReleaseRunner.cs | 96 ++++++++-----------
build/common.props | 2 +-
16 files changed, 160 insertions(+), 118 deletions(-)
create mode 100644 build/BenchmarkDotNet.Build/EnvVar.cs
delete mode 100644 build/BenchmarkDotNet.Build/Meta/GitHubCredentials.cs
diff --git a/build/BenchmarkDotNet.Build/BuildContext.cs b/build/BenchmarkDotNet.Build/BuildContext.cs
index d20e5891e7..b09456c6e2 100644
--- a/build/BenchmarkDotNet.Build/BuildContext.cs
+++ b/build/BenchmarkDotNet.Build/BuildContext.cs
@@ -5,6 +5,7 @@
using System.Text;
using BenchmarkDotNet.Build.Helpers;
using BenchmarkDotNet.Build.Meta;
+using BenchmarkDotNet.Build.Options;
using BenchmarkDotNet.Build.Runners;
using Cake.Common;
using Cake.Common.Build;
@@ -23,9 +24,6 @@ public class BuildContext : FrostingContext
{
public string BuildConfiguration { get; set; } = "Release";
public DotNetVerbosity BuildVerbosity { get; set; } = DotNetVerbosity.Minimal;
- public bool VersionStable { get; }
- public string NextVersion { get; }
- public bool PushMode { get; }
public DirectoryPath RootDirectory { get; }
public DirectoryPath BuildDirectory { get; }
@@ -83,9 +81,7 @@ public BuildContext(ICakeContext context)
MsBuildSettingsBuild.WithProperty("UseSharedCompilation", "false");
}
- VersionStable = false;
- NextVersion = "";
- PushMode = false;
+
if (context.Arguments.HasArgument("msbuild"))
{
var msBuildParameters = context.Arguments.GetArguments().First(it => it.Key == "msbuild").Value;
@@ -109,19 +105,19 @@ public BuildContext(ICakeContext context)
if (parsedVerbosity != null)
BuildVerbosity = parsedVerbosity.Value;
}
-
- if (name.Equals("VersionStable", StringComparison.OrdinalIgnoreCase) && value != "")
- VersionStable = true;
-
- if (name.Equals("NextVersion", StringComparison.OrdinalIgnoreCase) && value != "")
- NextVersion = value;
-
- if (name.Equals("PushMode", StringComparison.OrdinalIgnoreCase) && value != "")
- PushMode = true;
}
}
}
+ if (KnownOptions.Stable.Resolve(this))
+ {
+ const string name = "NoVersionSuffix";
+ const string value = "true";
+ MsBuildSettingsRestore.WithProperty(name, value);
+ MsBuildSettingsBuild.WithProperty(name, value);
+ MsBuildSettingsPack.WithProperty(name, value);
+ }
+
// NativeAOT build requires VS C++ tools to be added to $path via vcvars64.bat
// but once we do that, dotnet restore fails with:
// "Please specify a valid solution configuration using the Configuration and Platform properties"
@@ -177,4 +173,13 @@ public void GenerateFile(FilePath filePath, string content, bool reportNoChanges
}
}
+ public void RunOnlyInPushMode(Action action)
+ {
+ if (KnownOptions.Push.Resolve(this))
+ {
+ action();
+ }
+ else
+ this.Information(" Skip because PushMode is disabled");
+ }
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs b/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
index a7537c51c6..e7769e1fbd 100644
--- a/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
+++ b/build/BenchmarkDotNet.Build/ChangeLogBuilder.cs
@@ -60,7 +60,7 @@ private async Task Build()
if (string.IsNullOrEmpty(lastCommit))
lastCommit = $"v{currentVersion}";
- var client = GitHubCredentials.CreateClient();
+ var client = Utils.CreateGitHubClient();
if (currentVersion == "_")
{
diff --git a/build/BenchmarkDotNet.Build/CommandLineParser.cs b/build/BenchmarkDotNet.Build/CommandLineParser.cs
index c80535a40f..fdb17328c0 100644
--- a/build/BenchmarkDotNet.Build/CommandLineParser.cs
+++ b/build/BenchmarkDotNet.Build/CommandLineParser.cs
@@ -86,7 +86,7 @@ public class CommandLineParser
private readonly IOption[] baseOptions =
{
- KnownOptions.Verbosity, KnownOptions.Exclusive, KnownOptions.Help
+ KnownOptions.Verbosity, KnownOptions.Exclusive, KnownOptions.Help, KnownOptions.Stable
};
private void PrintHelp()
@@ -108,7 +108,7 @@ private void PrintHelp()
WriteLine();
- PrintExamples(GetTasks().SelectMany(task => task.HelpInfo.Examples));
+ PrintExamples(GetTasks().SelectMany(task => task.HelpInfo.Examples).ToList());
PrintOptions(baseOptions);
@@ -169,10 +169,10 @@ private void PrintTaskHelp(string taskName)
if (helpInfo.EnvironmentVariables.Any())
{
WriteHeader("Environment variables:");
- foreach (var variable in helpInfo.EnvironmentVariables)
+ foreach (var envVar in helpInfo.EnvironmentVariables)
{
WritePrefix();
- WriteOption(variable);
+ WriteOption(envVar.Name);
WriteLine();
}
}
@@ -237,8 +237,10 @@ int GetWidth(IOption option)
WriteLine();
}
- private void PrintExamples(IEnumerable examples)
+ private void PrintExamples(IReadOnlyList examples)
{
+ if (!examples.Any())
+ return;
WriteHeader("Examples:");
foreach (var example in examples)
diff --git a/build/BenchmarkDotNet.Build/EnvVar.cs b/build/BenchmarkDotNet.Build/EnvVar.cs
new file mode 100644
index 0000000000..569c33726b
--- /dev/null
+++ b/build/BenchmarkDotNet.Build/EnvVar.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace BenchmarkDotNet.Build;
+
+public class EnvVar
+{
+ public static readonly EnvVar GitHubToken = new("GITHUB_TOKEN");
+ public static readonly EnvVar NuGetToken = new("NUGET_TOKEN");
+
+ public string Name { get; }
+
+ private EnvVar(string name) => Name = name;
+
+ public string? GetValue() => Environment.GetEnvironmentVariable(Name);
+
+ public void AssertHasValue()
+ {
+ if (string.IsNullOrEmpty(GetValue()))
+ throw new Exception($"Environment variable '{Name}' is not specified!");
+ }
+
+ public void SetEmpty() => Environment.SetEnvironmentVariable(Name, "");
+}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Example.cs b/build/BenchmarkDotNet.Build/Example.cs
index 831def85d3..eaef9799e5 100644
--- a/build/BenchmarkDotNet.Build/Example.cs
+++ b/build/BenchmarkDotNet.Build/Example.cs
@@ -15,19 +15,19 @@ public Example(string taskName)
TaskName = taskName;
}
- public Example WithArgument(string name, string? value = null)
+ public Example WithMsBuildArgument(string name, string value)
{
- arguments.Add(new Argument(name, value, false));
+ arguments.Add(new Argument(name, value, true));
return this;
}
- public Example WithMsBuildArgument(string name, string value)
+ public Example WithArgument(BoolOption option)
{
- arguments.Add(new Argument(name, value, true));
+ arguments.Add(new Argument(option.CommandLineName, null, false));
return this;
}
- public Example WithArgument(IOption option, string? value = null)
+ public Example WithArgument(StringOption option, string value)
{
arguments.Add(new Argument(option.CommandLineName, value, false));
return this;
diff --git a/build/BenchmarkDotNet.Build/HelpInfo.cs b/build/BenchmarkDotNet.Build/HelpInfo.cs
index c7718cd7f5..5de8c27931 100644
--- a/build/BenchmarkDotNet.Build/HelpInfo.cs
+++ b/build/BenchmarkDotNet.Build/HelpInfo.cs
@@ -7,6 +7,6 @@ public class HelpInfo
{
public string Description { get; init; } = "";
public IOption[] Options { get; init; } = Array.Empty();
- public string[] EnvironmentVariables { get; init; } = Array.Empty();
+ public EnvVar[] EnvironmentVariables { get; init; } = Array.Empty();
public Example[] Examples { get; init; } = Array.Empty();
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Helpers/Utils.cs b/build/BenchmarkDotNet.Build/Helpers/Utils.cs
index 017e092419..6e97e34618 100644
--- a/build/BenchmarkDotNet.Build/Helpers/Utils.cs
+++ b/build/BenchmarkDotNet.Build/Helpers/Utils.cs
@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using BenchmarkDotNet.Build.Options;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
+using Octokit;
namespace BenchmarkDotNet.Build.Helpers;
@@ -35,4 +38,14 @@ public static string GetOs()
};
return lookup.TryGetValue(verbosity, out var value) ? value : null;
}
+
+ public static GitHubClient CreateGitHubClient()
+ {
+ EnvVar.GitHubToken.AssertHasValue();
+
+ var client = new GitHubClient(new ProductHeaderValue("BenchmarkDotNet"));
+ var tokenAuth = new Credentials(EnvVar.GitHubToken.GetValue());
+ client.Credentials = tokenAuth;
+ return client;
+ }
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Meta/GitHubCredentials.cs b/build/BenchmarkDotNet.Build/Meta/GitHubCredentials.cs
deleted file mode 100644
index c174784417..0000000000
--- a/build/BenchmarkDotNet.Build/Meta/GitHubCredentials.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using Octokit;
-
-namespace BenchmarkDotNet.Build.Meta;
-
-public static class GitHubCredentials
-{
- public const string TokenVariableName = "GITHUB_TOKEN";
-
- public const string ProductHeader = "BenchmarkDotNet";
- public static string? Token => Environment.GetEnvironmentVariable(TokenVariableName);
-
- public static GitHubClient CreateClient()
- {
- var client = new GitHubClient(new ProductHeaderValue(ProductHeader));
- var tokenAuth = new Credentials(Token);
- client.Credentials = tokenAuth;
- return client;
- }
-}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/BoolOption.cs b/build/BenchmarkDotNet.Build/Options/BoolOption.cs
index 5a437d8095..3213ee8d54 100644
--- a/build/BenchmarkDotNet.Build/Options/BoolOption.cs
+++ b/build/BenchmarkDotNet.Build/Options/BoolOption.cs
@@ -17,4 +17,11 @@ public override bool Resolve(BuildContext context)
return true;
return !value.Equals(false.ToString(), StringComparison.OrdinalIgnoreCase);
}
+
+ public void AssertTrue(BuildContext context)
+ {
+ var value = Resolve(context);
+ if (!value)
+ throw new Exception($"{CommandLineName} is not specified");
+ }
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/KnownOptions.cs b/build/BenchmarkDotNet.Build/Options/KnownOptions.cs
index 19467c09c3..c5101e1d52 100644
--- a/build/BenchmarkDotNet.Build/Options/KnownOptions.cs
+++ b/build/BenchmarkDotNet.Build/Options/KnownOptions.cs
@@ -34,4 +34,21 @@ public static class KnownOptions
Description = "Prints help information",
Aliases = new[] { "-h" }
};
+
+ public static readonly BoolOption Stable = new("--stable")
+ {
+ Description = "Removes VersionSuffix in MSBuild settings",
+ Aliases = new[] { "-s" }
+ };
+
+ public static readonly StringOption NextVersion = new("--next-version")
+ {
+ Description = "Specifies next version number",
+ Aliases = new[] { "-n" }
+ };
+
+ public static readonly BoolOption Push = new("--push")
+ {
+ Description = "When specified, the task actually perform push to GitHub and nuget.org"
+ };
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Options/StringOption.cs b/build/BenchmarkDotNet.Build/Options/StringOption.cs
index 66a3bc375b..657017dbe2 100644
--- a/build/BenchmarkDotNet.Build/Options/StringOption.cs
+++ b/build/BenchmarkDotNet.Build/Options/StringOption.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace BenchmarkDotNet.Build.Options;
public class StringOption : Option
@@ -16,4 +18,12 @@ public override string Resolve(BuildContext context)
return "";
return value.Trim();
}
+
+ public string AssertHasValue(BuildContext context)
+ {
+ var value = Resolve(context);
+ if (string.IsNullOrWhiteSpace(value))
+ throw new Exception($"{CommandLineName} is not specified");
+ return value;
+ }
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Program.cs b/build/BenchmarkDotNet.Build/Program.cs
index 1f431d17c7..58d72f4cf8 100644
--- a/build/BenchmarkDotNet.Build/Program.cs
+++ b/build/BenchmarkDotNet.Build/Program.cs
@@ -1,4 +1,3 @@
-using BenchmarkDotNet.Build.Meta;
using BenchmarkDotNet.Build.Options;
using Cake.Common;
using Cake.Frosting;
@@ -129,7 +128,8 @@ public HelpInfo GetHelp()
{
new Example(Name)
.WithMsBuildArgument("VersionPrefix", "0.1.1729")
- .WithMsBuildArgument("VersionSuffix", "preview")
+ .WithMsBuildArgument("VersionSuffix", "preview"),
+ new Example(Name).WithArgument(KnownOptions.Stable)
}
};
}
@@ -147,7 +147,7 @@ public HelpInfo GetHelp()
return new HelpInfo
{
Options = new IOption[] { KnownOptions.DocsPreview, KnownOptions.DocsDepth },
- EnvironmentVariables = new[] { GitHubCredentials.TokenVariableName },
+ EnvironmentVariables = new[] { EnvVar.GitHubToken },
Examples = new[]
{
new Example(Name)
@@ -210,10 +210,14 @@ public class ReleaseTask : FrostingTask, IHelpProvider
public HelpInfo GetHelp() => new()
{
- EnvironmentVariables = new[]
+ Options = new IOption[] { KnownOptions.NextVersion, KnownOptions.Push },
+ EnvironmentVariables = new[] { EnvVar.GitHubToken, EnvVar.NuGetToken },
+ Examples = new[]
{
- GitHubCredentials.TokenVariableName,
- "NUGET_TOKEN"
+ new Example(Name)
+ .WithArgument(KnownOptions.Stable)
+ .WithArgument(KnownOptions.NextVersion, "v0.1.1729")
+ .WithArgument(KnownOptions.Push)
}
};
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
index 7b59d223fc..82edd849c5 100644
--- a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
@@ -57,14 +57,13 @@ public DocumentationRunner(BuildContext context)
public void Update()
{
+ EnvVar.GitHubToken.AssertHasValue();
+
ReadmeUpdater.Run(context);
UpdateLastFooter();
EnsureChangelogDetailsExist();
- if (string.IsNullOrEmpty(GitHubCredentials.Token))
- throw new Exception($"Environment variable '{GitHubCredentials.TokenVariableName}' is not specified!");
-
var history = context.VersionHistory;
var stableVersionCount = history.StableVersions.Length;
@@ -294,7 +293,7 @@ private void UpdateLastFooter()
{
var version = context.VersionHistory.CurrentVersion;
var previousVersion = context.VersionHistory.StableVersions.Last();
- var date = context.VersionStable
+ var date = KnownOptions.Stable.Resolve(context)
? DateTime.Now.ToString("MMMM dd, yyyy", CultureInfo.InvariantCulture)
: "TBA";
diff --git a/build/BenchmarkDotNet.Build/Runners/GitRunner.cs b/build/BenchmarkDotNet.Build/Runners/GitRunner.cs
index 0fd1ae5640..37ab8d5c0b 100644
--- a/build/BenchmarkDotNet.Build/Runners/GitRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/GitRunner.cs
@@ -63,13 +63,11 @@ public void Push(string target, bool force = false)
context.Information("[GitPush]");
context.Information($" Target: {target}");
context.Information($" Force: {force}");
- if (context.PushMode)
+ context.RunOnlyInPushMode(() =>
{
var forceFlag = force ? " --force" : "";
RunCommand($"push origin {target}{forceFlag}");
- }
- else
- context.Information(" Skip because PushMode is disabled");
+ });
}
private void RunCommand(string commandLineArgs) => RunCommand(null, commandLineArgs);
diff --git a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
index 10873340ef..053d2f4a05 100644
--- a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
@@ -3,7 +3,9 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using BenchmarkDotNet.Build.Helpers;
using BenchmarkDotNet.Build.Meta;
+using BenchmarkDotNet.Build.Options;
using Cake.Common.Diagnostics;
using Cake.Common.IO;
using Cake.Common.Tools.DotNet;
@@ -24,48 +26,46 @@ public ReleaseRunner(BuildContext context)
public void Run()
{
- var nextVersion = context.NextVersion;
+ KnownOptions.Stable.AssertTrue(context);
+
+ EnvVar.GitHubToken.AssertHasValue();
+ if (KnownOptions.Push.Resolve(context))
+ EnvVar.NuGetToken.AssertHasValue();
+ else
+ EnvVar.NuGetToken.SetEmpty();
+
+ var nextVersion = KnownOptions.NextVersion.AssertHasValue(context);
var currentVersion = context.VersionHistory.CurrentVersion;
- var isStable = context.VersionStable;
var tag = "v" + currentVersion;
- if (string.IsNullOrEmpty(nextVersion))
- throw new Exception("NextVersion is not specified");
- if (!isStable)
- throw new Exception("VersionStable is not specified");
- if (string.IsNullOrEmpty(GitHubCredentials.Token))
- throw new Exception($"Environment variable '{GitHubCredentials.TokenVariableName}' is not specified!");
- if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NUGET_TOKEN")))
- throw new Exception($"Environment variable 'NUGET_TOKEN' is not specified!");
-
context.GitRunner.Tag(tag);
- context.GitRunner.BranchMove(Repo.DocsStableBranch, "HEAD");
-
+
// Upgrade current version and commit changes
- UpdateVersionsTxt();
- UpdateCommonProps();
+ UpdateVersionsTxt(nextVersion);
+ UpdateCommonProps(nextVersion);
context.Information($"Building {context.TemplatesTestsProjectFile}");
context.BuildRunner.BuildProjectSilent(context.TemplatesTestsProjectFile);
context.GitRunner.Commit($"Set next BenchmarkDotNet version: {nextVersion}");
-
- UpdateMilestones().Wait();
-
+
+ UpdateMilestones(nextVersion).Wait();
+
+ context.GitRunner.BranchMove(Repo.DocsStableBranch, "HEAD");
context.GitRunner.Push(Repo.MasterBranch);
context.GitRunner.Push(Repo.DocsStableBranch, true);
context.GitRunner.Push(tag);
PushNupkg();
- PublishGitHubRelease().Wait();
+ PublishGitHubRelease();
}
- private void UpdateVersionsTxt()
+ private void UpdateVersionsTxt(string versionToAppend)
{
var content = context.FileReadText(context.VersionsFile).Trim();
- context.GenerateFile(context.VersionsFile, $"{content}\n{context.NextVersion}");
+ context.GenerateFile(context.VersionsFile, $"{content}\n{versionToAppend}");
}
- private void UpdateCommonProps()
+ private void UpdateCommonProps(string newCurrentVersion)
{
var regex = new Regex(@"([\d\.]+)");
@@ -75,43 +75,34 @@ private void UpdateCommonProps()
throw new Exception($"Failed to find VersionPrefix definition in {context.CommonPropsFile}");
var oldVersion = match.Groups[1].Value;
- context.GenerateFile(context.CommonPropsFile, content.Replace(oldVersion, context.NextVersion));
+ context.GenerateFile(context.CommonPropsFile, content.Replace(oldVersion, newCurrentVersion));
}
- private async Task UpdateMilestones()
+ private async Task UpdateMilestones(string nextVersion)
{
var currentVersion = context.VersionHistory.CurrentVersion;
- var nextVersion = context.NextVersion;
- var client = GitHubCredentials.CreateClient();
+ var client = Utils.CreateGitHubClient();
var allMilestones = await client.Issue.Milestone.GetAllForRepository(Repo.Owner, Repo.Name);
var currentMilestone = allMilestones.First(milestone => milestone.Title == $"v{currentVersion}");
context.Information($"[GitHub] Close milestone v{currentVersion}");
- if (context.PushMode)
+ context.RunOnlyInPushMode(() =>
{
- await client.Issue.Milestone.Update(Repo.Owner, Repo.Name, currentMilestone.Number,
- new MilestoneUpdate { State = ItemState.Closed, DueOn = DateTimeOffset.Now });
- }
- else
- {
- context.Information(" Skip because PushMode is disabled");
- }
+ var milestoneUpdate = new MilestoneUpdate { State = ItemState.Closed, DueOn = DateTimeOffset.Now };
+ client.Issue.Milestone.Update(Repo.Owner, Repo.Name, currentMilestone.Number, milestoneUpdate).Wait();
+ });
context.Information($"[GitHub] Create milestone v{nextVersion}");
- if (context.PushMode)
- {
- await client.Issue.Milestone.Create(Repo.Owner, Repo.Name, new NewMilestone($"v{nextVersion}"));
- }
- else
+ context.RunOnlyInPushMode(() =>
{
- context.Information(" Skip because PushMode is disabled");
- }
+ client.Issue.Milestone.Create(Repo.Owner, Repo.Name, new NewMilestone($"v{nextVersion}")).Wait();
+ });
}
private void PushNupkg()
{
- var nuGetToken = Environment.GetEnvironmentVariable("NUGET_TOKEN");
+ var nuGetToken = EnvVar.NuGetToken.GetValue();
var files = context
.GetFiles(context.ArtifactsDirectory.CombineWithFilePath("*").FullPath)
@@ -126,14 +117,11 @@ private void PushNupkg()
foreach (var file in files)
{
context.Information($"Push: {file}");
- if (context.PushMode)
- context.DotNetNuGetPush(file, settings);
- else
- context.Information(" Skip because PushMode is disabled");
+ context.RunOnlyInPushMode(() => context.DotNetNuGetPush(file, settings));
}
}
- private async Task PublishGitHubRelease()
+ private void PublishGitHubRelease()
{
var version = context.VersionHistory.CurrentVersion;
var tag = $"v{version}";
@@ -145,23 +133,19 @@ private async Task PublishGitHubRelease()
PreprocessMarkdown(context.FileReadText(notesFile));
context.Information($"[GitHub] Creating release '{version}'");
- var client = GitHubCredentials.CreateClient();
- if (context.PushMode)
+ var client = Utils.CreateGitHubClient();
+ context.RunOnlyInPushMode(() =>
{
- await client.Repository.Release.Create(Repo.Owner, Repo.Name, new NewRelease(tag)
+ client.Repository.Release.Create(Repo.Owner, Repo.Name, new NewRelease(tag)
{
Name = version,
Draft = false,
Prerelease = false,
GenerateReleaseNotes = false,
Body = notes
- });
+ }).Wait();
context.Information(" Success");
- }
- else
- {
- context.Information(" Skip because PushMode is disabled");
- }
+ });
}
private static string PreprocessMarkdown(string content)
diff --git a/build/common.props b/build/common.props
index 7037f3bed9..8254859142 100644
--- a/build/common.props
+++ b/build/common.props
@@ -40,7 +40,7 @@
0.13.7
-
+
develop
ci
From 8a7caa7acd6a2b2f5e49b57f225ccbabd268029b Mon Sep 17 00:00:00 2001
From: Andrey Akinshin
Date: Wed, 12 Jul 2023 18:25:47 +0400
Subject: [PATCH 71/73] [build] Rework ReadmeUpdater
---
README.md | 44 ++--------
build/BenchmarkDotNet.Build/BuildContext.cs | 2 +
.../CommandLineParser.cs | 4 +-
build/BenchmarkDotNet.Build/Helpers/Utils.cs | 14 +++-
build/BenchmarkDotNet.Build/Meta/Repo.cs | 18 ++++
build/BenchmarkDotNet.Build/Program.cs | 6 ++
.../Runners/DocumentationRunner.cs | 14 +++-
.../Runners/ReadmeUpdater.cs | 82 -------------------
.../Runners/ReleaseRunner.cs | 14 ++--
9 files changed, 63 insertions(+), 135 deletions(-)
delete mode 100644 build/BenchmarkDotNet.Build/Runners/ReadmeUpdater.cs
diff --git a/README.md b/README.md
index fa0f673bac..4d3518d5bf 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,11 @@ It's no harder than writing unit tests!
Under the hood, it performs a lot of [magic](#automation) that guarantees [reliable and precise](#reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) statistical engine.
BenchmarkDotNet protects you from popular benchmarking mistakes and warns you if something is wrong with your benchmark design or obtained measurements.
The results are presented in a [user-friendly](#friendliness) form that highlights all the important facts about your experiment.
-The library is adopted by [16600+ GitHub projects](#who-uses-benchmarkdotnet) including .NET Runtime.
+BenchmarkDotNet is already adopted by [16600+ GitHub projects](https://github.com/dotnet/BenchmarkDotNet/network/dependents) including
+ [.NET Runtime](https://github.com/dotnet/runtime),
+ [.NET Compiler](https://github.com/dotnet/roslyn),
+ [.NET Performance](https://github.com/dotnet/performance),
+ and many others.
It's [easy](#simplicity) to start writing benchmarks, check out the following example
(copy-pastable version is [here](https://benchmarkdotnet.org/articles/guides/getting-started.html)):
@@ -229,44 +233,6 @@ Of course, you can request any additional statistics and visualizations manually
If you don't customize the summary view,
the default presentation will be as much user-friendly as possible. :)
-## Who uses BenchmarkDotNet?
-
-Everyone!
-BenchmarkDotNet is already adopted by more than [16600+](https://github.com/dotnet/BenchmarkDotNet/network/dependents?package_id=UGFja2FnZS0xNTY3MzExMzE%3D) projects including
- [dotnet/performance](https://github.com/dotnet/performance) (reference benchmarks for all .NET Runtimes),
- [dotnet/runtime](https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=BenchmarkDotNet) (.NET runtime and libraries),
- [Roslyn](https://github.com/dotnet/roslyn/search?q=BenchmarkDotNet&type=Issues&utf8=✓) (C# and Visual Basic compiler),
- [Mono](https://github.com/mono/mono/tree/master/sdks/wasm/bench-runner),
- [ASP.NET Core](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/IIS/IIS/benchmarks),
- [ML.NET](https://github.com/dotnet/machinelearning/tree/main/test/Microsoft.ML.PerformanceTests),
- [Entity Framework Core](https://github.com/dotnet/efcore/tree/master/benchmark),
- [PowerShell](https://github.com/PowerShell/PowerShell/tree/master/test/perf/benchmarks)
- [SignalR](https://github.com/aspnet/SignalR/tree/master/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks),
- [F#](https://github.com/fsharp/fsharp/blob/master/tests/scripts/array-perf/array-perf.fs),
- [Orleans](https://github.com/dotnet/orleans/tree/master/test/Benchmarks),
- [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json.Tests/Benchmarks),
- [Elasticsearch.Net](https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/bool-queries.html#_perfomance_considerations),
- [Dapper](https://github.com/DapperLib/Dapper/tree/main/benchmarks/Dapper.Tests.Performance),
- [Expecto](https://github.com/haf/expecto/tree/master/Expecto.BenchmarkDotNet),
- [ImageSharp](https://github.com/SixLabors/ImageSharp/tree/master/tests/ImageSharp.Benchmarks),
- [RavenDB](https://github.com/ravendb/ravendb/tree/v4.0/bench),
- [NodaTime](https://github.com/nodatime/nodatime/tree/master/src/NodaTime.Benchmarks),
- [Jint](https://github.com/sebastienros/jint/tree/dev/Jint.Benchmark),
- [NServiceBus](https://github.com/Particular/NServiceBus/issues?utf8=✓&q=+BenchmarkDotNet+),
- [Serilog](https://github.com/serilog/serilog/tree/dev/test/Serilog.PerformanceTests),
- [Autofac](https://github.com/autofac/Autofac/tree/develop/bench/Autofac.Benchmarks),
- [Npgsql](https://github.com/npgsql/npgsql/tree/main/test/Npgsql.Benchmarks),
- [Avalonia](https://github.com/AvaloniaUI/Avalonia/tree/master/tests/Avalonia.Benchmarks),
- [ReactiveUI](https://github.com/reactiveui/ReactiveUI/tree/master/src/Benchmarks),
- [SharpZipLib](https://github.com/icsharpcode/SharpZipLib/tree/master/benchmark/ICSharpCode.SharpZipLib.Benchmark),
- [LiteDB](https://github.com/mbdavid/LiteDB/tree/master/LiteDB.Benchmarks),
- [GraphQL for .NET](https://github.com/graphql-dotnet/graphql-dotnet/tree/master/src/GraphQL.Benchmarks),
- [.NET Docs](https://github.com/dotnet/docs/tree/master/samples/snippets/csharp/safe-efficient-code/benchmark),
- [RestSharp](https://github.com/restsharp/RestSharp/tree/dev/benchmarks/RestSharp.Benchmarks),
- [MediatR](https://github.com/jbogard/MediatR/tree/master/test/MediatR.Benchmarks),
- [TensorFlow.NET](https://github.com/SciSharp/TensorFlow.NET/tree/master/src/TensorFlowNet.Benchmarks),
- [Apache Thrift](https://github.com/apache/thrift/tree/master/lib/netstd/Benchmarks/Thrift.Benchmarks).
-
## Learn more about benchmarking
BenchmarkDotNet is not a silver bullet that magically makes all of your benchmarks correct and analyzes the measurements for you.
diff --git a/build/BenchmarkDotNet.Build/BuildContext.cs b/build/BenchmarkDotNet.Build/BuildContext.cs
index b09456c6e2..a13c77c5ed 100644
--- a/build/BenchmarkDotNet.Build/BuildContext.cs
+++ b/build/BenchmarkDotNet.Build/BuildContext.cs
@@ -34,6 +34,7 @@ public class BuildContext : FrostingContext
public FilePathCollection AllPackableSrcProjects { get; }
public FilePath VersionsFile { get; }
public FilePath CommonPropsFile { get; }
+ public FilePath ReadmeFile { get; }
public DotNetMSBuildSettings MsBuildSettingsRestore { get; }
public DotNetMSBuildSettings MsBuildSettingsBuild { get; }
@@ -68,6 +69,7 @@ public BuildContext(ICakeContext context)
VersionsFile = BuildDirectory.CombineWithFilePath("versions.txt");
CommonPropsFile = BuildDirectory.CombineWithFilePath("common.props");
+ ReadmeFile = RootDirectory.CombineWithFilePath("README.md");
MsBuildSettingsRestore = new DotNetMSBuildSettings();
MsBuildSettingsBuild = new DotNetMSBuildSettings();
diff --git a/build/BenchmarkDotNet.Build/CommandLineParser.cs b/build/BenchmarkDotNet.Build/CommandLineParser.cs
index fdb17328c0..e97676ca68 100644
--- a/build/BenchmarkDotNet.Build/CommandLineParser.cs
+++ b/build/BenchmarkDotNet.Build/CommandLineParser.cs
@@ -143,11 +143,11 @@ private void PrintTaskHelp(string taskName)
? $"Task '{taskName}': {taskDescription}"
: $"Task '{taskName}'");
- if (string.IsNullOrWhiteSpace(helpInfo.Description))
+ if (!string.IsNullOrWhiteSpace(helpInfo.Description))
foreach (var line in helpInfo.Description.Split('\n', StringSplitOptions.RemoveEmptyEntries))
{
WritePrefix();
- WriteLine(line.Trim());
+ WriteLine(line.TrimEnd());
}
WriteLine();
diff --git a/build/BenchmarkDotNet.Build/Helpers/Utils.cs b/build/BenchmarkDotNet.Build/Helpers/Utils.cs
index 6e97e34618..2d6bbfc520 100644
--- a/build/BenchmarkDotNet.Build/Helpers/Utils.cs
+++ b/build/BenchmarkDotNet.Build/Helpers/Utils.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
-using BenchmarkDotNet.Build.Options;
-using Cake.Common.Diagnostics;
+using System.Text.RegularExpressions;
using Cake.Common.Tools.DotNet;
using Octokit;
@@ -48,4 +47,15 @@ public static GitHubClient CreateGitHubClient()
client.Credentials = tokenAuth;
return client;
}
+
+ public static string ApplyRegex(string content, string pattern, string newValue)
+ {
+ var regex = new Regex(pattern);
+ var match = regex.Match(content);
+ if (!match.Success)
+ throw new Exception("Failed to apply regex");
+
+ var oldValue = match.Groups[1].Value;
+ return content.Replace(oldValue, newValue);
+ }
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Meta/Repo.cs b/build/BenchmarkDotNet.Build/Meta/Repo.cs
index ec1231a9d0..38215fcce8 100644
--- a/build/BenchmarkDotNet.Build/Meta/Repo.cs
+++ b/build/BenchmarkDotNet.Build/Meta/Repo.cs
@@ -1,3 +1,8 @@
+using System;
+using System.Net.Http;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
namespace BenchmarkDotNet.Build.Meta;
public static class Repo
@@ -10,4 +15,17 @@ public static class Repo
public const string ChangelogDetailsBranch = "docs-changelog-details";
public const string DocsStableBranch = "docs-stable";
public const string MasterBranch = "master";
+
+ public static async Task GetDependentProjectsNumber()
+ {
+ using var httpClient = new HttpClient();
+ const string url = $"{HttpsUrlBase}/network/dependents";
+ var response = await httpClient.GetAsync(new Uri(url));
+ var dependentsPage = await response.Content.ReadAsStringAsync();
+ var match = new Regex(@"([0-9\,]+)[\n\r\s]+Repositories").Match(dependentsPage);
+ var number = int.Parse(match.Groups[1].Value.Replace(",", ""));
+ number = number / 100 * 100;
+ return number;
+ }
+
}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Program.cs b/build/BenchmarkDotNet.Build/Program.cs
index 58d72f4cf8..1ff1a26a7b 100644
--- a/build/BenchmarkDotNet.Build/Program.cs
+++ b/build/BenchmarkDotNet.Build/Program.cs
@@ -1,3 +1,4 @@
+using BenchmarkDotNet.Build.Meta;
using BenchmarkDotNet.Build.Options;
using Cake.Common;
using Cake.Frosting;
@@ -146,6 +147,11 @@ public HelpInfo GetHelp()
{
return new HelpInfo
{
+ Description = $"This task updates the following files:\n" +
+ $"* README.md (the number of dependent projects number)\n" +
+ $"* Last changelog footer (if {KnownOptions.Stable.CommandLineName} is specified)\n" +
+ $"* All changelog details in docs/_changelog\n" +
+ $" (This dir is a cloned version of this repo from branch {Repo.ChangelogDetailsBranch})",
Options = new IOption[] { KnownOptions.DocsPreview, KnownOptions.DocsDepth },
EnvironmentVariables = new[] { EnvVar.GitHubToken },
Examples = new[]
diff --git a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
index 82edd849c5..6883abe79a 100644
--- a/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs
@@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Text;
+using BenchmarkDotNet.Build.Helpers;
using BenchmarkDotNet.Build.Meta;
using BenchmarkDotNet.Build.Options;
using Cake.Common.Diagnostics;
@@ -59,7 +60,7 @@ public void Update()
{
EnvVar.GitHubToken.AssertHasValue();
- ReadmeUpdater.Run(context);
+ UpdateReadme();
UpdateLastFooter();
EnsureChangelogDetailsExist();
@@ -96,6 +97,17 @@ public void Update()
"HEAD");
}
+ private void UpdateReadme()
+ {
+ var content = Utils.ApplyRegex(
+ context.FileReadText(context.ReadmeFile),
+ @"\[(\d+)\+ GitHub projects\]",
+ Repo.GetDependentProjectsNumber().Result.ToString()
+ );
+
+ context.GenerateFile(context.ReadmeFile, content, true);
+ }
+
public void Prepare()
{
foreach (var version in context.VersionHistory.StableVersions)
diff --git a/build/BenchmarkDotNet.Build/Runners/ReadmeUpdater.cs b/build/BenchmarkDotNet.Build/Runners/ReadmeUpdater.cs
deleted file mode 100644
index c040beada3..0000000000
--- a/build/BenchmarkDotNet.Build/Runners/ReadmeUpdater.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using System.Net.Http;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using BenchmarkDotNet.Build.Meta;
-using Cake.FileHelpers;
-
-namespace BenchmarkDotNet.Build.Runners;
-
-public class ReadmeUpdater
-{
- public static void Run(BuildContext context) => new ReadmeUpdater().RunInternal(context);
-
- private void RunInternal(BuildContext context)
- {
- var dependentProjectsNumber = GetDependentProjectsNumber().Result;
- var updaters = new LineUpdater[]
- {
- new(
- "The library is adopted by",
- @"\[(\d+)\+ GitHub projects\]",
- dependentProjectsNumber
- ),
- new(
- "BenchmarkDotNet is already adopted by more than ",
- @"\[(\d+)\+\]",
- dependentProjectsNumber
- ),
- };
-
- var file = context.RootDirectory.CombineWithFilePath("README.md");
- var lines = context.FileReadLines(file);
- for (var i = 0; i < lines.Length; i++)
- {
- foreach (var updater in updaters)
- lines[i] = updater.Apply(lines[i]);
- }
-
- context.FileWriteLines(file, lines);
- }
-
- private static async Task GetDependentProjectsNumber()
- {
- using var httpClient = new HttpClient();
- const string url = $"{Repo.HttpsUrlBase}/network/dependents";
- var response = await httpClient.GetAsync(new Uri(url));
- var dependentsPage = await response.Content.ReadAsStringAsync();
- var match = new Regex(@"([0-9\,]+)[\n\r\s]+Repositories").Match(dependentsPage);
- var number = int.Parse(match.Groups[1].Value.Replace(",", ""));
- number = number / 100 * 100;
- return number;
- }
-
- private class LineUpdater
- {
- public string Prefix { get; }
- public Regex Regex { get; }
- public int Value { get; }
-
- public LineUpdater(string prefix, string regex, int value)
- {
- Prefix = prefix;
- Regex = new Regex(regex);
- Value = value;
- }
-
- public string Apply(string line)
- {
- if (!line.StartsWith(Prefix))
- return line;
-
- var match = Regex.Match(line);
- if (!match.Success)
- return line;
-
- // Groups[1] refers to the first group (\d+)
- var numberString = match.Groups[1].Value;
- var number = int.Parse(numberString);
- return line.Replace(number.ToString(), Value.ToString());
- }
- }
-}
\ No newline at end of file
diff --git a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
index 053d2f4a05..b1d2e191e4 100644
--- a/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
+++ b/build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs
@@ -67,15 +67,11 @@ private void UpdateVersionsTxt(string versionToAppend)
private void UpdateCommonProps(string newCurrentVersion)
{
- var regex = new Regex(@"([\d\.]+)");
-
- var content = context.FileReadText(context.CommonPropsFile);
- var match = regex.Match(content);
- if (!match.Success)
- throw new Exception($"Failed to find VersionPrefix definition in {context.CommonPropsFile}");
-
- var oldVersion = match.Groups[1].Value;
- context.GenerateFile(context.CommonPropsFile, content.Replace(oldVersion, newCurrentVersion));
+ var content = Utils.ApplyRegex(
+ context.FileReadText(context.CommonPropsFile),
+ @"([\d\.]+)",
+ newCurrentVersion);
+ context.GenerateFile(context.CommonPropsFile, content);
}
private async Task UpdateMilestones(string nextVersion)
From 7a8135baac605861635a0b379048c59f1683ca28 Mon Sep 17 00:00:00 2001
From: Mohammad Rahhal
Date: Thu, 13 Jul 2023 13:02:19 +0300
Subject: [PATCH 72/73] IComparable fallback for Tuple/ValueTuple (#2368)
* Catch CompareTo argument exceptions and fallback to string comparison
* Catch when message contains expected IComparable error
---
.../Parameters/ParameterComparer.cs | 11 ++-
.../ParameterComparerTests.cs | 68 +++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/src/BenchmarkDotNet/Parameters/ParameterComparer.cs b/src/BenchmarkDotNet/Parameters/ParameterComparer.cs
index a1363de073..6cadf6a946 100644
--- a/src/BenchmarkDotNet/Parameters/ParameterComparer.cs
+++ b/src/BenchmarkDotNet/Parameters/ParameterComparer.cs
@@ -28,7 +28,16 @@ private int CompareValues(object x, object y)
if (x != null && y != null && x.GetType() == y.GetType() &&
x is IComparable xComparable)
{
- return xComparable.CompareTo(y);
+ try
+ {
+ return xComparable.CompareTo(y);
+ }
+ // Some types, such as Tuple and ValueTuple, have a fallible CompareTo implementation which can throw if the inner items don't implement IComparable.
+ // See: https://github.com/dotnet/BenchmarkDotNet/issues/2346
+ // For now, catch and ignore the exception, and fallback to string comparison below.
+ catch (ArgumentException ex) when (ex.Message.Contains("At least one object must implement IComparable."))
+ {
+ }
}
// Anything else.
diff --git a/tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs b/tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs
index 0f01045b5c..2ef1bc8891 100644
--- a/tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs
+++ b/tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs
@@ -157,6 +157,70 @@ public void IComparableComparisionTest()
Assert.Equal(4, ((ComplexParameter)sortedData[3].Items[0].Value).Value);
}
+ [Fact]
+ public void ValueTupleWithNonIComparableInnerTypesComparisionTest()
+ {
+ var comparer = ParameterComparer.Instance;
+ var originalData = new[]
+ {
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 1), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 3), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 2), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 4), null)
+ })
+ };
+
+ var sortedData = originalData.OrderBy(d => d, comparer).ToArray();
+
+ Assert.Equal(1, (((ComplexNonIComparableParameter, int))sortedData[0].Items[0].Value).Item2);
+ Assert.Equal(2, (((ComplexNonIComparableParameter, int))sortedData[1].Items[0].Value).Item2);
+ Assert.Equal(3, (((ComplexNonIComparableParameter, int))sortedData[2].Items[0].Value).Item2);
+ Assert.Equal(4, (((ComplexNonIComparableParameter, int))sortedData[3].Items[0].Value).Item2);
+ }
+
+ [Fact]
+ public void TupleWithNonIComparableInnerTypesComparisionTest()
+ {
+ var comparer = ParameterComparer.Instance;
+ var originalData = new[]
+ {
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 1), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 3), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 2), null)
+ }),
+ new ParameterInstances(new[]
+ {
+ new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 4), null)
+ })
+ };
+
+ var sortedData = originalData.OrderBy(d => d, comparer).ToArray();
+
+ Assert.Equal(1, ((Tuple)sortedData[0].Items[0].Value).Item2);
+ Assert.Equal(2, ((Tuple)sortedData[1].Items[0].Value).Item2);
+ Assert.Equal(3, ((Tuple)sortedData[2].Items[0].Value).Item2);
+ Assert.Equal(4, ((Tuple)sortedData[3].Items[0].Value).Item2);
+ }
+
private class ComplexParameter : IComparable, IComparable
{
public ComplexParameter(int value, string name)
@@ -199,5 +263,9 @@ public int CompareTo(object obj)
return CompareTo(other);
}
}
+
+ private class ComplexNonIComparableParameter
+ {
+ }
}
}
\ No newline at end of file
From fd2639ff7b9e8353bb48c0eb6668c8bf32d19792 Mon Sep 17 00:00:00 2001
From: Tim Cassell <35501420+timcassell@users.noreply.github.com>
Date: Mon, 17 Jul 2023 04:14:13 -0400
Subject: [PATCH 73/73] Removed `PackageReference` from copied settings.
(#2365)
---
.../Toolchains/CsProj/CsProjGenerator.cs | 3 +-
.../CsProjGeneratorTests.cs | 58 -------------------
2 files changed, 1 insertion(+), 60 deletions(-)
diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
index 2934a28ed2..d732275d95 100644
--- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
+++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
@@ -34,8 +34,7 @@ public class CsProjGenerator : DotNetCliGenerator, IEquatable
"CopyLocalLockFileAssemblies",
"PreserveCompilationContext",
"UserSecretsId",
- "EnablePreviewFeatures",
- "PackageReference"
+ "EnablePreviewFeatures"
}.ToImmutableArray();
public string RuntimeFrameworkVersion { get; }
diff --git a/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs b/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs
index 1888e05227..715d7dad64 100644
--- a/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs
+++ b/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs
@@ -94,64 +94,6 @@ public void UseWpfSettingGetsCopied()
Assert.Equal("Microsoft.NET.Sdk", sdkName);
}
- [Fact]
- public void PackageReferenceSingleLineGetsCopied()
- {
- const string WithPackageReference = @"
-
-
- AnyCPU
-
-
-
-
-
-
-";
- var sut = new CsProjGenerator("netcoreapp3.0", null, null, null, true);
-
- var xmlDoc = new XmlDocument();
- xmlDoc.LoadXml(WithPackageReference);
- var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);
-
- AssertCustomProperties(@"
-
-", customProperties);
- Assert.Equal("Microsoft.NET.Sdk", sdkName);
- }
-
- [Fact]
- public void PackageReferenceMultiLineGetsCopied()
- {
- const string WithPackageReference = @"
-
-
- AnyCPU
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-";
- var sut = new CsProjGenerator("netcoreapp3.0", null, null, null, true);
-
- var xmlDoc = new XmlDocument();
- xmlDoc.LoadXml(WithPackageReference);
- var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);
-
- AssertCustomProperties(@"
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-", customProperties);
- Assert.Equal("Microsoft.NET.Sdk", sdkName);
- }
-
[Fact]
public void SettingsFromPropsFileImportedUsingAbsolutePathGetCopies()
{