From 9e580f7d8db33492afd2a79347d09de42f6d0c09 Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 25 Oct 2023 15:45:02 +0200 Subject: [PATCH 1/5] Exit the commandline tool if the version of FSharp.Core cannot be loaded. --- Directory.Packages.props | 4 ++-- docs/content/Getting Started.fsx | 7 ++++++ src/FSharp.Analyzers.Cli/Program.fs | 24 ++++++++++++++++++- .../FSharp.Analyzers.SDK.fs | 9 +++++++ .../FSharp.Analyzers.SDK.fsi | 1 + 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index e604290..8dcc8c7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,8 +5,8 @@ - - + + diff --git a/docs/content/Getting Started.fsx b/docs/content/Getting Started.fsx index ce458eb..37ec1bf 100644 --- a/docs/content/Getting Started.fsx +++ b/docs/content/Getting Started.fsx @@ -34,6 +34,13 @@ dotnet add package FSharp.Analyzers.SDK paket add FSharp.Analyzers.SDK ``` +The `FSharp.Analyzers.SDK` takes a dependency on [FSharp.Compiler.Service](https://www.nuget.org/packages/FSharp.Compiler.Service/), which has a strict dependency on `FSharp.Core`. +It is considered a best practice to use the correct `FSharp.Core` version and not the implicit one from the SDK. + +```xml + +``` + ## First analyzer An [Analyzer<'TContext>](../reference/fsharp-analyzers-sdk-analyzer-1.html) is a function that takes a `Context` and returns a list of `Message`. diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index 9cf97ed..2eafc36 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -1,5 +1,6 @@ open System open System.IO +open System.Runtime.Loader open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Text open Argu @@ -55,12 +56,18 @@ let printInfo (fmt: Printf.TextWriterFormat<'a>) : 'a = else unbox (mkKn typeof<'a>) -let printError text arg = +let printError (text: Printf.TextWriterFormat<('a -> unit)>) (arg: 'a) : unit = Console.ForegroundColor <- ConsoleColor.Red printf "Error : " printfn text arg Console.ForegroundColor <- origForegroundColor +let printError2 (text: string) : unit = + Console.ForegroundColor <- ConsoleColor.Red + printf "Error : " + Console.WriteLine(text) + Console.ForegroundColor <- origForegroundColor + let loadProject toolsPath projPath = async { let loader = WorkspaceLoader.Create(toolsPath) @@ -277,6 +284,21 @@ let main argv = printInfo "%s" msg } + AssemblyLoadContext.Default.add_Resolving (fun ctx assemblyName -> + if assemblyName.Name = "FSharp.Core" then + let msg = + $"""Could not load FSharp.Core %A{assemblyName.Version}. The expected assembly version of FSharp.Core is %A{Utils.currentFSharpCoreVersion}. +Consider adding to your .fsproj. +The correct version can be found over at https://www.nuget.org/packages/FSharp.Analyzers.SDK#dependencies-body-tab. +""" + + printError2 msg + else + printError2 $"Could not load %s{assemblyName.Name} %A{assemblyName.Version}." + + exit 1 + ) + let client = Client(logger, Set.ofList excludeAnalyzers) diff --git a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs index 0d1da36..91c589b 100644 --- a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs +++ b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs @@ -180,6 +180,15 @@ module Utils = let currentFSharpAnalyzersSDKVersion = Assembly.GetExecutingAssembly().GetName().Version + let currentFSharpCoreVersion = + let currentAssembly = Assembly.GetExecutingAssembly() + let references = currentAssembly.GetReferencedAssemblies() + let fc = references |> Array.tryFind (fun ra -> ra.Name = "FSharp.Core") + + match fc with + | None -> failwith "FSharp.Core could not be found as a reference assembly of the SDK." + | Some fc -> fc.Version + let createContext (checkProjectResults: FSharpCheckProjectResults) (fileName: string) diff --git a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi index 95c0dea..6b574a2 100644 --- a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi +++ b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi @@ -161,6 +161,7 @@ module Utils = | SourceText of ISourceText val currentFSharpAnalyzersSDKVersion: Version + val currentFSharpCoreVersion: Version val createFCS: documentSource: option Async>> -> FSharpChecker From 717ea53aa6bf213a629a7d047ab4a28f4a5f246a Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 25 Oct 2023 17:16:38 +0200 Subject: [PATCH 2/5] Replace Printf.TextWriterFormat in printError. --- src/FSharp.Analyzers.Cli/Program.fs | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index 2eafc36..3f52463 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -56,15 +56,9 @@ let printInfo (fmt: Printf.TextWriterFormat<'a>) : 'a = else unbox (mkKn typeof<'a>) -let printError (text: Printf.TextWriterFormat<('a -> unit)>) (arg: 'a) : unit = +let printError (text: string) : unit = Console.ForegroundColor <- ConsoleColor.Red - printf "Error : " - printfn text arg - Console.ForegroundColor <- origForegroundColor - -let printError2 (text: string) : unit = - Console.ForegroundColor <- ConsoleColor.Red - printf "Error : " + Console.Write "Error : " Console.WriteLine(text) Console.ForegroundColor <- origForegroundColor @@ -96,12 +90,7 @@ let runProject (client: Client) toolsPath proj let fileContent = File.ReadAllText fileName let sourceText = SourceText.ofString fileContent - Utils.typeCheckFile - fcs - (fun s -> printError "%s" s) - option - fileName - (Utils.SourceOfSource.SourceText sourceText) + Utils.typeCheckFile fcs printError option fileName (Utils.SourceOfSource.SourceText sourceText) |> Option.map (Utils.createContext checkProjectResults fileName sourceText) ) |> Array.map (fun ctx -> @@ -277,7 +266,7 @@ let main argv = let logger = { new Logger with - member _.Error msg = printError "%s" msg + member _.Error msg = printError msg member _.Verbose msg = if verbose then @@ -292,9 +281,9 @@ Consider adding printError "No project given. Use `--project PATH_TO_FSPROJ`. Pass path relative to current directory.%s" - "" None | Some projects -> From 472c41c53038b2a9140890cad1e8517986bf21fc Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 25 Oct 2023 17:19:34 +0200 Subject: [PATCH 3/5] Add changelog entry. --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b54e8a..1e37333 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Changed +* [Use fixed version of FCS and FSharp.Core](https://github.com/ionide/FSharp.Analyzers.SDK/pull/127) (thanks @nojaf!) + ## [0.16.0] - 2023-10-16 ### Added From 60cf0a26256160876cbf4c4fd0b9d57e58dab375 Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 25 Oct 2023 17:23:52 +0200 Subject: [PATCH 4/5] Only care about FSharp.Core not loading. --- src/FSharp.Analyzers.Cli/Program.fs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index 3f52463..c08ef13 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -274,17 +274,17 @@ let main argv = } AssemblyLoadContext.Default.add_Resolving (fun ctx assemblyName -> - if assemblyName.Name = "FSharp.Core" then - let msg = - $"""Could not load FSharp.Core %A{assemblyName.Version}. The expected assembly version of FSharp.Core is %A{Utils.currentFSharpCoreVersion}. -Consider adding to your .fsproj. -The correct version can be found over at https://www.nuget.org/packages/FSharp.Analyzers.SDK#dependencies-body-tab. -""" - - printError msg + if assemblyName.Name <> "FSharp.Core" then + null else - printError $"Could not load %s{assemblyName.Name} %A{assemblyName.Version}." + let msg = + $"""Could not load FSharp.Core %A{assemblyName.Version}. The expected assembly version of FSharp.Core is %A{Utils.currentFSharpCoreVersion}. + Consider adding to your .fsproj. + The correct version can be found over at https://www.nuget.org/packages/FSharp.Analyzers.SDK#dependencies-body-tab. + """ + + printError msg exit 1 ) From 63446db5b4e87c4b7a04cbd4c6027b7ebedcf8c6 Mon Sep 17 00:00:00 2001 From: Florian Verdonck Date: Wed, 25 Oct 2023 22:26:12 +0200 Subject: [PATCH 5/5] Update src/FSharp.Analyzers.Cli/Program.fs Co-authored-by: dawe --- src/FSharp.Analyzers.Cli/Program.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharp.Analyzers.Cli/Program.fs b/src/FSharp.Analyzers.Cli/Program.fs index c08ef13..c937185 100644 --- a/src/FSharp.Analyzers.Cli/Program.fs +++ b/src/FSharp.Analyzers.Cli/Program.fs @@ -273,7 +273,7 @@ let main argv = printInfo "%s" msg } - AssemblyLoadContext.Default.add_Resolving (fun ctx assemblyName -> + AssemblyLoadContext.Default.add_Resolving (fun _ctx assemblyName -> if assemblyName.Name <> "FSharp.Core" then null else