From cca870aeedbded8da6110c2b3429c7c21122d17b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 13 Apr 2021 21:42:54 +0100 Subject: [PATCH 1/3] add options for global properties on getProjectInfo --- src/Ionide.ProjInfo/Library.fs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Ionide.ProjInfo/Library.fs b/src/Ionide.ProjInfo/Library.fs index 6e8c24af..07a3d9ca 100644 --- a/src/Ionide.ProjInfo/Library.fs +++ b/src/Ionide.ProjInfo/Library.fs @@ -99,11 +99,16 @@ module ProjectLoader = "_GenerateCompileDependencyCache" "CoreCompile" |] - let loadProject (path: string) (generateBinlog: bool) (ToolsPath toolsPath) = + let loadProject (path: string) (generateBinlog: bool) (ToolsPath toolsPath) globalProperties toolsVersion = try let tfm = getTfm path - let globalProperties = getGlobalProps path tfm + let defaultGlobalProperties = getGlobalProps path tfm + let globalProperties = + dict [ for (KeyValue(k,v)) in defaultGlobalProperties -> (k,v) + yield! globalProperties ] + + let toolsVersion = toolsVersion |> Option.defaultValue null match System.Environment.GetEnvironmentVariable "DOTNET_HOST_PATH" with | null @@ -112,7 +117,7 @@ module ProjectLoader = use pc = new ProjectCollection(globalProperties) - let pi = pc.LoadProject(path) + let pi = pc.LoadProject(path, globalProperties, toolsVersion) use sw = new StringWriter() @@ -343,10 +348,12 @@ module ProjectLoader = /// Full path to the `.fsproj` file /// Path to MsBuild obtained from `ProjectLoader.init ()` /// Enable Binary Log generation + /// The global properties to use (e.g. Configuration=Release). Some additional global properties are pre-set by the tool + /// The tools version to use, if any. /// List of additional MsBuild properties that you want to obtain. /// Returns the record instance representing the loaded project or string containing error message - let getProjectInfo (path: string) (toolsPath: ToolsPath) (generateBinlog: bool) (customProperties: string list) : Result = - let loadedProject = loadProject path generateBinlog toolsPath + let getProjectInfo (path: string) (toolsPath: ToolsPath) (globalProperties: (string*string) list) (toolsVersion: string option) (generateBinlog: bool) (customProperties: string list) : Result = + let loadedProject = loadProject path generateBinlog toolsPath globalProperties toolsVersion match loadedProject with | Success project -> getLoadedProjectInfo path customProperties project @@ -561,7 +568,7 @@ type WorkspaceLoader private (toolsPath: ToolsPath) = cache |> Seq.map (fun n -> n.Value) |> Seq.toList let rec loadProject p = - let res = ProjectLoader.getProjectInfo p toolsPath generateBinlog customProperties + let res = ProjectLoader.getProjectInfo p toolsPath [] None generateBinlog customProperties match res with | Ok project -> From 696ce9357ac05a7e28953999a6984eab3ebd7f53 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 13 Apr 2021 22:14:10 +0100 Subject: [PATCH 2/3] add test --- src/Ionide.ProjInfo/Library.fs | 45 +++++++++---------- test/Ionide.ProjInfo.Tests/Tests.fs | 22 ++++++--- test/examples/sample2-netsdk-lib/n1/n1.fsproj | 3 +- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/Ionide.ProjInfo/Library.fs b/src/Ionide.ProjInfo/Library.fs index 07a3d9ca..4abbf82c 100644 --- a/src/Ionide.ProjInfo/Library.fs +++ b/src/Ionide.ProjInfo/Library.fs @@ -78,7 +78,7 @@ module ProjectLoader = else [ logger ] - let getGlobalProps (path: string) (tfm: string option) = + let getGlobalProps (path: string) (tfm: string option) (globalProperties: (string * string) list)= dict [ "ProvideCommandLineArgs", "true" "DesignTimeBuild", "true" "SkipCompilerExecution", "true" @@ -91,7 +91,8 @@ module ProjectLoader = "TargetFramework", tfm.Value if path.EndsWith ".csproj" then "NonExistentFile", Path.Combine("__NonExistentSubDir__", "__NonExistentFile__") - "DotnetProjInfo", "true" ] + "DotnetProjInfo", "true" + yield! globalProperties ] let buildArgs = @@ -99,16 +100,11 @@ module ProjectLoader = "_GenerateCompileDependencyCache" "CoreCompile" |] - let loadProject (path: string) (generateBinlog: bool) (ToolsPath toolsPath) globalProperties toolsVersion = + let loadProject (path: string) (generateBinlog: bool) (ToolsPath toolsPath) globalProperties = try let tfm = getTfm path - let defaultGlobalProperties = getGlobalProps path tfm - let globalProperties = - dict [ for (KeyValue(k,v)) in defaultGlobalProperties -> (k,v) - yield! globalProperties ] - - let toolsVersion = toolsVersion |> Option.defaultValue null + let globalProperties = getGlobalProps path tfm globalProperties match System.Environment.GetEnvironmentVariable "DOTNET_HOST_PATH" with | null @@ -117,7 +113,7 @@ module ProjectLoader = use pc = new ProjectCollection(globalProperties) - let pi = pc.LoadProject(path, globalProperties, toolsVersion) + let pi = pc.LoadProject(path, globalProperties, toolsVersion=null) use sw = new StringWriter() @@ -349,11 +345,10 @@ module ProjectLoader = /// Path to MsBuild obtained from `ProjectLoader.init ()` /// Enable Binary Log generation /// The global properties to use (e.g. Configuration=Release). Some additional global properties are pre-set by the tool - /// The tools version to use, if any. /// List of additional MsBuild properties that you want to obtain. /// Returns the record instance representing the loaded project or string containing error message - let getProjectInfo (path: string) (toolsPath: ToolsPath) (globalProperties: (string*string) list) (toolsVersion: string option) (generateBinlog: bool) (customProperties: string list) : Result = - let loadedProject = loadProject path generateBinlog toolsPath globalProperties toolsVersion + let getProjectInfo (path: string) (toolsPath: ToolsPath) (globalProperties: (string*string) list) (generateBinlog: bool) (customProperties: string list) : Result = + let loadedProject = loadProject path generateBinlog toolsPath globalProperties match loadedProject with | Success project -> getLoadedProjectInfo path customProperties project @@ -376,7 +371,8 @@ type IWorkspaceLoader = [] abstract Notifications : IEvent -type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) = +type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath, ?globalProperties: (string*string) list) = + let globalProperties = defaultArg globalProperties [] let logger = LogProvider.getLoggerFor () let loadingNotification = new Event() @@ -390,9 +386,11 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) = loadingNotification.Trigger(WorkspaceProjectState.Failed(p, ProjectNotFound(p))) None - let projectInstanceFactory projectPath globalProperties (projectCollection: ProjectCollection) = + let projectInstanceFactory projectPath (_globalProperties: IDictionary) (projectCollection: ProjectCollection) = let tfm = ProjectLoader.getTfm projectPath - ProjectInstance(projectPath, ProjectLoader.getGlobalProps projectPath tfm, null, projectCollection) + //let globalProperties = globalProperties |> Seq.toList |> List.map (fun (KeyValue(k,v)) -> (k,v)) + let globalProperties = ProjectLoader.getGlobalProps projectPath tfm globalProperties + ProjectInstance(projectPath, globalProperties, toolsVersion=null, projectCollection=projectCollection) let projectGraphProjs (paths: string seq) = @@ -400,7 +398,7 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) = <| fun () -> paths |> Seq.iter (fun p -> loadingNotification.Trigger(WorkspaceProjectState.Loading p)) let entryPoints = paths |> Seq.map ProjectGraphEntryPoint - ProjectGraph(entryPoints, ProjectCollection.GlobalProjectCollection, projectInstanceFactory) + ProjectGraph(entryPoints, projectCollection=ProjectCollection.GlobalProjectCollection, projectInstanceFactory=projectInstanceFactory) let projectGraphSln (path: string) = handleProjectGraphFailures @@ -548,10 +546,11 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) = this.LoadSln(sln, customProperties, false) - static member Create(toolsPath: ToolsPath) = - WorkspaceLoaderViaProjectGraph(toolsPath) :> IWorkspaceLoader + static member Create(toolsPath: ToolsPath, ?globalProperties) = + WorkspaceLoaderViaProjectGraph(toolsPath, ?globalProperties=globalProperties) :> IWorkspaceLoader -type WorkspaceLoader private (toolsPath: ToolsPath) = +type WorkspaceLoader private (toolsPath: ToolsPath, ?globalProperties: (string * string) list) = + let globalProperties = defaultArg globalProperties [] let loadingNotification = new Event() @@ -568,7 +567,7 @@ type WorkspaceLoader private (toolsPath: ToolsPath) = cache |> Seq.map (fun n -> n.Value) |> Seq.toList let rec loadProject p = - let res = ProjectLoader.getProjectInfo p toolsPath [] None generateBinlog customProperties + let res = ProjectLoader.getProjectInfo p toolsPath globalProperties generateBinlog customProperties match res with | Ok project -> @@ -651,8 +650,8 @@ type WorkspaceLoader private (toolsPath: ToolsPath) = - static member Create(toolsPath: ToolsPath) = - WorkspaceLoader(toolsPath) :> IWorkspaceLoader + static member Create(toolsPath: ToolsPath, ?globalProperties) = + WorkspaceLoader(toolsPath, ?globalProperties=globalProperties) :> IWorkspaceLoader type ProjectViewerTree = { Name: string diff --git a/test/Ionide.ProjInfo.Tests/Tests.fs b/test/Ionide.ProjInfo.Tests/Tests.fs index d179fc86..e4217feb 100644 --- a/test/Ionide.ProjInfo.Tests/Tests.fs +++ b/test/Ionide.ProjInfo.Tests/Tests.fs @@ -13,6 +13,8 @@ open Ionide.ProjInfo open Expecto.Logging.Message open FSharp.Compiler.SourceCodeServices +#nowarn "25" + let RepoDir = (__SOURCE_DIRECTORY__ / ".." / "..") |> Path.GetFullPath let ExamplesDir = RepoDir / "test" / "examples" let TestRunDir = RepoDir / "test" / "testrun_ws" @@ -140,10 +142,10 @@ module ExpectNotification = let watchNotifications logger loader = NotificationWatcher(loader, logNotification logger) -let testSample2 toolsPath workspaceLoader (workspaceFactory: ToolsPath -> IWorkspaceLoader) = +let testSample2 toolsPath workspaceLoader isRelease (workspaceFactory: ToolsPath * (string * string) list -> IWorkspaceLoader) = testCase |> withLog - (sprintf "can load sample2 - %s" workspaceLoader) + (sprintf "can load sample2 - %s - isRelease is %b" workspaceLoader isRelease) (fun logger fs -> let testDir = inDir fs "load_sample2" copyDirFromAssets fs ``sample2 NetSdk library``.ProjDir testDir @@ -153,7 +155,9 @@ let testSample2 toolsPath workspaceLoader (workspaceFactory: ToolsPath -> IWorks dotnet fs [ "restore"; projPath ] |> checkExitCodeZero - let loader = workspaceFactory toolsPath + let config = if isRelease then "Release" else "Debug" + let props = [("Configuration", config)] + let loader = workspaceFactory (toolsPath, props) let watcher = watchNotifications logger loader @@ -168,8 +172,10 @@ let testSample2 toolsPath workspaceLoader (workspaceFactory: ToolsPath -> IWorks let n1Parsed = parsed |> expectFind projPath "first is a lib" let expectedSources = - [ projDir / "obj/Debug/netstandard2.0/n1.AssemblyInfo.fs" - projDir / "Library.fs" ] + [ projDir / ("obj/" + config + "/netstandard2.0/n1.AssemblyInfo.fs") + projDir / "Library.fs" + if isRelease then + projDir / "Other.fs" ] |> List.map Path.GetFullPath Expect.equal parsed.Length 1 "console and lib" @@ -981,8 +987,10 @@ let tests toolsPath = testSequenced <| testList "Main tests" - [ testSample2 toolsPath "WorkspaceLoader" WorkspaceLoader.Create - testSample2 toolsPath "WorkspaceLoaderViaProjectGraph" WorkspaceLoaderViaProjectGraph.Create + [ testSample2 toolsPath "WorkspaceLoader" false (fun (tools,props) -> WorkspaceLoader.Create(tools, globalProperties=props)) + testSample2 toolsPath "WorkspaceLoader" true (fun (tools,props) -> WorkspaceLoader.Create(tools, globalProperties=props)) + testSample2 toolsPath "WorkspaceLoaderViaProjectGraph" false (fun (tools,props) -> WorkspaceLoaderViaProjectGraph.Create(tools, globalProperties=props)) + testSample2 toolsPath "WorkspaceLoaderViaProjectGraph" true (fun (tools,props) -> WorkspaceLoaderViaProjectGraph.Create(tools, globalProperties=props)) testSample3 toolsPath "WorkspaceLoader" WorkspaceLoader.Create testSample3WorkspaceLoaderExpected //- Sample 3 having issues, was also marked pending on old test suite // testSample3 toolsPath "WorkspaceLoaderViaProjectGraph" WorkspaceLoaderViaProjectGraph.Create testSample3GraphExpected //- Sample 3 having issues, was also marked pending on old test suite testSample4 toolsPath "WorkspaceLoader" WorkspaceLoader.Create diff --git a/test/examples/sample2-netsdk-lib/n1/n1.fsproj b/test/examples/sample2-netsdk-lib/n1/n1.fsproj index df454322..0cf27b2f 100644 --- a/test/examples/sample2-netsdk-lib/n1/n1.fsproj +++ b/test/examples/sample2-netsdk-lib/n1/n1.fsproj @@ -5,7 +5,8 @@ - + + From 2cf6dcc500fb929045e00a6e96ac506871fd052f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 13 Apr 2021 22:17:08 +0100 Subject: [PATCH 3/3] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56b91748..9a72e930 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ 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). +## [0.51.0] - 2021-04-13 + +* [Allow global properties to be provided to project loaders](https://github.com/ionide/proj-info/pull/107) + ## [0.50.0] - 2021-03-13 * Introduce a pluggable abstraction for creating workspaces to allow for independent experimentation