Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
Saibamen committed Nov 30, 2024
2 parents a2ccecb + d5decbf commit e0563b8
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 182 deletions.
Original file line number Diff line number Diff line change
@@ -1,47 +1,27 @@
name: Build release packages and documentation
name: Release documentation
on:
workflow_dispatch:
push:
tags:
- 'v*'

env:
CONFIGURATION: Release

jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
dotnet-version: 9.0.x

- name: Setup Ruby for documentation build
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true

- name: Build package and docs
run: dotnet run --project 'build/build.fsproj' -- -t All

- name: Upload packages
uses: actions/upload-artifact@v4
with:
name: packages
path: |
bin/Release/NSubstitute/*.nupkg
bin/Release/NSubstitute/*.snupkg
retention-days: 7
- name: Build documentation
run: dotnet run --project 'build/build.fsproj' -- -t Documentation

- name: Upload documentation
uses: actions/upload-artifact@v4
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/release_packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Release packages
on:
workflow_dispatch:

jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x

- name: Build package
run: dotnet pack src/NSubstitute/NSubstitute.csproj -p:CI=true

- name: Upload packages
uses: actions/upload-artifact@v4
with:
name: packages
path: |
bin/Release/NSubstitute/*.nupkg
bin/Release/NSubstitute/*.snupkg
retention-days: 7
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build, Test, and Format
name: Build, Test, and Format verification
on:
push:
branches:
Expand All @@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macOS-latest]
framework: [net8.0]
framework: [net9.0, net8.0]
include:
- os: windows-latest
framework: net462
Expand All @@ -24,6 +24,7 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
8.0.x
- name: Build
Expand All @@ -37,13 +38,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
8.0.x
# used for documentation
Expand All @@ -53,8 +53,8 @@ jobs:
ruby-version: '3.2'
bundler-cache: true

- name: Build all targets
run: build\build.cmd --target All
- name: Build documentation
run: build\build.cmd --target Documentation

format-verify:
runs-on: ubuntu-latest
Expand All @@ -65,7 +65,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x

- name: Format
run: dotnet format --verify-no-changes
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* [UPDATE] Update github actions steps versions
* [UPDATE] Remove legacy obsolete API
* [UPDATE] Mark as obsolete api CompatArg with pre c# 7.0 support

* [NEW] Added .NET 9 to test matrix

### 5.3.0 (October 2024)

Expand Down
1 change: 0 additions & 1 deletion build/ExtractDocs.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module ExtractDocs

open System
open System.IO
open System.Text.RegularExpressions

let LiquidTagRegex = @"```(?<tag>\w+)" + // Tag start with argument. e.g. "```csharp"
Expand Down
120 changes: 3 additions & 117 deletions build/build.fs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
open System
open System.Diagnostics
open System.IO
open System.Text.RegularExpressions

open Fake.Core
open Fake.Core.TargetOperators
open Fake.DotNet
open Fake.IO
open Fake.IO.Globbing.Operators
open Fake.IO.FileSystemOperators
open Fake.Tools

open ExtractDocs

Expand All @@ -18,7 +16,7 @@ let description = Target.description

module FileReaderWriter =
let Read file = File.ReadAllText(file)
let Write file text = File.WriteAllText(file, text)
let Write file (text: string) = File.WriteAllText(file, text)
let TransformFile file target (f : string -> string) =
Read file
|> f
Expand All @@ -42,111 +40,15 @@ module ExamplesToCode =
ConvertFile file targetDir

type BuildVersion = { assembly: string; file: string; info: string; package: string }
let getVersion () =
// The --first-parent flag is needed to make our walk linear from current commit and top.
// This way also merge commit is counted as "1".
let desc = Git.CommandHelper.runSimpleGitCommand "" "describe --tags --long --abbrev=40 --first-parent --match=v*"
let result = Regex.Match(desc,
@"^v(?<maj>\d+)\.(?<min>\d+)\.(?<rev>\d+)(?<pre>-\w+\d*)?-(?<num>\d+)-g(?<sha>[a-z0-9]+)$",
RegexOptions.IgnoreCase)
.Groups
let getMatch (name:string) = result.[name].Value

let (major, minor, revision, preReleaseSuffix, commitsNum, commitSha) =
(getMatch "maj" |> int, getMatch "min" |> int, getMatch "rev" |> int, getMatch "pre", getMatch "num" |> int, getMatch "sha")

// Assembly version should contain major and minor only, as no breaking changes are expected in bug fix releases.
let assemblyVersion = sprintf "%d.%d.0.0" major minor
let fileVersion = sprintf "%d.%d.%d.%d" major minor revision commitsNum

// If number of commits since last tag is greater than zero, we append another identifier with number of commits.
// The produced version is larger than the last tag version.
// If we are on a tag, we use version without modification.
// Examples of output: 3.50.2.1, 3.50.2.215, 3.50.1-rc1.3, 3.50.1-rc3.35
let packageVersion = match commitsNum with
| 0 -> sprintf "%d.%d.%d%s" major minor revision preReleaseSuffix
| _ -> sprintf "%d.%d.%d%s.%d" major minor revision preReleaseSuffix commitsNum

let infoVersion = match commitsNum with
| 0 -> packageVersion
| _ -> sprintf "%s-%s" packageVersion commitSha

{ assembly = assemblyVersion; file = fileVersion; info = infoVersion; package = packageVersion }


let root = __SOURCE_DIRECTORY__ </> ".." |> Path.getFullName

let configuration = Environment.environVarOrDefault "configuration" "Debug"
let version = getVersion ()

let additionalArgs = [
"AssemblyVersion", version.assembly
"FileVersion", version.file
"InformationalVersion", version.info
"PackageVersion", version.package
]

let output = root </> "bin" </> configuration
let solution = (root </> "NSubstitute.sln")

let initTargets() =
Target.create "Default" ignore
Target.create "All" ignore

Target.description("Clean compilation artifacts and remove output bin directory")
Target.create "Clean" (fun _ ->
DotNet.exec (fun p -> { p with WorkingDirectory = root }) "clean"
(sprintf "--configuration %s --verbosity minimal" configuration)
|> ignore
Shell.cleanDirs [ output ]
)

Target.description("Restore dependencies")
Target.create "Restore" (fun _ ->
DotNet.restore (fun p -> p) solution
)

Target.description("Compile all projects")
Target.create "Build" (fun _ ->
DotNet.build (fun p ->
{ p with Configuration = DotNet.BuildConfiguration.fromString configuration
MSBuildParams = { p.MSBuildParams with Properties = additionalArgs }
}) solution
)

Target.description("Run tests")
Target.create "Test" (fun _ ->
DotNet.test (fun p ->
{ p with Configuration = DotNet.BuildConfiguration.fromString configuration
MSBuildParams = { p.MSBuildParams with Properties = additionalArgs }
}) (root </> "tests/NSubstitute.Acceptance.Specs/NSubstitute.Acceptance.Specs.csproj")
)

Target.description("Generate Nuget package")
Target.create "Package" (fun _ ->
DotNet.pack (fun p ->
{ p with Configuration = DotNet.BuildConfiguration.fromString configuration
MSBuildParams = { p.MSBuildParams with Properties = additionalArgs }
}) (root </> "src/NSubstitute/NSubstitute.csproj")
)

Target.description("Run all benchmarks. Must be run with configuration=Release.")
Target.create "Benchmarks" (fun _ ->
if configuration <> "Release" then
failwith "Benchmarks can only be run in Release mode. Please re-run the build in Release configuration."

let benchmarkCsproj = root </> "tests/NSubstitute.Benchmarks/NSubstitute.Benchmarks.csproj" |> Path.getFullName
let benchmarkToRun = Environment.environVarOrDefault "benchmark" "*" // Defaults to "*" (all)
[ "netcoreapp2.1" ]
|> List.iter (fun framework ->
Trace.traceImportant ("Benchmarking " + framework)
let work = output </> "benchmark-" + framework
Directory.ensure work
DotNet.exec (fun p -> { p with WorkingDirectory = work }) "run"
("--framework " + framework + " --project " + benchmarkCsproj + " -- " + benchmarkToRun)
|> ignore
)
)

Target.description("Extract, build and test code from documentation.")
Target.create "TestCodeFromDocs" <| fun _ ->
let outputCodePath = output </> "CodeFromDocs"
Expand Down Expand Up @@ -219,23 +121,7 @@ let initTargets() =
printfn ""
Target.listAvailable()

"Clean" ?=> "Build" |> ignore
"Clean" ?=> "Test" |> ignore
"Clean" ?=> "Restore" |> ignore
"Clean" ?=> "Documentation" |> ignore
"Clean" ?=> "TestCodeFromDocs" |> ignore
"Clean" ?=> "Package" |> ignore
"Clean" ?=> "Default" |> ignore

"Build" <== [ "Restore" ]
"Test" <== [ "Build" ]
"Documentation" <== [ "TestCodeFromDocs" ]
"Benchmarks" <== [ "Build" ]
// For packaging, use a clean build and make sure all tests (inc. docs) pass.
"Package" <== [ "Clean"; "Build"; "Test"; "TestCodeFromDocs" ]

"Default" <== [ "Restore"; "Build"; "Test" ]
"All" <== [ "Clean"; "Default"; "Documentation"; "Package" ]

[<EntryPoint>]
let main argv =
Expand All @@ -245,5 +131,5 @@ let main argv =
|> Context.RuntimeContext.Fake
|> Context.setExecutionContext
initTargets()
Target.runOrDefaultWithArguments "Default"
Target.runOrDefaultWithArguments "TestCodeFromDocs"
0
9 changes: 4 additions & 5 deletions build/build.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Exe</OutputType>
<OutputPath>buildOutput</OutputPath>
</PropertyGroup>
Expand All @@ -14,11 +14,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="17.11.4" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.11.4" />
<PackageReference Include="Microsoft.Build" Version="17.12.6" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
<PackageReference Include="MSBuild.StructuredLogger" Version="2.2.386" />
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
<PackageReference Include="Fake.Tools.Git" Version="6.1.3" />
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
</ItemGroup>

Expand Down
5 changes: 5 additions & 0 deletions src/NSubstitute/Core/Arguments/ArgumentMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ private class GenericToNonGenericMatcherProxy<T>(IArgumentMatcher<T> matcher) :
protected readonly IArgumentMatcher<T> _matcher = matcher;

public bool IsSatisfiedBy(object? argument) => _matcher.IsSatisfiedBy((T?)argument!);

public override string ToString() =>
_matcher is IDescribeSpecification describe
? describe.DescribeSpecification() ?? string.Empty
: _matcher.ToString() ?? string.Empty;
}

private class GenericToNonGenericMatcherProxyWithDescribe<T> : GenericToNonGenericMatcherProxy<T>, IDescribeNonMatches
Expand Down
5 changes: 4 additions & 1 deletion src/NSubstitute/Core/Arguments/ArgumentSpecification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public string FormatArgument(object? argument)
: ArgumentFormatter.Default.Format(argument, highlight: !isSatisfiedByArg);
}

public override string ToString() => matcher.ToString() ?? string.Empty;
public override string ToString() =>
matcher is IDescribeSpecification describe
? describe.DescribeSpecification()
: matcher.ToString() ?? string.Empty;

public IArgumentSpecification CreateCopyMatchingAnyArgOfType(Type requiredType)
{
Expand Down
12 changes: 8 additions & 4 deletions src/NSubstitute/Core/Arguments/IArgumentMatcher.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace NSubstitute.Core.Arguments;

/// <summary>
/// Provides a specification for arguments for use with <see ctype="Arg.Matches (IArgumentMatcher)" />.
/// Can additionally implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
/// Provides a specification for arguments.
/// Can implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
/// Can implement <see cref="IDescribeSpecification"/> to give descriptions of expected arguments (otherwise
/// `ToString()` will be used for descriptions).
/// </summary>
public interface IArgumentMatcher
{
Expand All @@ -14,8 +16,10 @@ public interface IArgumentMatcher
}

/// <summary>
/// Provides a specification for arguments for use with <see ctype="Arg.Matches &lt; T &gt;(IArgumentMatcher)" />.
/// Can additionally implement <see ctype="IDescribeNonMatches" /> to give descriptions when arguments do not match.
/// Provides a specification for arguments.
/// Can implement <see cref="IDescribeNonMatches" /> to give descriptions when arguments do not match.
/// Can implement <see cref="IDescribeSpecification"/> to give descriptions of expected arguments (otherwise
/// `ToString()` will be used for descriptions).
/// </summary>
/// <typeparam name="T">Matches arguments of type <typeparamref name="T"/> or compatible type.</typeparam>
public interface IArgumentMatcher<T>
Expand Down
Loading

0 comments on commit e0563b8

Please sign in to comment.