From 1d1321f721d0ac58fdbc92c4bf752e38c5f8540e Mon Sep 17 00:00:00 2001 From: Tuomas Hietanen Date: Fri, 2 May 2025 20:29:41 +0100 Subject: [PATCH 1/2] Updates to F# 8 and .NET 8.0 --- .github/workflows/dotnetcore.yml | 11 +- build.fsx | 3 +- global.json | 6 -- paket.dependencies | 14 +-- paket.lock | 102 ++++++++++-------- .../FSharp.Configuration.DesignTime.fsproj | 4 +- .../FSharp.Configuration.Runtime.fs | 2 + .../FSharp.Configuration.Runtime.fsproj | 8 +- .../TypeProviders.Helper.fs | 96 ++++++++++------- .../YamlConfigProvider.Runtime.fs | 31 +++++- .../paket.template | 5 + .../FSharp.Configuration.Tests.fsproj | 5 +- tests/FSharp.Configuration.Tests/app.config | 30 +----- 13 files changed, 180 insertions(+), 137 deletions(-) delete mode 100644 global.json diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index b91d870..b9b60e8 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -15,15 +15,20 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - dotnet: [6.0.400] + dotnet6: [6.0.400] + dotnet8: [8.0.400] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 - - name: Setup .NET Core + - name: Setup .NET Core 6 (for build) uses: actions/setup-dotnet@v1 with: - dotnet-version: ${{ matrix.dotnet }} + dotnet-version: ${{ matrix.dotnet6 }} + - name: Setup .NET Core 8 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ matrix.dotnet8 }} - name: Install local tools run: dotnet tool restore - name: Paket Restore diff --git a/build.fsx b/build.fsx index e89c0e7..a6c0722 100644 --- a/build.fsx +++ b/build.fsx @@ -108,7 +108,8 @@ Target.create "RunTests" (fun _ -> { r with WorkingDirectory = "tests/FSharp.Configuration.Tests/" }) - "run" + //"run --framework net48" + "run --framework net8.0" "") Target.create "NuGet" (fun _ -> diff --git a/global.json b/global.json deleted file mode 100644 index 510ef93..0000000 --- a/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sdk": { - "version": "6.0.400", - "rollForward": "minor" - } -} \ No newline at end of file diff --git a/paket.dependencies b/paket.dependencies index d6c780d..15436c9 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -1,10 +1,11 @@ +version 8.1.0 source https://api.nuget.org/v3/index.json -framework: net6.0, netstandard2.0 +storage: none nuget YamlDotNet -nuget FSharp.Core 4.7.2 +nuget FSharp.Core 8.0.301 -nuget System.Configuration.ConfigurationManager +nuget System.Configuration.ConfigurationManager 9.0.4 nuget NETStandard.Library.NETFramework github fsprojects/FSharp.TypeProviders.SDK src/ProvidedTypes.fs @@ -13,9 +14,8 @@ github fsprojects/FSharp.TypeProviders.SDK tests/ProvidedTypesTesting.fs group Test source https://api.nuget.org/v3/index.json - framework: net6.0 nuget FSharp.Core redirects: force - nuget Expecto - nuget System.Configuration.ConfigurationManager redirects: force - nuget System.Resources.Extensions \ No newline at end of file + nuget Expecto 9.0.4 + nuget System.Configuration.ConfigurationManager 9.0.4 redirects: force + nuget System.Resources.Extensions diff --git a/paket.lock b/paket.lock index 17c7454..968a770 100644 --- a/paket.lock +++ b/paket.lock @@ -1,57 +1,65 @@ -RESTRICTION: || (== net6.0) (== netstandard2.0) +STORAGE: NONE NUGET remote: https://api.nuget.org/v3/index.json - FSharp.Core (4.7.2) - Microsoft.Win32.SystemEvents (6.0.1) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) + FSharp.Core (8.0.301) + Microsoft.NETCore.Platforms (7.0.4) - restriction: >= net461 + NETStandard.Library (2.0.3) - restriction: >= net461 + Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (>= net45) (< netstandard1.3)) (&& (< net45) (>= netstandard1.1) (< netstandard1.2) (< win8)) (&& (< net45) (>= netstandard1.2) (< netstandard1.3) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.3) (< netstandard1.4) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.4) (< netstandard1.5) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.5) (< netstandard1.6) (< win8) (< wpa81)) (&& (< net45) (>= netstandard1.6) (< netstandard2.0) (< win8) (< wpa81)) (&& (< net45) (>= netstandard2.0)) (&& (>= net46) (< netstandard1.4)) (>= net461) (>= netcoreapp2.0) (&& (>= netstandard1.0) (< portable-net45+win8+wpa81)) (&& (< netstandard1.0) (>= portable-net45+win8) (< win8)) (&& (< netstandard1.0) (< portable-net45+win8) (>= portable-net45+win8+wpa81)) (&& (< netstandard1.0) (>= portable-net45+win8+wp8+wpa81) (< portable-net45+win8+wpa81)) (&& (< netstandard1.0) (>= win8)) (&& (< netstandard1.3) (< win8) (>= wpa81)) (&& (< netstandard1.5) (>= uap10.0)) (>= uap10.1) (>= wp8) NETStandard.Library.NETFramework (2.0.0-preview2-25405-01) - System.Buffers (4.5.1) - restriction: == netstandard2.0 - System.Configuration.ConfigurationManager (6.0.1) - System.Security.Cryptography.ProtectedData (>= 6.0) - System.Security.Permissions (>= 6.0) - System.Drawing.Common (6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) - Microsoft.Win32.SystemEvents (>= 6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) - System.Memory (4.5.5) - restriction: == netstandard2.0 - System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (== netstandard2.0) - System.Numerics.Vectors (>= 4.4) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (== netstandard2.0) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (== netstandard2.0) - System.Numerics.Vectors (4.5) - restriction: == netstandard2.0 - System.Runtime.CompilerServices.Unsafe (6.0) - restriction: == netstandard2.0 - System.Security.AccessControl (6.0) - System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) - System.Security.Cryptography.ProtectedData (6.0) - System.Memory (>= 4.5.4) - restriction: == netstandard2.0 - System.Security.Permissions (6.0) - System.Security.AccessControl (>= 6.0) - System.Windows.Extensions (>= 6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) - System.Security.Principal.Windows (5.0) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) - System.Windows.Extensions (6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) - System.Drawing.Common (>= 6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= netcoreapp3.1)) + Microsoft.NETCore.Platforms (>= 2.0.0-preview2-25405-01) - restriction: >= net461 + NETStandard.Library (>= 2.0.0-preview2-25401-01) - restriction: >= net461 + System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) + System.Configuration.ConfigurationManager (9.0.4) + System.Diagnostics.EventLog (>= 9.0.4) - restriction: >= net8.0 + System.Security.Cryptography.ProtectedData (>= 9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Diagnostics.EventLog (9.0.4) - restriction: >= net8.0 + System.Memory (4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) + System.Buffers (>= 4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (< uap10.1) (>= wpa81)) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) + System.Numerics.Vectors (>= 4.4) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) + System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) + System.Numerics.Vectors (4.5) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) + System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= uap10.1)) + System.Security.Cryptography.ProtectedData (9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Memory (>= 4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) YamlDotNet (12.0.1) GITHUB remote: fsprojects/FSharp.TypeProviders.SDK - src/ProvidedTypes.fs (6ad1174db0794a348f4a1c0aa5a60ae3f1803810) - src/ProvidedTypes.fsi (6ad1174db0794a348f4a1c0aa5a60ae3f1803810) - tests/ProvidedTypesTesting.fs (6ad1174db0794a348f4a1c0aa5a60ae3f1803810) + src/ProvidedTypes.fs (23b588d06acb8e100402523abc1d4f3f06325b8a) + src/ProvidedTypes.fsi (23b588d06acb8e100402523abc1d4f3f06325b8a) + tests/ProvidedTypesTesting.fs (23b588d06acb8e100402523abc1d4f3f06325b8a) GROUP Test -RESTRICTION: == net6.0 NUGET remote: https://api.nuget.org/v3/index.json Expecto (9.0.4) - FSharp.Core (>= 4.6) - Mono.Cecil (>= 0.11.3) - FSharp.Core (6.0.6) - redirects: force - Microsoft.Win32.SystemEvents (6.0.1) - redirects: force - Mono.Cecil (0.11.4) - System.Configuration.ConfigurationManager (6.0.1) - redirects: force - System.Security.Cryptography.ProtectedData (>= 6.0) - System.Security.Permissions (>= 6.0) - System.Drawing.Common (6.0) - redirects: force - Microsoft.Win32.SystemEvents (>= 6.0) - System.Resources.Extensions (6.0) - System.Security.AccessControl (6.0) - redirects: force - System.Security.Cryptography.ProtectedData (6.0) - redirects: force - System.Security.Permissions (6.0) - redirects: force - System.Security.AccessControl (>= 6.0) - System.Windows.Extensions (>= 6.0) - System.Windows.Extensions (6.0) - redirects: force - System.Drawing.Common (>= 6.0) + FSharp.Core (>= 4.6) - restriction: || (>= net461) (>= netstandard2.0) + Mono.Cecil (>= 0.11.3) - restriction: || (>= net461) (>= netstandard2.0) + FSharp.Core (9.0.202) - redirects: force + Microsoft.Bcl.HashCode (6.0) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + Mono.Cecil (0.11.4) - restriction: || (>= net461) (>= netstandard2.0) + System.Buffers (4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Collections.Immutable (9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) + System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Configuration.ConfigurationManager (9.0.4) - redirects: force + System.Diagnostics.EventLog (>= 9.0.4) - restriction: >= net8.0 + System.Security.Cryptography.ProtectedData (>= 9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Diagnostics.EventLog (9.0.4) - redirects: force, restriction: >= net8.0 + System.Formats.Nrbf (9.0.4) - restriction: || (>= net462) (>= netstandard2.0) + Microsoft.Bcl.HashCode (>= 1.1.1) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Reflection.Metadata (>= 9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) + System.ValueTuple (>= 4.5) - restriction: >= net462 + System.Memory (4.6.3) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Buffers (>= 4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Numerics.Vectors (>= 4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Numerics.Vectors (4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Reflection.Metadata (9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) + System.Collections.Immutable (>= 9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) + System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Resources.Extensions (9.0.4) + System.Formats.Nrbf (>= 9.0.4) - restriction: || (>= net462) (>= netstandard2.0) + System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Runtime.CompilerServices.Unsafe (6.1.2) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) + System.Security.Cryptography.ProtectedData (9.0.4) - redirects: force, restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Memory (>= 4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) + System.ValueTuple (4.6.1) - restriction: >= net462 diff --git a/src/FSharp.Configuration.DesignTime/FSharp.Configuration.DesignTime.fsproj b/src/FSharp.Configuration.DesignTime/FSharp.Configuration.DesignTime.fsproj index 7870b51..220a219 100644 --- a/src/FSharp.Configuration.DesignTime/FSharp.Configuration.DesignTime.fsproj +++ b/src/FSharp.Configuration.DesignTime/FSharp.Configuration.DesignTime.fsproj @@ -2,12 +2,14 @@ Library - netstandard2.0;net6.0 + netstandard2.0;net8.0 true true true PackageReference true + false + DESIGNTIME ..\FSharp.Configuration.Runtime\bin\$(Configuration)\typeproviders\fsharp41\ diff --git a/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fs b/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fs index e55ffab..4357f3c 100644 --- a/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fs +++ b/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fs @@ -1,5 +1,7 @@ namespace FSharp.Configuration.Yaml // Put the TypeProviderAssemblyAttribute in the runtime DLL, pointing to the design-time DLL +#if TP_RUNTIME [] do () +#endif diff --git a/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fsproj b/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fsproj index 2e205d7..50f55a2 100644 --- a/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fsproj +++ b/src/FSharp.Configuration.Runtime/FSharp.Configuration.Runtime.fsproj @@ -4,8 +4,9 @@ Library - netstandard2.0 + netstandard2.0;net8.0 true + false TP_RUNTIME @@ -32,12 +33,11 @@ - + - - + \ No newline at end of file diff --git a/src/FSharp.Configuration.Runtime/TypeProviders.Helper.fs b/src/FSharp.Configuration.Runtime/TypeProviders.Helper.fs index fb4c08f..35ba648 100644 --- a/src/FSharp.Configuration.Runtime/TypeProviders.Helper.fs +++ b/src/FSharp.Configuration.Runtime/TypeProviders.Helper.fs @@ -15,12 +15,12 @@ type FilePath = string type String with member x.TryGetChar i = - if i >= x.Length then None else Some x.[i] + if i >= x.Length then ValueNone else ValueSome x.[i] -let inline satisfies predicate (charOption: option) = +let inline satisfies predicate (charOption: voption) = match charOption with - | Some c when predicate c -> charOption - | _ -> None + | ValueSome c when predicate c -> charOption + | _ -> ValueNone let dispose(x: IDisposable) = if x = null then () else x.Dispose() @@ -33,13 +33,19 @@ let debug msg = // System.IO.File.AppendAllLines("debug.log", [sprintf "[%O] %s\n" dt msg]) Printf.kprintf writer msg +[] let (|EOF|_|) = function - | Some _ -> None - | _ -> Some() + | ValueSome _ -> ValueNone + | _ -> ValueSome() +[] let (|LetterDigit|_|) = satisfies Char.IsLetterOrDigit + +[] let (|Upper|_|) = satisfies Char.IsUpper + +[] let (|Lower|_|) = satisfies Char.IsLower /// Path.Combine @@ -120,24 +126,33 @@ module ValueParser = /// Converts a function returning bool,value to a function returning value option. /// Useful to process TryXX style functions. - let inline private tryParseWith(func: string -> 'a) = + let inline private tryParseWith(func: string -> bool * 'b) = func >> function - | true, value -> Some value - | false, _ -> None + | true, value -> ValueSome value + | false, _ -> ValueNone + [] let (|Bool|_|) = tryParseWith Boolean.TryParse + + [] let (|Int|_|) = tryParseWith Int32.TryParse + + [] let (|Int64|_|) = tryParseWith Int64.TryParse + [] let (|Float|_|) = tryParseWith(fun x -> Double.TryParse(x, NumberStyles.Any, CultureInfo.InvariantCulture)) + [] let (|TimeSpan|_|) = tryParseWith(fun x -> TimeSpan.TryParse(x, CultureInfo.InvariantCulture)) + [] let (|Guid|_|) = tryParseWith Guid.TryParse + [] let (|DateTime|_|) = tryParseWith(fun x -> DateTime.TryParse(x, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal)) @@ -151,6 +166,15 @@ module ValueParser = else None) +let inline forall predicate (source: ReadOnlySpan<_>) = + let mutable state = true + let mutable e = source.GetEnumerator() + + while state && e.MoveNext() do + state <- predicate e.Current + + state + /// Turns a string into a nice PascalCase identifier let createNiceNameProvider() = let set = HashSet() @@ -160,40 +184,38 @@ let createNiceNameProvider() = s else // Starting to parse a new segment - let rec restart i = seq { + let rec restart i = match s.TryGetChar i with - | EOF -> () - | LetterDigit _ & Upper _ -> yield! upperStart i (i + 1) - | LetterDigit _ -> yield! consume i false (i + 1) - | _ -> yield! restart(i + 1) - } + | EOF -> Seq.empty + | LetterDigit _ & Upper _ -> upperStart i (i + 1) + | LetterDigit _ -> consume i false (i + 1) + | _ -> restart(i + 1) // Parsed first upper case letter, continue either all lower or all upper - and upperStart from i = seq { + and upperStart from i = match s.TryGetChar i with - | Upper _ -> yield! consume from true (i + 1) - | Lower _ -> yield! consume from false (i + 1) - | _ -> yield! restart(i + 1) - } + | Upper _ -> consume from true (i + 1) + | Lower _ -> consume from false (i + 1) + | _ -> restart(i + 1) // Consume are letters of the same kind (either all lower or all upper) - and consume from takeUpper i = seq { + and consume from takeUpper i = match s.TryGetChar i with - | Lower _ when not takeUpper -> yield! consume from takeUpper (i + 1) - | Upper _ when takeUpper -> yield! consume from takeUpper (i + 1) - | _ -> - yield from, i + | Lower _ when not takeUpper -> consume from takeUpper (i + 1) + | Upper _ when takeUpper -> consume from takeUpper (i + 1) + | _ -> seq { + yield struct (from, i) yield! restart i - } + } // Split string into segments and turn them to PascalCase let mutable name = seq { for i1, i2 in restart 0 do - let sub = s.Substring(i1, i2 - i1) + let sub = s.AsSpan(i1, i2 - i1) - if Seq.forall Char.IsLetterOrDigit sub then - yield sub.[0].ToString().ToUpper() + sub.[1..].ToLower() + if forall Char.IsLetterOrDigit sub then + yield Char.ToUpper(sub.[0]).ToString() + sub.Slice(1).ToString().ToLower() } |> String.concat "" @@ -243,12 +265,12 @@ module File = let tryReadNonEmptyTextFile filePath = let maxAttempts = 5 - let rec sleepAndRun attempt = async { - do! Async.Sleep 1000 + let rec sleepAndRun attempt = task { + do! System.Threading.Tasks.Task.Delay 1000 return! loop(attempt - 1) } - and loop attemptsLeft = async { + and loop attemptsLeft = task { let attempt = maxAttempts - attemptsLeft + 1 match tryOpenFile filePath with @@ -267,19 +289,19 @@ module File = | None -> if attemptsLeft = 0 then return raise(FileNotFoundException(sprintf "File, %s could not be opened after %d attempts." filePath maxAttempts)) - - printfn "Attempt %d of %d: cannot read %s. Sleep for 1 sec, then retry..." attempt maxAttempts filePath - return! sleepAndRun attemptsLeft + else + printfn "Attempt %d of %d: cannot read %s. Sleep for 1 sec, then retry..." attempt maxAttempts filePath + return! sleepAndRun attemptsLeft } - loop maxAttempts |> Async.RunSynchronously + loop maxAttempts type private State = { LastFileWriteTime: DateTime Updated: DateTime } - let watch changesOnly filePath onChanged = + let watch changesOnly (filePath: string) onChanged = let getLastWrite() = File.GetLastWriteTime filePath diff --git a/src/FSharp.Configuration.Runtime/YamlConfigProvider.Runtime.fs b/src/FSharp.Configuration.Runtime/YamlConfigProvider.Runtime.fs index f4e98ad..0a1c04b 100644 --- a/src/FSharp.Configuration.Runtime/YamlConfigProvider.Runtime.fs +++ b/src/FSharp.Configuration.Runtime/YamlConfigProvider.Runtime.fs @@ -137,13 +137,16 @@ module Parser = let! field = tryGetField target ("_" + name) let newValue = - if field.FieldType <> node.UnderlyingType then + if Type.(<>)(field.FieldType, node.UnderlyingType) then if - node.UnderlyingType <> typeof - && field.FieldType = typeof + Type.(<>)(node.UnderlyingType, typeof) + && Type.(=)(field.FieldType, typeof) then node.BoxedValue |> string |> box - elif node.UnderlyingType = typeof && field.FieldType = typeof then + elif + Type.(=)(node.UnderlyingType, typeof) + && Type.(=)(field.FieldType, typeof) + then node.BoxedValue :?> int32 |> int64 |> box else failwithf "Cannot assign value of type %s to field of %s: %s." node.UnderlyingType.Name name field.FieldType.Name @@ -339,12 +342,30 @@ type Root(inferTypesFromStrings: bool) = /// Load Yaml config from a file and update itself with it. member x.Load(filePath: string) = try - filePath |> Helper.File.tryReadNonEmptyTextFile |> x.LoadText + filePath + |> Helper.File.tryReadNonEmptyTextFile + |> Async.AwaitTask + |> Async.RunSynchronously + |> x.LoadText + lastLoadedFrom <- Some filePath with e -> async { errorEvent.Trigger e } |> Async.Start reraise() + /// Load Yaml config from a file and update itself with it. + member x.LoadAsync(filePath: string) = + try + task { + let! t = filePath |> Helper.File.tryReadNonEmptyTextFile + t |> x.LoadText + lastLoadedFrom <- Some filePath + return () + } + with e -> + async { errorEvent.Trigger e } |> Async.Start + reraise() + /// Load Yaml config from a file, update itself with it, then start watching it for changes. /// If it detects any change, it reloads the file. member x.LoadAndWatch(filePath: string) = diff --git a/src/FSharp.Configuration.Runtime/paket.template b/src/FSharp.Configuration.Runtime/paket.template index d13656c..53bf161 100644 --- a/src/FSharp.Configuration.Runtime/paket.template +++ b/src/FSharp.Configuration.Runtime/paket.template @@ -30,9 +30,14 @@ files bin/Release/netstandard2.0/*.dll ==> lib/netstandard2.0 bin/Release/netstandard2.0/FSharp.Configuration.Runtime.* ==> lib/netstandard2.0 bin/Release/typeproviders/fsharp41/netstandard2.0/*.dll ==> typeproviders/fsharp41/netstandard2.0 + bin/Release/net8.0/*.dll ==> lib/net8.0 + bin/Release/net8.0/FSharp.Configuration.Runtime.* ==> lib/net8.0 + bin/Release/typeproviders/fsharp41/net8.0/*.dll ==> typeproviders/fsharp41/net8.0 dependencies framework: netstandard20 FSharp.Core >= LOCKEDVERSION + framework: net8.0 + FSharp.Core >= LOCKEDVERSION references FSharp.Configuration.Runtime.dll System.Configuration.ConfigurationManager.dll diff --git a/tests/FSharp.Configuration.Tests/FSharp.Configuration.Tests.fsproj b/tests/FSharp.Configuration.Tests/FSharp.Configuration.Tests.fsproj index 4dcec6e..2c701ad 100644 --- a/tests/FSharp.Configuration.Tests/FSharp.Configuration.Tests.fsproj +++ b/tests/FSharp.Configuration.Tests/FSharp.Configuration.Tests.fsproj @@ -2,12 +2,15 @@ Exe - net6.0 + net8.0 + + FSharp.Configuration.Tests false true true true + false NET461 diff --git a/tests/FSharp.Configuration.Tests/app.config b/tests/FSharp.Configuration.Tests/app.config index 7604f94..8112084 100644 --- a/tests/FSharp.Configuration.Tests/app.config +++ b/tests/FSharp.Configuration.Tests/app.config @@ -22,41 +22,21 @@ True - - - - True - - + True - - - - True - - + True - - + + True - - - - True - - - - - True - - + \ No newline at end of file From 7adc5fa5edf2a1186d83a476c938f9e3613e7c49 Mon Sep 17 00:00:00 2001 From: Tuomas Hietanen Date: Fri, 2 May 2025 20:47:52 +0100 Subject: [PATCH 2/2] Let's drop System.Configuration.ConfigurationManager to v8 if that would be more suitable for CI builds --- paket.dependencies | 6 ++-- paket.lock | 34 ++++++++++++--------- tests/FSharp.Configuration.Tests/app.config | 2 +- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index 15436c9..3e94e34 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -5,7 +5,7 @@ storage: none nuget YamlDotNet nuget FSharp.Core 8.0.301 -nuget System.Configuration.ConfigurationManager 9.0.4 +nuget System.Configuration.ConfigurationManager 8.0.1 nuget NETStandard.Library.NETFramework github fsprojects/FSharp.TypeProviders.SDK src/ProvidedTypes.fs @@ -17,5 +17,5 @@ group Test nuget FSharp.Core redirects: force nuget Expecto 9.0.4 - nuget System.Configuration.ConfigurationManager 9.0.4 redirects: force - nuget System.Resources.Extensions + nuget System.Configuration.ConfigurationManager 8.0.1 redirects: force + nuget System.Resources.Extensions \ No newline at end of file diff --git a/paket.lock b/paket.lock index 968a770..62513f7 100644 --- a/paket.lock +++ b/paket.lock @@ -8,19 +8,21 @@ NUGET NETStandard.Library.NETFramework (2.0.0-preview2-25405-01) Microsoft.NETCore.Platforms (>= 2.0.0-preview2-25405-01) - restriction: >= net461 NETStandard.Library (>= 2.0.0-preview2-25401-01) - restriction: >= net461 - System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) - System.Configuration.ConfigurationManager (9.0.4) - System.Diagnostics.EventLog (>= 9.0.4) - restriction: >= net8.0 - System.Security.Cryptography.ProtectedData (>= 9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) - System.Diagnostics.EventLog (9.0.4) - restriction: >= net8.0 - System.Memory (4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) + System.Buffers (4.5.1) - restriction: || (&& (>= monoandroid) (>= net6.0) (< netstandard1.1)) (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (>= net6.0) (< netstandard1.1)) (&& (< monoandroid) (>= net6.0) (< netstandard2.0)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= net6.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (>= net45) (>= net6.0) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (>= net461) (>= net6.0)) (&& (>= net6.0) (< net8.0) (>= xamarintvos)) (&& (>= net6.0) (< net8.0) (>= xamarinwatchos)) (&& (>= net6.0) (< netcoreapp2.0)) (&& (>= net6.0) (< netstandard1.1) (>= win8)) (&& (>= net6.0) (< netstandard2.0) (>= wpa81)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) + System.Configuration.ConfigurationManager (8.0.1) + System.Diagnostics.EventLog (>= 8.0.1) - restriction: >= net7.0 + System.Security.Cryptography.ProtectedData (>= 8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net6.0) + System.Diagnostics.EventLog (9.0.4) - restriction: >= net7.0 + System.Security.Principal.Windows (>= 5.0) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Memory (4.5.5) - restriction: || (&& (< net462) (< net8.0) (>= netstandard2.0)) (&& (>= net6.0) (< net8.0)) System.Buffers (>= 4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (< uap10.1) (>= wpa81)) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) System.Numerics.Vectors (>= 4.4) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) - System.Numerics.Vectors (4.5) - restriction: && (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos) - System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= uap10.1)) - System.Security.Cryptography.ProtectedData (9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Numerics.Vectors (4.5) - restriction: || (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) (&& (>= net6.0) (< netcoreapp2.0) (< xamarinios) (< xamarinmac) (< xamarintvos) (< xamarinwatchos)) + System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (>= monoandroid) (>= net6.0) (< netstandard1.1)) (&& (>= monoandroid) (< netstandard1.1) (>= netstandard2.0)) (&& (< monoandroid) (>= net6.0) (< netcoreapp2.1)) (&& (< monoandroid) (>= net6.0) (< netstandard1.1)) (&& (< monoandroid) (>= net6.0) (< netstandard2.0)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= netstandard2.0) (< win8)) (&& (>= monotouch) (>= net6.0)) (&& (>= monotouch) (>= netstandard2.0)) (&& (>= net45) (>= net6.0) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (&& (>= net461) (< net462) (>= netstandard2.0)) (&& (>= net461) (>= net6.0)) (&& (>= net6.0) (< net8.0) (>= xamarintvos)) (&& (>= net6.0) (< net8.0) (>= xamarinwatchos)) (&& (>= net6.0) (< netcoreapp2.0)) (&& (>= net6.0) (< netstandard1.1) (>= win8)) (&& (>= net6.0) (< netstandard2.0) (>= wpa81)) (&& (>= net6.0) (>= uap10.1)) (&& (< net8.0) (>= netstandard2.0) (>= xamarintvos)) (&& (< net8.0) (>= netstandard2.0) (>= xamarinwatchos)) (&& (< net8.0) (>= xamarinios)) (&& (< net8.0) (>= xamarinmac)) (&& (< netstandard1.1) (>= netstandard2.0) (>= win8)) (&& (>= netstandard2.0) (>= uap10.1)) + System.Security.Cryptography.ProtectedData (9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net6.0) System.Memory (>= 4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) + System.Security.Principal.Windows (5.0) - restriction: || (&& (>= net462) (>= net7.0)) (&& (>= net7.0) (< net8.0)) YamlDotNet (12.0.1) GITHUB remote: fsprojects/FSharp.TypeProviders.SDK @@ -40,15 +42,16 @@ NUGET System.Collections.Immutable (9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) - System.Configuration.ConfigurationManager (9.0.4) - redirects: force - System.Diagnostics.EventLog (>= 9.0.4) - restriction: >= net8.0 - System.Security.Cryptography.ProtectedData (>= 9.0.4) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) - System.Diagnostics.EventLog (9.0.4) - redirects: force, restriction: >= net8.0 + System.Configuration.ConfigurationManager (8.0.1) - redirects: force + System.Diagnostics.EventLog (>= 8.0.1) - restriction: >= net7.0 + System.Security.Cryptography.ProtectedData (>= 8.0) - restriction: || (&& (< net462) (>= netstandard2.0)) (>= net6.0) + System.Diagnostics.EventLog (9.0.4) - redirects: force, restriction: >= net7.0 + System.Security.Principal.Windows (>= 5.0) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) System.Formats.Nrbf (9.0.4) - restriction: || (>= net462) (>= netstandard2.0) Microsoft.Bcl.HashCode (>= 1.1.1) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) System.Reflection.Metadata (>= 9.0.4) - restriction: || (>= net462) (&& (>= net8.0) (< net9.0)) (&& (< net8.0) (>= netstandard2.0)) System.ValueTuple (>= 4.5) - restriction: >= net462 - System.Memory (4.6.3) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) + System.Memory (4.6.3) - restriction: || (>= net462) (&& (>= net6.0) (< net8.0)) (&& (< net8.0) (>= netstandard2.0)) System.Buffers (>= 4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) System.Numerics.Vectors (>= 4.6.1) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - restriction: || (>= net462) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) @@ -60,6 +63,7 @@ NUGET System.Formats.Nrbf (>= 9.0.4) - restriction: || (>= net462) (>= netstandard2.0) System.Memory (>= 4.5.5) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) System.Runtime.CompilerServices.Unsafe (6.1.2) - restriction: || (>= net462) (&& (< net8.0) (>= netstandard2.0)) (&& (< netcoreapp2.1) (>= netstandard2.0) (< netstandard2.1)) - System.Security.Cryptography.ProtectedData (9.0.4) - redirects: force, restriction: || (&& (< net462) (>= netstandard2.0)) (>= net8.0) + System.Security.Cryptography.ProtectedData (9.0.4) - redirects: force, restriction: || (&& (< net462) (>= netstandard2.0)) (>= net6.0) System.Memory (>= 4.5.5) - restriction: && (< net462) (< net8.0) (>= netstandard2.0) + System.Security.Principal.Windows (5.0) - redirects: force, restriction: || (&& (>= net462) (>= net7.0)) (&& (>= net7.0) (< net8.0)) System.ValueTuple (4.6.1) - restriction: >= net462 diff --git a/tests/FSharp.Configuration.Tests/app.config b/tests/FSharp.Configuration.Tests/app.config index 8112084..765277e 100644 --- a/tests/FSharp.Configuration.Tests/app.config +++ b/tests/FSharp.Configuration.Tests/app.config @@ -27,7 +27,7 @@ True - + True