Compare commits

...

8 Commits

Author SHA1 Message Date
dependabot[bot]
1522e3cc9c Bump WoofWareMyriadPluginVersion from 2.1.51 to 2.1.52 (#99)
* Bump WoofWareMyriadPluginVersion from 2.1.51 to 2.1.52

Bumps `WoofWareMyriadPluginVersion` from 2.1.51 to 2.1.52.

Updates `WoofWare.Myriad.Plugins` from 2.1.51 to 2.1.52
- [Release notes](https://github.com/Smaug123/WoofWare.Myriad/releases)
- [Changelog](https://github.com/Smaug123/WoofWare.Myriad/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Smaug123/WoofWare.Myriad/compare/WoofWare.Myriad.Plugins.2.1.51...WoofWare.Myriad.Plugins.2.1.52)

Updates `WoofWare.Myriad.Plugins.Attributes` from 3.1.7 to 3.1.8
- [Release notes](https://github.com/Smaug123/WoofWare.Myriad/releases)
- [Changelog](https://github.com/Smaug123/WoofWare.Myriad/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Smaug123/WoofWare.Myriad/compare/WoofWare.Myriad.Plugins.Attributes.3.1.7...WoofWare.Myriad.Plugins.Attributes.3.1.8)

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: WoofWare.Myriad.Plugins.Attributes
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-01 19:05:43 +01:00
dependabot[bot]
81c6b584a4 Bump ApiSurface from 4.0.41 to 4.0.42, WoofWare.Myriad.Plugins from 2.1.45 to 2.1.51 (#98)
* Bump WoofWare.Myriad.Plugins from 2.1.45 to 2.1.49

Bumps [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad) from 2.1.45 to 2.1.49.
- [Release notes](https://github.com/Smaug123/WoofWare.Myriad/releases)
- [Changelog](https://github.com/Smaug123/WoofWare.Myriad/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Smaug123/WoofWare.Myriad/compare/WoofWare.Myriad.Plugins.2.1.45...WoofWare.Myriad.Plugins.2.1.49)

---
updated-dependencies:
- dependency-name: WoofWare.Myriad.Plugins
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump ApiSurface from 4.0.41 to 4.0.42

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.41 to 4.0.42.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.41...ApiSurface.4.0.42)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-01 18:44:01 +01:00
dependabot[bot]
40824e06e7 Bump actions/attest-build-provenance from 1.0.0 to 1.3.2 (#96)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.0.0 to 1.3.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](897ed5eab6...bdd51370e0)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-24 18:54:49 +01:00
Patrick Stevens
fb945c04ac Use DOTNET_STARTUP_HOOK to have the target run the tests (#91) 2024-06-23 17:25:24 +01:00
Patrick Stevens
85cd116d52 Delete unused file (#94) 2024-06-23 15:30:46 +01:00
Patrick Stevens
8e7c54cc83 Split out AppContext and Args to lib (#93) 2024-06-23 15:26:35 +01:00
Patrick Stevens
378a0169f8 Formatting (#92) 2024-06-23 15:13:40 +01:00
Patrick Stevens
870804d6ef Multi-framework Consumer test (#89) 2024-06-23 11:50:58 +01:00
21 changed files with 557 additions and 203 deletions

View File

@@ -1,40 +1,40 @@
root=true
root = true
[*]
charset=utf-8
trim_trailing_whitespace=true
insert_final_newline=true
indent_style=space
indent_size=4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
# ReSharper properties
resharper_xml_indent_size=2
resharper_xml_max_line_length=100
resharper_xml_tab_width=2
resharper_xml_indent_size = 2
resharper_xml_max_line_length = 100
resharper_xml_tab_width = 2
[*.{csproj,fsproj,sqlproj,targets,props,ts,tsx,css,json}]
indent_style=space
indent_size=2
indent_style = space
indent_size = 2
[*.{fs,fsi}]
fsharp_bar_before_discriminated_union_declaration=true
fsharp_space_before_uppercase_invocation=true
fsharp_space_before_class_constructor=true
fsharp_space_before_member=true
fsharp_space_before_colon=true
fsharp_space_before_semicolon=true
fsharp_multiline_bracket_style=aligned
fsharp_newline_between_type_definition_and_members=true
fsharp_align_function_signature_to_indentation=true
fsharp_alternative_long_member_definitions=true
fsharp_multi_line_lambda_closing_newline=true
fsharp_experimental_keep_indent_in_branch=true
fsharp_max_value_binding_width=80
fsharp_max_record_width=0
max_line_length=120
end_of_line=lf
fsharp_bar_before_discriminated_union_declaration = true
fsharp_space_before_uppercase_invocation = true
fsharp_space_before_class_constructor = true
fsharp_space_before_member = true
fsharp_space_before_colon = true
fsharp_space_before_semicolon = true
fsharp_multiline_bracket_style = aligned
fsharp_newline_between_type_definition_and_members = true
fsharp_align_function_signature_to_indentation = true
fsharp_alternative_long_member_definitions = true
fsharp_multi_line_lambda_closing_newline = true
fsharp_experimental_keep_indent_in_branch = true
fsharp_max_value_binding_width = 80
fsharp_max_record_width = 0
max_line_length = 120
end_of_line = lf
[*.{appxmanifest,build,dtd,nuspec,xaml,xamlx,xoml,xsd}]
indent_style=space
indent_size=2
tab_width=2
indent_style = space
indent_size = 2
tab_width = 2

View File

@@ -38,7 +38,7 @@ jobs:
- name: Build
run: 'nix develop --command dotnet build --no-restore --configuration ${{matrix.config}}'
- name: Test
run: 'nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}}'
run: 'nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}} --framework net8.0'
selftest:
runs-on: ubuntu-latest
@@ -71,7 +71,49 @@ jobs:
- name: Build
run: 'nix develop --command dotnet build --no-restore --configuration Release'
- name: Test using self
run: 'nix develop --command dotnet exec ./WoofWare.NUnitTestRunner/bin/Release/net8.0/WoofWare.NUnitTestRunner.dll ./Consumer/bin/Release/net8.0/Consumer.dll --trx TrxOut/out.trx'
run: 'nix develop --command dotnet exec ./WoofWare.NUnitTestRunner/bin/Release/net6.0/WoofWare.NUnitTestRunner.dll ./Consumer/bin/Release/net8.0/Consumer.dll --trx TrxOut/out.trx'
- name: Parse Trx files
uses: NasAmin/trx-parser@v0.6.0
if: always()
id: trx-parser
with:
TRX_PATH: ${{ github.workspace }}/TrxOut
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
selftest-net6:
runs-on: ubuntu-latest
permissions:
actions: none
checks: write
contents: read
deployments: none
id-token: none
issues: none
discussions: none
packages: none
pages: none
pull-requests: read
repository-projects: none
security-events: none
statuses: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
- name: Install Nix
uses: cachix/install-nix-action@V27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Restore dependencies
run: nix develop --command dotnet restore
- name: Build runner
run: 'nix develop --command dotnet build WoofWare.NUnitTestRunner --configuration Release'
- name: Build target
run: 'nix develop --command dotnet build Consumer --configuration Release'
- name: Test using self
run: 'nix develop .#net6 --command ./WoofWare.NUnitTestRunner/bin/Release/net6.0/WoofWare.NUnitTestRunner ./Consumer/bin/Release/net6.0/Consumer.dll --trx TrxOut/out.trx'
- name: Parse Trx files
uses: NasAmin/trx-parser@v0.6.0
if: always()
@@ -255,7 +297,7 @@ jobs:
name: nuget-package-lib
path: packed
- name: Attest Build Provenance
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
with:
subject-path: "packed/*.nupkg"
@@ -274,7 +316,7 @@ jobs:
name: nuget-package-tool
path: packed
- name: Attest Build Provenance
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
with:
subject-path: "packed/*.nupkg"
@@ -316,7 +358,7 @@ jobs:
run: 'bash ./.github/workflows/assert-contents.sh'
- name: Attest Build Provenance
if: steps.publish-success.outputs.result == 'published'
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
with:
subject-path: "from-nuget.nupkg"
@@ -358,7 +400,7 @@ jobs:
run: 'bash ./.github/workflows/assert-contents.sh'
- name: Attest Build Provenance
if: steps.publish-success.outputs.result == 'published'
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
with:
subject-path: "from-nuget.nupkg"

View File

@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
@@ -10,6 +9,7 @@
<ItemGroup>
<Compile Include="NoAttribute.fs" />
<Compile Include="Inconclusive.fs" />
<Compile Include="RunSubProcess.fs" />
<Compile Include="TestNonParallel.fs" />
<Compile Include="TestParallel.fs" />
<Compile Include="TestStdout.fs" />
@@ -26,9 +26,9 @@
<ItemGroup>
<PackageReference Include="FsUnit" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
<PackageReference Include="NUnit" Version="4.1.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
<PackageReference Include="NUnit" Version="4.1.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
</ItemGroup>
</Project>

45
Consumer/RunSubProcess.fs Normal file
View File

@@ -0,0 +1,45 @@
namespace Consumer
open System
open System.Diagnostics
open System.IO
open System.IO.Compression
open System.Text
open NUnit.Framework
open FsUnitTyped
[<TestFixture>]
module RunSubProcess =
[<Test>]
let ``Run a subprocess`` () =
let exe = "/bin/bash"
let args = [ "-c" ; "echo hi >&2 && echo bye" ]
let workingDir = None
let psi =
ProcessStartInfo (
exe,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Option.toObj workingDir
)
for arg in args do
psi.ArgumentList.Add arg
psi.EnvironmentVariables.Add ("THING", Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "hi"))
let stderr = StringBuilder ()
use proc = new Process (StartInfo = psi)
proc.OutputDataReceived.Add (fun e -> printfn $"%s{e.Data}")
proc.ErrorDataReceived.Add (fun e ->
eprintfn $"%s{e.Data}"
stderr.AppendLine e.Data |> ignore
)
proc.Start () |> shouldEqual true
proc.BeginOutputReadLine ()
proc.BeginErrorReadLine ()
proc.WaitForExit ()

View File

@@ -0,0 +1,99 @@
namespace WoofWare.NUnitTestRunner
open System
open System.IO
[<AutoOpen>]
module internal Patterns =
let (|Key|_|) (start : string) (s : string) : string option =
if s.StartsWith (start + "=", StringComparison.Ordinal) then
s.Substring (start.Length + 1) |> Some
else
None
/// Represents how verbose the test runner's logging should be.
[<RequireQualifiedAccess>]
type LogLevel =
/// Don't log any information about the test run.
| Nothing
/// Log as much information as is available about the test run.
| Verbose
/// Arguments controlling the test runner itself (not the tests therein).
type Args =
{
/// The DLL containing the tests we'll reflectively discover and invoke.
Dll : FileInfo
/// If set, the output file into which we will write a TRX report. (We'll create parent directories as necessary.)
Trx : FileInfo option
/// Also contains the original string which specified the filter.
Filter : (string * Filter) option
/// How verbose to be with the test runner's own logging.
Logging : LogLevel
/// Maximum number of tests which can run concurrently. This setting overrides any LevelOfParallelism reflectively
/// extracted from the assembly under test.
LevelOfParallelism : int option
/// Abort if the test runner is running for longer than this timeout.
Timeout : TimeSpan option
}
/// Parse `argv` into a structured Args.
static member Parse (args : string list) : Args =
match args with
| [] -> failwith "The first arg must be a positional arg, the DLL to test."
| dll :: args ->
let rec go
(trx : FileInfo option)
(filter : (string * Filter) option)
(logging : LogLevel option)
(par : int option)
(timeout : TimeSpan option)
(args : string list)
=
match args with
| [] ->
{
Dll = FileInfo dll
Trx = trx
Filter = filter
Logging = logging |> Option.defaultValue LogLevel.Nothing
LevelOfParallelism = par
Timeout = timeout
}
| Key "--filter" filterStr :: rest
| "--filter" :: filterStr :: rest ->
match filter with
| Some _ -> failwith "Two conflicting filters; you can only specify --filter once"
| None -> go trx (Some (filterStr, Filter.parse filterStr)) logging par timeout rest
| Key "--trx" trxStr :: rest
| "--trx" :: trxStr :: rest ->
match trx with
| Some _ -> failwith "Two conflicting TRX outputs; you can only specify --trx once"
| None -> go (Some (FileInfo trxStr)) filter logging par timeout rest
| Key "--verbose" verboseStr :: rest
| "--verbose" :: verboseStr :: rest ->
match logging with
| Some _ -> failwith "Two conflicting --verbose outputs; you can only specify --verbose once"
| None ->
let verbose =
if Boolean.Parse verboseStr then
LogLevel.Verbose
else
LogLevel.Nothing
go trx filter (Some verbose) par timeout rest
| Key "--parallelism" parStr :: rest
| "--parallelism" :: parStr :: rest ->
match par with
| Some _ -> failwith "Two conflicting --parallelism outputs; you can only specify --parallelism once"
| None -> go trx filter logging (Some (Int32.Parse parStr)) timeout rest
| Key "--timeout-seconds" timeoutStr :: rest
| "--timeout-seconds" :: timeoutStr :: rest ->
match timeout with
| Some _ ->
failwith "Two conflicting --timeout-seconds outputs; you can only specify --timeout-seconds once"
| None -> go trx filter logging par (Some (TimeSpan.FromSeconds (Int32.Parse timeoutStr |> float))) rest
| k :: _rest -> failwith $"Unrecognised arg %s{k}"
go None None None None None args

View File

@@ -89,8 +89,13 @@ type TestContexts =
AsyncLocal = local
}
member internal this.Stdout : TextWriter = this.StdOutWriter
member internal this.Stderr : TextWriter = this.StdErrWriter
/// An output stream which will identify the ExecutionContext it's being written to from,
/// and will separate that output into its own stream internally.
member this.Stdout : TextWriter = this.StdOutWriter
/// An output stream which will identify the ExecutionContext it's being written to from,
/// and will separate that output into its own stream internally.
member this.Stderr : TextWriter = this.StdErrWriter
member internal this.DumpStdout (id : OutputStreamId) : string =
lock

View File

@@ -1,3 +1,18 @@
WoofWare.NUnitTestRunner.Args inherit obj, implements WoofWare.NUnitTestRunner.Args System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.Args..ctor [constructor]: (System.IO.FileInfo, System.IO.FileInfo option, (string * WoofWare.NUnitTestRunner.Filter) option, WoofWare.NUnitTestRunner.LogLevel, int option, System.TimeSpan option)
WoofWare.NUnitTestRunner.Args.Dll [property]: [read-only] System.IO.FileInfo
WoofWare.NUnitTestRunner.Args.Filter [property]: [read-only] (string * WoofWare.NUnitTestRunner.Filter) option
WoofWare.NUnitTestRunner.Args.get_Dll [method]: unit -> System.IO.FileInfo
WoofWare.NUnitTestRunner.Args.get_Filter [method]: unit -> (string * WoofWare.NUnitTestRunner.Filter) option
WoofWare.NUnitTestRunner.Args.get_LevelOfParallelism [method]: unit -> int option
WoofWare.NUnitTestRunner.Args.get_Logging [method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.Args.get_Timeout [method]: unit -> System.TimeSpan option
WoofWare.NUnitTestRunner.Args.get_Trx [method]: unit -> System.IO.FileInfo option
WoofWare.NUnitTestRunner.Args.LevelOfParallelism [property]: [read-only] int option
WoofWare.NUnitTestRunner.Args.Logging [property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.Args.Parse [static method]: string list -> WoofWare.NUnitTestRunner.Args
WoofWare.NUnitTestRunner.Args.Timeout [property]: [read-only] System.TimeSpan option
WoofWare.NUnitTestRunner.Args.Trx [property]: [read-only] System.IO.FileInfo option
WoofWare.NUnitTestRunner.AssemblyLevelAttributes inherit obj, implements WoofWare.NUnitTestRunner.AssemblyLevelAttributes System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.AssemblyLevelAttributes System.IComparable, System.IComparable, System.Collections.IStructuralComparable
WoofWare.NUnitTestRunner.AssemblyLevelAttributes..ctor [constructor]: (int option, WoofWare.NUnitTestRunner.AssemblyParallelScope WoofWare.NUnitTestRunner.Parallelizable option)
WoofWare.NUnitTestRunner.AssemblyLevelAttributes.get_Parallelism [method]: unit -> int option
@@ -155,6 +170,20 @@ WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberSkipped [method]: string -> u
WoofWare.NUnitTestRunner.ITestProgress.OnTestMemberStart [method]: string -> unit
WoofWare.NUnitTestRunner.LoadContext inherit System.Runtime.Loader.AssemblyLoadContext
WoofWare.NUnitTestRunner.LoadContext..ctor [constructor]: (System.IO.FileInfo, System.IO.DirectoryInfo list, WoofWare.NUnitTestRunner.TestContexts)
WoofWare.NUnitTestRunner.LogLevel inherit obj, implements WoofWare.NUnitTestRunner.LogLevel System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.LogLevel System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
WoofWare.NUnitTestRunner.LogLevel+Tags inherit obj
WoofWare.NUnitTestRunner.LogLevel+Tags.Nothing [static field]: int = 0
WoofWare.NUnitTestRunner.LogLevel+Tags.Verbose [static field]: int = 1
WoofWare.NUnitTestRunner.LogLevel.get_IsNothing [method]: unit -> bool
WoofWare.NUnitTestRunner.LogLevel.get_IsVerbose [method]: unit -> bool
WoofWare.NUnitTestRunner.LogLevel.get_Nothing [static method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.get_Tag [method]: unit -> int
WoofWare.NUnitTestRunner.LogLevel.get_Verbose [static method]: unit -> WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.IsNothing [property]: [read-only] bool
WoofWare.NUnitTestRunner.LogLevel.IsVerbose [property]: [read-only] bool
WoofWare.NUnitTestRunner.LogLevel.Nothing [static property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.LogLevel.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.LogLevel.Verbose [static property]: [read-only] WoofWare.NUnitTestRunner.LogLevel
WoofWare.NUnitTestRunner.Match inherit obj, implements WoofWare.NUnitTestRunner.Match System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.NUnitTestRunner.Match System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
WoofWare.NUnitTestRunner.Match+Contains inherit WoofWare.NUnitTestRunner.Match
WoofWare.NUnitTestRunner.Match+Contains.get_Item [method]: unit -> string
@@ -236,6 +265,10 @@ WoofWare.NUnitTestRunner.SingleTestMethodModule inherit obj
WoofWare.NUnitTestRunner.SingleTestMethodModule.parse [static method]: string list -> System.Reflection.MethodInfo -> System.Reflection.CustomAttributeData list -> (WoofWare.NUnitTestRunner.SingleTestMethod option * System.Reflection.CustomAttributeData list)
WoofWare.NUnitTestRunner.TestContexts inherit obj, implements WoofWare.NUnitTestRunner.TestContexts System.IEquatable, System.Collections.IStructuralEquatable, IDisposable
WoofWare.NUnitTestRunner.TestContexts.Empty [static method]: unit -> WoofWare.NUnitTestRunner.TestContexts
WoofWare.NUnitTestRunner.TestContexts.get_Stderr [method]: unit -> System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.get_Stdout [method]: unit -> System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.Stderr [property]: [read-only] System.IO.TextWriter
WoofWare.NUnitTestRunner.TestContexts.Stdout [property]: [read-only] System.IO.TextWriter
WoofWare.NUnitTestRunner.TestFailure inherit obj, implements WoofWare.NUnitTestRunner.TestFailure System.IEquatable, System.Collections.IStructuralEquatable - union type with 3 cases
WoofWare.NUnitTestRunner.TestFailure+SetUpFailed inherit WoofWare.NUnitTestRunner.TestFailure
WoofWare.NUnitTestRunner.TestFailure+SetUpFailed.get_Item [method]: unit -> WoofWare.NUnitTestRunner.UserMethodFailure
@@ -366,6 +399,7 @@ WoofWare.NUnitTestRunner.TestMemberSuccess.Ok [static property]: [read-only] Woo
WoofWare.NUnitTestRunner.TestMemberSuccess.Tag [property]: [read-only] int
WoofWare.NUnitTestRunner.TestProgress inherit obj
WoofWare.NUnitTestRunner.TestProgress.toStderr [static method]: unit -> WoofWare.NUnitTestRunner.ITestProgress
WoofWare.NUnitTestRunner.TestProgress.toWriter [static method]: System.IO.TextWriter -> WoofWare.NUnitTestRunner.ITestProgress
WoofWare.NUnitTestRunner.TrxCounters inherit obj, implements WoofWare.NUnitTestRunner.TrxCounters System.IEquatable, System.Collections.IStructuralEquatable
WoofWare.NUnitTestRunner.TrxCounters..ctor [constructor]: (System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32, System.UInt32)
WoofWare.NUnitTestRunner.TrxCounters.Aborted [property]: [read-only] System.UInt32

View File

@@ -1,6 +1,7 @@
namespace WoofWare.NUnitTestRunner
open System
open System.IO
/// Represents something which knows how to report progress through a test suite.
/// Note that we don't guarantee anything about parallelism; you must make sure
@@ -24,22 +25,25 @@ type ITestProgress =
/// Methods for constructing specific ITestProgress objects.
[<RequireQualifiedAccess>]
module TestProgress =
/// An ITestProgress which logs to stderr.
let toStderr () : ITestProgress =
/// An ITestProgress which logs to the given writer.
let toWriter (writer : TextWriter) : ITestProgress =
{ new ITestProgress with
member _.OnTestFixtureStart name testCount =
let plural = if testCount = 1 then "" else "s"
Console.Error.WriteLine $"Running test fixture: %s{name} (%i{testCount} test%s{plural} to run)"
writer.WriteLine $"Running test fixture: %s{name} (%i{testCount} test%s{plural} to run)"
member _.OnTestMemberStart name =
Console.Error.WriteLine $"Running test: %s{name}"
writer.WriteLine $"Running test: %s{name}"
member _.OnTestFailed name failure =
Console.Error.WriteLine $"Test failed: %O{failure}"
writer.WriteLine $"Test failed: %O{failure}"
member _.OnTestMemberFinished name =
Console.Error.WriteLine $"Finished test %s{name}"
writer.WriteLine $"Finished test %s{name}"
member _.OnTestMemberSkipped name =
Console.Error.WriteLine $"Skipping test due to filter: %s{name}"
writer.WriteLine $"Skipping test due to filter: %s{name}"
}
/// An ITestProgress which logs to stderr.
let toStderr () : ITestProgress = toWriter Console.Error

View File

@@ -14,7 +14,7 @@
<PackageId>WoofWare.NUnitTestRunner.Lib</PackageId>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarnOn>FS3559</WarnOn>
<WoofWareMyriadPluginVersion>2.1.45</WoofWareMyriadPluginVersion>
<WoofWareMyriadPluginVersion>2.1.52</WoofWareMyriadPluginVersion>
</PropertyGroup>
<ItemGroup>
@@ -29,6 +29,7 @@
<Compile Include="Result.fs" />
<Compile Include="Domain.fs" />
<Compile Include="Filter.fs" />
<Compile Include="Args.fs" />
<Compile Include="ParallelQueue.fs" />
<Compile Include="SingleTestMethod.fs" />
<Compile Include="TestProgress.fs" />
@@ -46,11 +47,11 @@
<EmbeddedResource Include="version.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WoofWare.PrattParser" Version="0.2.1" />
<PackageReference Include="WoofWare.PrattParser" Version="0.2.2" />
<PackageReference Update="FSharp.Core" Version="6.0.0" />
<PackageReference Include="WoofWare.DotnetRuntimeLocator" Version="0.1.9" />
<PackageReference Include="WoofWare.Myriad.Plugins.Attributes" Version="3.1.7" />
<PackageReference Include="Myriad.SDK" Version="0.8.3" />
<PackageReference Include="WoofWare.Myriad.Plugins.Attributes" Version="3.1.8" />
<PackageReference Include="Myriad.SDK" Version="0.8.3" PrivateAssets="all" />
<PackageReference Include="WoofWare.Myriad.Plugins" Version="$(WoofWareMyriadPluginVersion)" PrivateAssets="all" />
</ItemGroup>

View File

@@ -1,5 +1,5 @@
{
"version": "0.14",
"version": "0.16",
"publicReleaseRefSpec": [
"^refs/heads/main$"
],

View File

@@ -0,0 +1,35 @@
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using WoofWare.NUnitTestRunner.StartupHook;
namespace WoofWare.NUnitTestRunner.StartupHook
{
internal class StartupAssemblyLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
public StartupAssemblyLoadContext()
{
_resolver = new AssemblyDependencyResolver(Assembly.GetExecutingAssembly().Location);
}
protected override Assembly Load(AssemblyName assemblyName)
{
var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
}
}
}
// Must be internal and called `StartupHook`
internal class StartupHook
{
public static void Initialize()
{
var loadContext = new StartupAssemblyLoadContext();
var assembly = loadContext.LoadFromAssemblyName(new AssemblyName("WoofWare.NUnitTestRunner.StartupHookLogic"));
assembly.DefinedTypes.First(x => x.Name == "StartupHookLogic").GetDeclaredMethod("DoIt")!.Invoke(null, null);
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj"/>
</ItemGroup>
<ItemGroup>
<Compile Include="StartupHook.cs"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,102 @@
using System.Reflection;
using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Core;
namespace WoofWare.NUnitTestRunner.StartupHookLogic;
public class StartupHookLogic
{
private static void DoIt()
{
// Load test runner lib
var nunitLib = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_LIB");
if (string.IsNullOrEmpty(nunitLib))
{
throw new ArgumentException("WoofWare.NUnitTestRunner hook expects to run with WOOFWARE_NUNIT_LIB set to WoofWare.NUnitTestRunner.Lib.dll");
}
Assembly.LoadFrom(nunitLib);
var startTime = DateTimeOffset.Now;
// Arg parsing
var filterVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_FILTER");
static bool NoFilter(TestFixture f, SingleTestMethod g)
{
return true;
}
FSharpFunc<TestFixture, FSharpFunc<SingleTestMethod, bool>> filter;
if (string.IsNullOrEmpty(filterVar))
{
filter = FuncConvert.FromFunc<TestFixture, SingleTestMethod, bool>(NoFilter);
}
else
{
filter = FilterModule.shouldRun(FilterModule.parse(filterVar));
}
var assy = Assembly.GetEntryAssembly()!;
var attrs = AssemblyLevelAttributesModule.get(assy);
FSharpOption<int> levelOfParallelism;
var parallelismVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_PARALLELISM_LEVEL");
if (string.IsNullOrEmpty(parallelismVar))
{
levelOfParallelism = attrs.Parallelism;
}
else
{
levelOfParallelism = FSharpOption<int>.Some(Int32.Parse(parallelismVar));
}
var testFixtures = assy.ExportedTypes.Select(TestFixtureModule.parse);
using var par =
new ParallelQueue(levelOfParallelism, attrs.Parallelizable, FSharpOption<CancellationToken>.None);
var creationTime = DateTimeOffset.Now;
var timeoutVar = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_TIMEOUT_SECS");
TimeSpan timeout;
if (string.IsNullOrEmpty(timeoutVar))
{
timeout = TimeSpan.FromHours(2.0);
}
else
{
timeout = TimeSpan.FromSeconds(Int32.Parse(timeoutVar));
}
var normalErr = Console.Error;
using var contexts = TestContexts.Empty();
Console.SetOut(contexts.Stdout);
Console.SetError(contexts.Stderr);
var results =
Task.WhenAll(testFixtures.Select(x =>
TestFixtureModule.run(contexts, par, TestProgress.toWriter(normalErr), filter, x)));
if (!results.Wait(timeout))
{
throw new Exception($"Tests failed to terminate within timeout of {timeout}");
}
var sorted =
results.Result.SelectMany(x => x);
var report = BuildTrxReport.build(assy, creationTime, startTime, ListModule.OfSeq(sorted));
var trxFile = Environment.GetEnvironmentVariable("WOOFWARE_NUNIT_GENERATE_TRX");
if (!string.IsNullOrEmpty(trxFile))
{
var contents = TrxReportModule.toXml(report).OuterXml;
var trxPath = new FileInfo(trxFile);
trxPath.Directory!.Create();
File.WriteAllText(trxPath.FullName, contents);
normalErr.WriteLine($"Written TRX file: {trxPath.FullName}");
}
if (report.ResultsSummary.Outcome.Equals(TrxOutcome.Completed))
Environment.Exit(0);
else
Environment.Exit(1);
}
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj"/>
</ItemGroup>
<ItemGroup>
<Compile Include="StartupHookLogic.cs"/>
</ItemGroup>
</Project>

View File

@@ -8,6 +8,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WoofWare.NUnitTestRunner.Li
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "WoofWare.NUnitTestRunner.Test", "WoofWare.NUnitTestRunner\WoofWare.NUnitTestRunner.Test\WoofWare.NUnitTestRunner.Test.fsproj", "{443B01B3-2A8C-45CF-96D6-1D890EEA0533}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHook", "WoofWare.NUnitTestRunner.StartupHook\WoofWare.NUnitTestRunner.StartupHook.csproj", "{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WoofWare.NUnitTestRunner.StartupHookLogic", "WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj", "{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,5 +34,13 @@ Global
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Debug|Any CPU.Build.0 = Debug|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Release|Any CPU.ActiveCfg = Release|Any CPU
{443B01B3-2A8C-45CF-96D6-1D890EEA0533}.Release|Any CPU.Build.0 = Release|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2C73D96-570C-4E3C-B997-707AF8BB0E6A}.Release|Any CPU.Build.0 = Release|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A70627C8-9D19-42C2-AFEB-CFBDDDCE045D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -1,113 +1,22 @@
namespace WoofWare.NUnitTestRunner
open System
open System.Diagnostics
open System.IO
open System.Reflection
open System.Threading.Tasks
open Spectre.Console
// Fix for https://github.com/Smaug123/unofficial-nunit-runner/issues/8
// Set AppContext.BaseDirectory to where the test DLL is.
// (This tells the DLL loader to look next to the test DLL for dependencies.)
type SetBaseDir (testDll : FileInfo) =
let oldBaseDir = AppContext.BaseDirectory
do AppContext.SetData ("APP_CONTEXT_BASE_DIRECTORY", testDll.Directory.FullName)
interface IDisposable with
member _.Dispose () =
AppContext.SetData ("APP_CONTEXT_BASE_DIRECTORY", oldBaseDir)
[<RequireQualifiedAccess>]
type LogLevel =
| Nothing
| Verbose
[<AutoOpen>]
module Patterns =
let (|Key|_|) (start : string) (s : string) : string option =
if s.StartsWith (start + "=", StringComparison.Ordinal) then
s.Substring (start.Length + 1) |> Some
else
None
type Args =
{
Dll : FileInfo
Trx : FileInfo option
Filter : Filter option
Logging : LogLevel
LevelOfParallelism : int option
Timeout : TimeSpan option
}
static member Parse (args : string list) : Args =
match args with
| [] -> failwith "The first arg must be a positional arg, the DLL to test."
| dll :: args ->
let rec go
(trx : FileInfo option)
(filter : Filter option)
(logging : LogLevel option)
(par : int option)
(timeout : TimeSpan option)
(args : string list)
=
match args with
| [] ->
{
Dll = FileInfo dll
Trx = trx
Filter = filter
Logging = logging |> Option.defaultValue LogLevel.Nothing
LevelOfParallelism = par
Timeout = timeout
}
| Key "--filter" filterStr :: rest
| "--filter" :: filterStr :: rest ->
match filter with
| Some _ -> failwith "Two conflicting filters; you can only specify --filter once"
| None -> go trx (Some (Filter.parse filterStr)) logging par timeout rest
| Key "--trx" trxStr :: rest
| "--trx" :: trxStr :: rest ->
match trx with
| Some _ -> failwith "Two conflicting TRX outputs; you can only specify --trx once"
| None -> go (Some (FileInfo trxStr)) filter logging par timeout rest
| Key "--verbose" verboseStr :: rest
| "--verbose" :: verboseStr :: rest ->
match logging with
| Some _ -> failwith "Two conflicting --verbose outputs; you can only specify --verbose once"
| None ->
let verbose =
if Boolean.Parse verboseStr then
LogLevel.Verbose
else
LogLevel.Nothing
go trx filter (Some verbose) par timeout rest
| Key "--parallelism" parStr :: rest
| "--parallelism" :: parStr :: rest ->
match par with
| Some _ -> failwith "Two conflicting --parallelism outputs; you can only specify --parallelism once"
| None -> go trx filter logging (Some (Int32.Parse parStr)) timeout rest
| Key "--timeout-seconds" timeoutStr :: rest
| "--timeout-seconds" :: timeoutStr :: rest ->
match timeout with
| Some _ ->
failwith "Two conflicting --timeout-seconds outputs; you can only specify --timeout-seconds once"
| None -> go trx filter logging par (Some (TimeSpan.FromSeconds (Int32.Parse timeoutStr |> float))) rest
| k :: _rest -> failwith $"Unrecognised arg %s{k}"
go None None None None None args
module Program =
let main argv =
// This is actually transcribed into C# in WoofWare.NUnitTestRunner.StartupHookLogic.
let execute argv =
let startTime = DateTimeOffset.Now
let args = argv |> List.ofArray |> Args.Parse
let filter =
match args.Filter with
| Some filter -> Filter.shouldRun filter
| Some (_, filter) -> Filter.shouldRun filter
| None -> fun _ _ -> true
let stderr =
@@ -125,8 +34,6 @@ module Program =
for d in runtime do
stderr.WriteLine $".NET runtime directory: %s{d.FullName}"
use _ = new SetBaseDir (args.Dll)
use contexts = TestContexts.Empty ()
let ctx = LoadContext (args.Dll, runtime, contexts)
@@ -183,6 +90,52 @@ module Program =
| TrxOutcome.Completed -> 0
| _ -> 1
let main argv =
let args = argv |> List.ofArray |> Args.Parse
let psi = ProcessStartInfo "dotnet"
match args.Trx with
| None -> ()
| Some trx -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_GENERATE_TRX", trx.FullName)
match args.LevelOfParallelism with
| None -> ()
| Some par -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_PARALLELISM_LEVEL", string<int> par)
match args.Filter with
| None -> ()
| Some (filter, _) -> psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_FILTER", filter)
match args.Timeout with
| None -> ()
| Some timeout ->
psi.EnvironmentVariables.Add ("WOOFWARE_NUNIT_TIMEOUT_SECS", string<int> (int<float> timeout.TotalSeconds))
psi.ArgumentList.Add "exec"
psi.ArgumentList.Add args.Dll.FullName
let us = Assembly.GetExecutingAssembly().Location |> FileInfo
let startupHook =
Path.Combine (us.Directory.FullName, "WoofWare.NUnitTestRunner.StartupHook.dll")
psi.EnvironmentVariables.Add ("DOTNET_STARTUP_HOOKS", startupHook)
psi.EnvironmentVariables.Add (
"WOOFWARE_NUNIT_LIB",
Path.Combine (us.Directory.FullName, "WoofWare.NUnitTestRunner.Lib.dll")
)
use proc = new Process ()
proc.StartInfo <- psi
if not (proc.Start ()) then
failwith "Failed to start dotnet"
proc.WaitForExit ()
proc.ExitCode
[<EntryPoint>]
let reallyMain argv =
// Hack to make sure `finally`s get run.

View File

@@ -1,22 +0,0 @@
namespace WoofWare.NUnitTestRunner
[<RequireQualifiedAccess>]
module internal Seq =
let tryMinBy (f : 'a -> 'b) (s : 'a seq) : 'a option =
use enum = s.GetEnumerator ()
if not (enum.MoveNext ()) then
None
else
let mutable answer = enum.Current
let mutable fAnswer = f enum.Current
while enum.MoveNext () do
let fNext = f enum.Current
if fNext < fAnswer then
answer <- enum.Current
Some answer

View File

@@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ApiSurface" Version="4.0.41" />
<PackageReference Include="ApiSurface" Version="4.0.42" />
<PackageReference Include="FsCheck" Version="3.0.0-rc3" />
<PackageReference Include="FsUnit" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />

View File

@@ -2,7 +2,8 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RollForward>Major</RollForward>
<PackAsTool>true</PackAsTool>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Authors>Patrick Stevens</Authors>
@@ -19,7 +20,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Seq.fs" />
<Compile Include="Progress.fs" />
<Compile Include="Program.fs" />
<None Include="..\README.md">
@@ -30,6 +30,8 @@
<ItemGroup>
<ProjectReference Include="..\WoofWare.NUnitTestRunner.Lib\WoofWare.NUnitTestRunner.Lib.fsproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHookLogic\WoofWare.NUnitTestRunner.StartupHookLogic.csproj" />
<ProjectReference Include="..\WoofWare.NUnitTestRunner.StartupHook\WoofWare.NUnitTestRunner.StartupHook.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -56,13 +56,20 @@
doCheck = true;
};
};
devShell = pkgs.mkShell {
buildInputs = [dotnet-sdk];
packages = [
pkgs.alejandra
pkgs.nodePackages.markdown-link-check
pkgs.shellcheck
];
devShells = {
default = pkgs.mkShell {
packages = [
dotnet-sdk
pkgs.alejandra
pkgs.nodePackages.markdown-link-check
pkgs.shellcheck
];
};
net6 = pkgs.mkShell {
packages = [
pkgs.dotnetCorePackages.runtime_6_0
];
};
};
});
}

View File

@@ -3,8 +3,8 @@
{fetchNuGet}: [
(fetchNuGet {
pname = "ApiSurface";
version = "4.0.41";
sha256 = "03kfa5ngmgkik9lc58sp8s9rrh9g40hhgjnrv662ks0d0y2i9i89";
version = "4.0.42";
sha256 = "0azjv64bbbhc4rndbjhcmqxxg1bkf1v3ym3x34zmsbz0lr1hy6pv";
})
(fetchNuGet {
pname = "fantomas";
@@ -153,23 +153,23 @@
})
(fetchNuGet {
pname = "NuGet.Common";
version = "6.10.0";
sha256 = "0nizrnilmlcqbm945293h8q3wfqfchb4xi8g50x4kjn0rbpd1kbh";
version = "6.10.1";
sha256 = "1z69k0j727jcwrxzmvnixdac84lb9706iabqs8mrns8j7kbmw1ns";
})
(fetchNuGet {
pname = "NuGet.Configuration";
version = "6.10.0";
sha256 = "1aqaknaawnqx4mnvx9qw73wvj48jjzv0d78dzwl7m9zjlrl9myhz";
version = "6.10.1";
sha256 = "0qy2bdi3dz6fdw7qbv77fg956idm9d9733j8b1pcrcj9pfayys26";
})
(fetchNuGet {
pname = "NuGet.Frameworks";
version = "6.10.0";
sha256 = "0hrd8y31zx9a0wps49czw0qgbrakb49zn3abfgylc9xrq990zkqk";
version = "6.10.1";
sha256 = "1p8d701fhbqv2r8vqmj948af9xvz2fd3273803cdrjy3a2wykmq1";
})
(fetchNuGet {
pname = "NuGet.Packaging";
version = "6.10.0";
sha256 = "18s53cvrf51lihmaqqdf48p2qi6ky1l48jv0hvbp76cxwdg7rba4";
version = "6.10.1";
sha256 = "0zl8xfzvd1yij2ln6iwy6cz8qfwlbyyqlin872ab5y58ws61a2x2";
})
(fetchNuGet {
pname = "NuGet.Protocol";
@@ -178,8 +178,8 @@
})
(fetchNuGet {
pname = "NuGet.Versioning";
version = "6.10.0";
sha256 = "1x19njx4x0sw9fz8y5fibi15xfsrw5avir0cx0599yd7p3ykik5g";
version = "6.10.1";
sha256 = "0lji7g6abnpmhzlgvni8wlb7l62n4180v3sphp4494wi0gn7ds4c";
})
(fetchNuGet {
pname = "NUnit";
@@ -253,17 +253,17 @@
})
(fetchNuGet {
pname = "WoofWare.Myriad.Plugins";
version = "2.1.45";
sha256 = "1i9s9aq8dqnxyn01sa10dd24y9i7cgv2d0rshmrkvbvbjkcnz9vs";
version = "2.1.52";
sha256 = "03cx16c9zhc2yjldrks4kfh8xx3x757zjhjk98sd7i8q7s6agqyn";
})
(fetchNuGet {
pname = "WoofWare.Myriad.Plugins.Attributes";
version = "3.1.7";
sha256 = "1v1wsrjh7qz2khrlbcysj50yydqc9njj09vs1jglwscjhml1wl1v";
version = "3.1.8";
sha256 = "0xhgl5kkw5hn15ghry3k0w7h4v2d6aww9dmpb7j49aims1r6c76c";
})
(fetchNuGet {
pname = "WoofWare.PrattParser";
version = "0.2.1";
sha256 = "1cb9496fbbrdc40dirjmc7ax02ghr27ahqq5hpk96rdzyaang9hg";
version = "0.2.2";
sha256 = "0cgrmd1kc3k224lsjhy5npalwg6kpqd8nx78szi1yq67kyb0farq";
})
]