diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 41785ce..8ca7b8d 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,16 +3,18 @@
"isRoot": true,
"tools": {
"paket": {
- "version": "8.0.0",
+ "version": "9.0.2",
"commands": [
"paket"
- ]
+ ],
+ "rollForward": false
},
"fantomas": {
- "version": "6.2.3",
+ "version": "7.0.1",
"commands": [
"fantomas"
- ]
+ ],
+ "rollForward": false
}
}
}
\ No newline at end of file
diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets
index 4deb15b..17aeb63 100644
--- a/.paket/Paket.Restore.targets
+++ b/.paket/Paket.Restore.targets
@@ -1,322 +1,330 @@
-
-
-
-
-
- $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
-
- $(MSBuildVersion)
- 15.0.0
- false
- true
-
- true
- $(MSBuildThisFileDirectory)
- $(MSBuildThisFileDirectory)..\
- $(PaketRootPath)paket-files\paket.restore.cached
- $(PaketRootPath)paket.lock
- classic
- proj
- assembly
- native
- /Library/Frameworks/Mono.framework/Commands/mono
- mono
-
-
- $(PaketRootPath)paket.bootstrapper.exe
- $(PaketToolsPath)paket.bootstrapper.exe
- $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\
-
- "$(PaketBootStrapperExePath)"
- $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
-
-
-
-
- true
- true
-
-
- True
-
-
- False
-
- $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/'))
-
-
-
-
-
-
-
-
- $(PaketRootPath)paket
- $(PaketToolsPath)paket
-
-
-
-
-
- $(PaketRootPath)paket.exe
- $(PaketToolsPath)paket.exe
-
-
-
-
-
- <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json"))
- <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"'))
- <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false
-
-
-
-
-
-
-
-
-
-
- <_PaketCommand>dotnet paket
-
-
-
-
-
- $(PaketToolsPath)paket
- $(PaketBootStrapperExeDir)paket
-
-
- paket
-
-
-
-
- <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
- <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- $(NoWarn);NU1603;NU1604;NU1605;NU1608
- false
- true
-
-
-
-
-
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)'))
-
-
-
-
-
-
- $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``))
- $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``))
-
-
-
-
- %(PaketRestoreCachedKeyValue.Value)
- %(PaketRestoreCachedKeyValue.Value)
-
-
-
-
- true
- false
- true
-
-
-
+
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+
+ $(MSBuildVersion)
+ 15.0.0
+ false
+ true
+
+ true
+ $(MSBuildThisFileDirectory)
+ $(MSBuildThisFileDirectory)..\
+ $(PaketRootPath)paket-files\paket.restore.cached
+ $(PaketRootPath)paket.lock
+ classic
+ proj
+ assembly
+ native
+ /Library/Frameworks/Mono.framework/Commands/mono
+ mono
+
+
+ $(PaketRootPath)paket.bootstrapper.exe
+ $(PaketToolsPath)paket.bootstrapper.exe
+ $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\
+
+ "$(PaketBootStrapperExePath)"
+ $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
+
+
+
+
+ true
+ true
+
+
+ True
+
+
+ False
+
+ $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/'))
+
+
+
+
+
+
+
+
+ $(PaketRootPath)paket
+ $(PaketToolsPath)paket
+
+
+
+
+
+ $(PaketRootPath)paket.exe
+ $(PaketToolsPath)paket.exe
+
+
+
+
+
+ <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json"))
+ <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"'))
+ <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false
+
+
+
+
+
+
+
+
+
+
+ <_PaketCommand>dotnet paket
+
+
+
+
+
+ $(PaketToolsPath)paket
+ $(PaketBootStrapperExeDir)paket
+
+
+ paket
+
+
+
+
+ <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)"
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
+ <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(NoWarn);NU1603;NU1604;NU1605;NU1608
+ false
+ true
+
+
+
+
+
+
+
+
+ $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)'))
+
+
+
+
+
+
+ $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``))
+ $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``))
+
+
+
+
+ %(PaketRestoreCachedKeyValue.Value)
+ %(PaketRestoreCachedKeyValue.Value)
+
+
+
+
+ true
+ false
+ true
+
+
+
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached
-
- $(MSBuildProjectFullPath).paket.references
-
- $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references
-
- $(MSBuildProjectDirectory)\paket.references
-
- false
- true
- true
- references-file-or-cache-not-found
-
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)'))
- $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)'))
- references-file
- false
-
-
-
-
- false
-
-
-
-
- true
- target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths)
-
-
-
-
-
-
-
-
-
-
- false
- true
-
-
-
-
-
-
-
-
-
-
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7])
-
-
- %(PaketReferencesFileLinesInfo.PackageVersion)
- All
- runtime
- $(ExcludeAssets);contentFiles
- $(ExcludeAssets);build;buildMultitargeting;buildTransitive
- true
- true
-
-
-
-
- $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools
-
-
-
-
-
-
-
-
- $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0])
- $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1])
-
-
- %(PaketCliToolFileLinesInfo.PackageVersion)
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached
+
+ $(MSBuildProjectFullPath).paket.references
+
+ $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references
+
+ $(MSBuildProjectDirectory)\paket.references
+
+ false
+ true
+ true
+ references-file-or-cache-not-found
+
+
+
+
+ $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)'))
+ $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)'))
+ references-file
+ false
+
+
+
+
+ false
+
+
+
+
+ true
+ target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths)
+
+
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[2])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[8])
+
+
+ %(PaketReferencesFileLinesInfo.PackageVersion)
+ All
+ runtime
+ $(ExcludeAssets);contentFiles
+ $(ExcludeAssets);build;buildMultitargeting;buildTransitive
+ %(PaketReferencesFileLinesInfo.Aliases)
+ true
+ true
+
+
+
+
+ %(PaketReferencesFileLinesInfo.PackageVersion)
+
+
+
+
+ $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools
+
+
+
+
+
+
+
+
+ $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0])
+ $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1])
+
+
+ %(PaketCliToolFileLinesInfo.PackageVersion)
+
+
+
+
-
-
-
-
- false
-
-
-
-
-
- <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/>
-
-
-
-
-
- $(MSBuildProjectDirectory)/$(MSBuildProjectFile)
- true
- false
- true
- false
- true
- false
- true
- false
- true
- false
- true
- $(PaketIntermediateOutputPath)\$(Configuration)
- $(PaketIntermediateOutputPath)
-
-
-
- <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/>
-
-
-
-
-
-
-
-
-
+
+
+
+
+ false
+
+
+
+
+
+ <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/>
+
+
+
+
+
+ $(MSBuildProjectDirectory)/$(MSBuildProjectFile)
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ $(PaketIntermediateOutputPath)\$(Configuration)
+ $(PaketIntermediateOutputPath)
+
+
+
+ <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/>
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/paket.lock b/paket.lock
index 0bb17f6..eb89c7b 100644
--- a/paket.lock
+++ b/paket.lock
@@ -2,30 +2,47 @@ RESTRICTION: || (== net6.0) (== net7.0) (== net8.0) (== netstandard2.0) (== nets
NUGET
remote: https://api.nuget.org/v3/index.json
FSharp.Core (6.0.7)
- FsUnit (5.6)
+ FsUnit (7.0.1)
FSharp.Core (>= 5.0.2)
- NUnit (>= 3.14)
- Microsoft.CodeCoverage (17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- Microsoft.NET.Test.Sdk (17.8)
- Microsoft.CodeCoverage (>= 17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- Microsoft.TestPlatform.TestHost (>= 17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- Microsoft.NETCore.Platforms (7.0.4)
- Microsoft.TestPlatform.ObjectModel (17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- NuGet.Frameworks (>= 6.5)
+ NUnit (>= 4.0.1)
+ Microsoft.ApplicationInsights (2.23) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Diagnostics.DiagnosticSource (>= 5.0)
+ Microsoft.CodeCoverage (17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.NET.Test.Sdk (17.13)
+ Microsoft.CodeCoverage (>= 17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.TestPlatform.TestHost (>= 17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Extensions.Telemetry (1.6.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.ApplicationInsights (>= 2.22)
+ Microsoft.Testing.Platform (>= 1.6.3)
+ Microsoft.Testing.Extensions.TrxReport.Abstractions (1.6.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Platform (>= 1.6.3)
+ Microsoft.Testing.Extensions.VSTestBridge (1.6.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Extensions.Telemetry (>= 1.6.3)
+ Microsoft.Testing.Extensions.TrxReport.Abstractions (>= 1.6.3)
+ Microsoft.Testing.Platform (>= 1.6.3)
+ Microsoft.TestPlatform.ObjectModel (>= 17.13)
+ Microsoft.Testing.Platform (1.6.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Platform.MSBuild (1.6.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Platform (>= 1.6.3)
+ Microsoft.TestPlatform.ObjectModel (17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
System.Reflection.Metadata (>= 1.6)
- Microsoft.TestPlatform.TestHost (17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- Microsoft.TestPlatform.ObjectModel (>= 17.8) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.TestPlatform.TestHost (17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.TestPlatform.ObjectModel (>= 17.13) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
Newtonsoft.Json (>= 13.0.1) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- NETStandard.Library (2.0.3)
- Microsoft.NETCore.Platforms (>= 1.1)
Newtonsoft.Json (13.0.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- NuGet.Frameworks (6.7) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- NUnit (3.14)
- NETStandard.Library (>= 2.0)
- NUnit.Analyzers (3.9)
- NUnit3TestAdapter (4.5)
- System.Collections.Immutable (8.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (== net6.0) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< net6.0)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (&& (== net8.0) (< net7.0)) (== netstandard2.0) (== netstandard2.1)
- System.Reflection.Metadata (8.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
- System.Collections.Immutable (>= 8.0)
- System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (== net6.0) (&& (== net7.0) (== netstandard2.0)) (&& (== net7.0) (== netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< net6.0)) (&& (== net8.0) (== netstandard2.0)) (&& (== net8.0) (== netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< net6.0)) (&& (== net8.0) (< net7.0)) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net6.0)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ NUnit (4.3.2)
+ NUnit.Analyzers (4.7)
+ NUnit3TestAdapter (5.0)
+ Microsoft.Testing.Extensions.VSTestBridge (>= 1.5.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ Microsoft.Testing.Platform.MSBuild (>= 1.5.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Collections.Immutable (9.0.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Memory (>= 4.5.5) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (>= net462)) (== netstandard2.0) (== netstandard2.1)
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (>= net462)) (== netstandard2.0) (== netstandard2.1)
+ System.Diagnostics.DiagnosticSource (9.0.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= net462)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Memory (>= 4.5.5) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (>= net462)) (== netstandard2.0) (== netstandard2.1)
+ System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (>= net462)) (== netstandard2.0) (== netstandard2.1)
+ System.Memory (4.6.3) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (== netstandard2.0)) (&& (== net8.0) (== netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Reflection.Metadata (9.0.3) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
+ System.Collections.Immutable (>= 9.0.3)
+ System.Memory (>= 4.5.5) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (>= net462)) (== netstandard2.0) (== netstandard2.1)
+ System.Runtime.CompilerServices.Unsafe (6.1.2) - restriction: || (== net6.0) (== net7.0) (&& (== net8.0) (== netstandard2.0)) (&& (== net8.0) (== netstandard2.1)) (&& (== net8.0) (>= net462)) (&& (== netstandard2.0) (>= netcoreapp3.1)) (&& (== netstandard2.1) (>= netcoreapp3.1))
diff --git a/src/Fli.Tests/ExecContext/ExecCommandConfigureUnixTests.fs b/src/Fli.Tests/ExecContext/ExecCommandConfigureUnixTests.fs
index bd173d0..855ab2c 100644
--- a/src/Fli.Tests/ExecContext/ExecCommandConfigureUnixTests.fs
+++ b/src/Fli.Tests/ExecContext/ExecCommandConfigureUnixTests.fs
@@ -10,10 +10,7 @@ open System.Text
[]
[]
let ``Check FileName in ProcessStartInfo Exec program`` () =
- cli { Exec "bash" }
- |> Command.buildProcess
- |> _.FileName
- |> should equal "bash"
+ cli { Exec "bash" } |> Command.buildProcess |> _.FileName |> should equal "bash"
[]
[]
@@ -120,4 +117,4 @@ let ``Check all possible values in ProcessStartInfo`` () =
config.Environment.Contains(KeyValuePair("Fli", "test")) |> should be True
config.Environment.Contains(KeyValuePair("Fli.Test", "test")) |> should be True
config.StandardOutputEncoding |> should equal Encoding.UTF8
- config.StandardErrorEncoding |> should equal Encoding.UTF8
\ No newline at end of file
+ config.StandardErrorEncoding |> should equal Encoding.UTF8
diff --git a/src/Fli.Tests/ExecContext/ExecCommandConfigureWindowsTests.fs b/src/Fli.Tests/ExecContext/ExecCommandConfigureWindowsTests.fs
index 809ffd6..20a63c4 100644
--- a/src/Fli.Tests/ExecContext/ExecCommandConfigureWindowsTests.fs
+++ b/src/Fli.Tests/ExecContext/ExecCommandConfigureWindowsTests.fs
@@ -26,6 +26,25 @@ let ``Check Arguments in ProcessStartInfo with Arguments`` () =
|> _.Arguments
|> should equal "-c echo Hello World!"
+#if NET
+[]
+[]
+let ``Check Arguments in ProcessStartInfo with ArgumentList`` () =
+ cli {
+ Exec "cmd.exe"
+ Arguments [ "-c"; "echo Hello World!" ]
+ }
+ |> Command.buildProcess
+ |> _.ArgumentList
+ :> seq<_>
+ |> should
+ equal
+ (seq {
+ "-c"
+ "echo Hello World!"
+ })
+#endif
+
[]
[]
let ``Check WorkingDirectory in ProcessStartInfo with WorkingDirectory`` () =
@@ -153,4 +172,4 @@ let ``Check all possible values in ProcessStartInfo for windows`` () =
config.Environment.Contains(KeyValuePair("Fli.Test", "test")) |> should be True
config.StandardOutputEncoding |> should equal Encoding.UTF8
config.StandardErrorEncoding |> should equal Encoding.UTF8
- config.WindowStyle |> should equal Diagnostics.ProcessWindowStyle.Normal
\ No newline at end of file
+ config.WindowStyle |> should equal Diagnostics.ProcessWindowStyle.Normal
diff --git a/src/Fli.Tests/ExecContext/ExecCommandExecuteUnixTests.fs b/src/Fli.Tests/ExecContext/ExecCommandExecuteUnixTests.fs
index 250cd25..7534ab3 100644
--- a/src/Fli.Tests/ExecContext/ExecCommandExecuteUnixTests.fs
+++ b/src/Fli.Tests/ExecContext/ExecCommandExecuteUnixTests.fs
@@ -92,4 +92,4 @@ let ``Passing data to a progrma on stdin`` () =
}
|> Command.execute
|> Output.toText
- |> should equal "Test"
\ No newline at end of file
+ |> should equal "Test"
diff --git a/src/Fli.Tests/ExecContext/ExecCommandExecuteWindowsTests.fs b/src/Fli.Tests/ExecContext/ExecCommandExecuteWindowsTests.fs
index ae59428..7b42d0f 100644
--- a/src/Fli.Tests/ExecContext/ExecCommandExecuteWindowsTests.fs
+++ b/src/Fli.Tests/ExecContext/ExecCommandExecuteWindowsTests.fs
@@ -18,6 +18,17 @@ let ``Hello World with executing program`` () =
|> Output.toText
|> should equal "Hello World!"
+[]
+[]
+let ``Print "Test" properly with ArgumentList`` () =
+ cli {
+ Exec "pwsh.exe"
+ Arguments [ "/C"; "Write-Host \"Test\"" ]
+ }
+ |> Command.execute
+ |> Output.toText
+ |> should equal "Test"
+
[]
[]
let ``Get process Id`` () =
@@ -110,4 +121,4 @@ let ``Hello World with executing program throws exception with unknown Verb`` ()
|> ignore
with :? ArgumentException as ex ->
ex.Message
- |> should equal ("Unknown verb 'print'. Possible verbs on 'cmd.exe': open, runas, runasuser")
\ No newline at end of file
+ |> should equal ("Unknown verb 'print'. Possible verbs on 'cmd.exe': open, runas, runasuser")
diff --git a/src/Fli.Tests/ExecContext/ExecConfigTests.fs b/src/Fli.Tests/ExecContext/ExecConfigTests.fs
index 48bfbc8..ff572d0 100644
--- a/src/Fli.Tests/ExecContext/ExecConfigTests.fs
+++ b/src/Fli.Tests/ExecContext/ExecConfigTests.fs
@@ -16,7 +16,7 @@ let ``Check arguments config for executing program`` () =
Arguments "echo Hello World!"
}
|> _.config.Arguments
- |> should equal (Some "echo Hello World!")
+ |> should equal (Some(Arguments(Some "echo Hello World!")))
[]
let ``Check arguments list config for executing program`` () =
@@ -25,7 +25,7 @@ let ``Check arguments list config for executing program`` () =
Arguments [ "echo"; "Hello World!" ]
}
|> _.config.Arguments
- |> should equal (Some "echo Hello World!")
+ |> should equal (Some(ArgumentList(Some [| "echo"; "Hello World!" |])))
[]
let ``Check Input config for executing program`` () =
@@ -51,15 +51,17 @@ let ``Empty string in Output ends up as None`` () =
Exec "cmd.exe"
Output ""
}
- |> _.config.Output |> should be (ofCase <@ None @>)
+ |> _.config.Output
+ |> should be (ofCase <@ None @>)
[]
let ``Nullable file path in Output ends up as None`` () =
cli {
Exec "cmd.exe"
- Output (File(null))
+ Output(File(null))
}
- |> _.config.Output |> should be (ofCase <@ None @>)
+ |> _.config.Output
+ |> should be (ofCase <@ None @>)
[]
let ``Check working directory config for executing program`` () =
@@ -74,7 +76,8 @@ let ``Check working directory config for executing program`` () =
let ``Check WindowStyle config for executing program`` () =
cli {
Exec "cmd.exe"
- WindowStyle Normal }
+ WindowStyle Normal
+ }
|> _.config.WindowStyle
|> should equal (Some Normal)
diff --git a/src/Fli.Tests/ShellContext/ShellCommandConfigureUnixTests.fs b/src/Fli.Tests/ShellContext/ShellCommandConfigureUnixTests.fs
index 303cff6..e586e7d 100644
--- a/src/Fli.Tests/ShellContext/ShellCommandConfigureUnixTests.fs
+++ b/src/Fli.Tests/ShellContext/ShellCommandConfigureUnixTests.fs
@@ -10,10 +10,7 @@ open System.Text
[]
[]
let ``Check FileName in ProcessStartInfo with CMD Shell`` () =
- cli { Shell BASH }
- |> Command.buildProcess
- |> _.FileName
- |> should equal "bash"
+ cli { Shell BASH } |> Command.buildProcess |> _.FileName |> should equal "bash"
[]
[]
diff --git a/src/Fli.Tests/ShellContext/ShellConfigTests.fs b/src/Fli.Tests/ShellContext/ShellConfigTests.fs
index 4ea27c0..c61fa47 100644
--- a/src/Fli.Tests/ShellContext/ShellConfigTests.fs
+++ b/src/Fli.Tests/ShellContext/ShellConfigTests.fs
@@ -42,15 +42,17 @@ let ``Empty string in Output ends up as None`` () =
Shell CMD
Output ""
}
- |> _.config.Output |> should be (ofCase <@ None @>)
+ |> _.config.Output
+ |> should be (ofCase <@ None @>)
[]
let ``Nullable file path in Output ends up as None`` () =
cli {
Shell CMD
- Output (File(null))
+ Output(File(null))
}
- |> _.config.Output |> should be (ofCase <@ None @>)
+ |> _.config.Output
+ |> should be (ofCase <@ None @>)
[]
let ``Check WorkingDirectory config`` () =
diff --git a/src/Fli/CE.fs b/src/Fli/CE.fs
index e06273d..3b98d9e 100644
--- a/src/Fli/CE.fs
+++ b/src/Fli/CE.fs
@@ -38,8 +38,7 @@ module CE =
/// Extra `Output` that is being executed immediately after getting output from execution.
[]
- member _.Output(context: ICommandContext, output: Outputs) =
- Cli.output output context.Context
+ member _.Output(context: ICommandContext, output: Outputs) = Cli.output output context.Context
/// Extra `Output` that is being executed immediately after getting output from execution.
[]
@@ -99,8 +98,8 @@ module CE =
member _.Arguments(context: ICommandContext, arguments) =
let matchArguments arguments =
match box arguments with
- | :? string as s -> s
- | :? seq as s -> s |> Seq.map string |> String.concat " "
+ | :? string as s -> s |> Some |> Arguments
+ | :? seq as s -> s |> Array.ofSeq |> Some |> ArgumentList
| _ -> failwith "Cannot convert arguments to a string!"
Program.arguments (matchArguments arguments) context.Context
@@ -111,8 +110,7 @@ module CE =
/// Extra `Output` that is being executed immediately after getting output from execution.
[]
- member _.Output(context: ICommandContext, output: Outputs) =
- Program.output output context.Context
+ member _.Output(context: ICommandContext, output: Outputs) = Program.output output context.Context
/// Extra `Output` that is being executed immediately after getting output from execution.
[]
diff --git a/src/Fli/Command.fs b/src/Fli/Command.fs
index d760737..dbbdd45 100644
--- a/src/Fli/Command.fs
+++ b/src/Fli/Command.fs
@@ -29,16 +29,27 @@ module Command =
| ZSH -> "zsh", "-c"
| CUSTOM(shell, flag) -> shell, flag
- let private createProcess executable argumentString openDefault =
- ProcessStartInfo(
- FileName = executable,
- Arguments = argumentString,
- CreateNoWindow = true,
- UseShellExecute = openDefault,
- RedirectStandardInput = not openDefault,
- RedirectStandardOutput = not openDefault,
- RedirectStandardError = not openDefault
- )
+ let private getArguments arguments executable =
+ match arguments with
+ | Some(Arguments a) ->
+ let args = (a |> Option.defaultValue "")
+ ProcessStartInfo(executable, args)
+ | Some(ArgumentList list) ->
+#if NET
+ ProcessStartInfo(executable, (list |> Option.defaultValue [||]))
+#else
+ ProcessStartInfo(executable, ArgumentList(list).toString())
+#endif
+ | None -> ProcessStartInfo(executable, "")
+
+ let private createProcess executable arguments openDefault =
+ let processInfo = getArguments arguments executable
+ processInfo.CreateNoWindow <- true
+ processInfo.UseShellExecute <- openDefault
+ processInfo.RedirectStandardInput <- not openDefault
+ processInfo.RedirectStandardOutput <- not openDefault
+ processInfo.RedirectStandardError <- not openDefault
+ processInfo
let private trim (s: string) = s.TrimEnd([| '\r'; '\n' |])
@@ -200,12 +211,7 @@ module Command =
cts.Token
let private quoteBashCommand (context: ShellContext) =
- let noQuoteNeeded = [|
- Shells.CMD
- Shells.PWSH
- Shells.PS
- Shells.WSL
- |]
+ let noQuoteNeeded = [| Shells.CMD; Shells.PWSH; Shells.PS; Shells.WSL |]
match Array.contains context.config.Shell noQuoteNeeded with
| true -> context.config.Command |> Option.defaultValue ""
@@ -222,8 +228,9 @@ module Command =
static member internal buildProcess(context: ShellContext) =
let proc, flag = (context.config.Shell, context.config.Input) ||> shellToProcess
let command = context |> quoteBashCommand
+ let args = Arguments(Some $"""{flag} {command}""")
- (createProcess proc $"""{flag} {command}""" false)
+ (createProcess proc (Some args) false)
.With(WorkingDirectory = (context.config.WorkingDirectory |> Option.defaultValue ""))
.With(StandardOutputEncoding = (context.config.Encoding |> Option.defaultValue null))
.With(StandardErrorEncoding = (context.config.Encoding |> Option.defaultValue null))
@@ -233,14 +240,12 @@ module Command =
static member internal buildProcess(context: ExecContext) =
checkVerb context.config.Verb context.config.Program
- let arguments = (context.config.Arguments |> Option.defaultValue "")
-
- let openDefault =
- context.config.Arguments.IsNone
+ let openDefault =
+ context.config.Arguments.IsNone
&& context.config.EnvironmentVariables.IsNone
&& context.config.Input.IsNone
- (createProcess context.config.Program arguments openDefault)
+ (createProcess context.config.Program context.config.Arguments openDefault)
.With(Verb = (context.config.Verb |> Option.defaultValue null))
.With(WorkingDirectory = (context.config.WorkingDirectory |> Option.defaultValue ""))
.With(UserName = (context.config.UserName |> Option.defaultValue ""))
@@ -258,7 +263,13 @@ module Command =
/// Stringifies executable + arguments.
static member toString(context: ExecContext) =
- $"""{context.config.Program} {context.config.Arguments |> Option.defaultValue ""}"""
+ let args =
+ if context.config.Arguments.IsSome then
+ context.config.Arguments.Value.toString ()
+ else
+ ""
+
+ $"""{context.config.Program} {args}"""
/// Executes the given context as a new process.
static member execute(context: ShellContext) =
diff --git a/src/Fli/Domain.fs b/src/Fli/Domain.fs
index 6666626..b1a081d 100644
--- a/src/Fli/Domain.fs
+++ b/src/Fli/Domain.fs
@@ -43,7 +43,7 @@ module Domain =
type ExecConfig =
{ Program: string
- Arguments: string option
+ Arguments: Arguments option
Input: string option
Output: Outputs option
WorkingDirectory: string option
@@ -57,6 +57,23 @@ module Domain =
and Credentials = Credentials of Domain: string * UserName: string * Password: string
+ and Arguments =
+ | Arguments of string option
+ | ArgumentList of string array option
+
+ member x.toString() =
+ match x with
+ | Arguments(Some s) -> s
+ | ArgumentList(Some s) ->
+ let escapeString (str: string) =
+ if str.Contains("\"") then
+ str.Replace("\"", "\"\"") |> fun s -> $"\"{s}\""
+ else
+ str
+
+ s |> Seq.map escapeString |> String.concat " "
+ | _ -> ""
+
type Config =
{ ShellConfig: ShellConfig
ExecConfig: ExecConfig }
diff --git a/src/Fli/Dsl.fs b/src/Fli/Dsl.fs
index f12f9d2..ed5bd56 100644
--- a/src/Fli/Dsl.fs
+++ b/src/Fli/Dsl.fs
@@ -24,7 +24,8 @@ module Cli =
| File path -> path |> toOptionWithDefault output
| _ -> Some output
- { context with config.Output = outputsOption }
+ { context with
+ config.Output = outputsOption }
let workingDirectory (workingDirectory: string) (context: ShellContext) =
{ context with
@@ -58,7 +59,7 @@ module Program =
{ config.ExecConfig with
Program = program } }
- let arguments (arguments: string) (context: ExecContext) =
+ let arguments (arguments: Arguments) (context: ExecContext) =
{ context with
config.Arguments = Some arguments }
@@ -72,7 +73,8 @@ module Program =
| File path -> path |> toOptionWithDefault output
| _ -> Some output
- { context with config.Output = outputsOption }
+ { context with
+ config.Output = outputsOption }
let workingDirectory (workingDirectory: string) (context: ExecContext) =
{ context with
diff --git a/src/Fli/Fli.fsproj b/src/Fli/Fli.fsproj
index 572e3f8..c7f9b49 100644
--- a/src/Fli/Fli.fsproj
+++ b/src/Fli/Fli.fsproj
@@ -3,7 +3,7 @@
Library
Library
- netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0
+ netstandard2.0;netstandard2.1;net8.0
false
Debug;Release
1.111.10.0
diff --git a/src/Fli/Helpers.fs b/src/Fli/Helpers.fs
index 9da4502..ff1a7ee 100644
--- a/src/Fli/Helpers.fs
+++ b/src/Fli/Helpers.fs
@@ -35,4 +35,4 @@ module Helpers =
match value with
| null
| "" -> None
- | _ -> Some defaultValue
\ No newline at end of file
+ | _ -> Some defaultValue