Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow loading of projects that are missing imports. #206

Merged
merged 12 commits into from
Apr 21, 2024
Merged
6 changes: 0 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ jobs:
env:
BuildNet7: ${{ matrix.build_net7 }}

- name: Upload NuGet packages
uses: actions/upload-artifact@v2
with:
name: packages
path: src/**/*.nupkg

- name: Archive test results
uses: actions/upload-artifact@v3

Expand Down
1 change: 0 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"name": "Ionide.ProjInfo.Tests",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/test/Ionide.ProjInfo.Tests/bin/Debug/${input:tfm}/Ionide.ProjInfo.Tests.dll",
"args": [
"--filter",
Expand Down
273 changes: 202 additions & 71 deletions src/Ionide.ProjInfo/Library.fs

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions test/Ionide.ProjInfo.Tests/TestAssets.fs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,13 @@ let ``NetSDK library referencing ProduceReferenceAssembly library`` = {
"l2"
/ "l2.fsproj"
TargetFrameworks = Map.ofList [ "netstandard2.0", sourceFiles [ "Library.fs" ] ]
ProjectReferences = [
``NetSDK library with ProduceReferenceAssembly``
]
ProjectReferences = [ ``NetSDK library with ProduceReferenceAssembly`` ]
}

let ``Console app with missing direct Import`` = {
ProjDir = "missing-import"
AssemblyName = "missing-import"
ProjectFile = "missing-import.fsproj"
TargetFrameworks = Map.ofList [ "net6.0", sourceFiles [ "Program.fs" ] ]
ProjectReferences = []
}
74 changes: 61 additions & 13 deletions test/Ionide.ProjInfo.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ let pathForProject (test: TestAssetProjInfo) =
pathForTestAssets test
/ test.ProjectFile

let implAssemblyForProject (test: TestAssetProjInfo) =
$"{test.AssemblyName}.dll"
let implAssemblyForProject (test: TestAssetProjInfo) = $"{test.AssemblyName}.dll"

let refAssemblyForProject (test: TestAssetProjInfo) =
Path.Combine("ref", implAssemblyForProject test)
Expand Down Expand Up @@ -366,7 +365,7 @@ let testLegacyFrameworkMultiProject toolsPath workspaceLoader isRelease (workspa
let testSample2 toolsPath workspaceLoader isRelease (workspaceFactory: ToolsPath * (string * string) list -> IWorkspaceLoader) =
testCase
|> withLog
(sprintf "can load sample2 - %s - isRelease is %b" workspaceLoader isRelease)
(sprintf "can load sample2 - isRelease is %b - %s" isRelease workspaceLoader)
(fun logger fs ->
let testDir = inDir fs "load_sample2"
copyDirFromAssets fs ``sample2 NetSdk library``.ProjDir testDir
Expand Down Expand Up @@ -1765,12 +1764,14 @@ let testLoadProject toolsPath =
]
|> checkExitCodeZero

let projResult = ProjectLoader.getProjectInfo projPath [] BinaryLogGeneration.Off []
let collection = new Microsoft.Build.Evaluation.ProjectCollection()

match projResult with
| Result.Ok proj -> Expect.equal proj.ProjectFileName projPath "project file names"
match ProjectLoader.loadProject projPath BinaryLogGeneration.Off collection with
| Result.Error err -> failwith $"{err}"

| Result.Ok proj ->
match ProjectLoader.getLoadedProjectInfo projPath [] proj with
| Result.Ok proj -> Expect.equal proj.ProjectFileName projPath "project file names"
| Result.Error err -> failwith $"{err}"
)

let testProjectSystem toolsPath workspaceLoader workspaceFactory =
Expand Down Expand Up @@ -2067,7 +2068,7 @@ let addFileToProject (projPath: string) fileName =
let loadProjfileFromDiskTests toolsPath workspaceLoader (workspaceFactory: ToolsPath -> IWorkspaceLoader) =
testCase
|> withLog
$"can load project from disk everytime {workspaceLoader}"
$"can load project from disk everytime - {workspaceLoader}"
(fun logger fs ->

let loader = workspaceFactory toolsPath
Expand Down Expand Up @@ -2157,14 +2158,17 @@ let referenceAssemblySupportTest toolsPath prefix (workspaceFactory: ToolsPath -
|> Seq.toList

Expect.hasLength parsed 2 "Should have loaded the F# lib and the referenced F# lib"
let fsharpProject = parsed |> Seq.find (fun p -> Path.GetFileName(p.ProjectFileName) = Path.GetFileName(childProj.ProjectFile))

let fsharpProject =
parsed
|> Seq.find (fun p -> Path.GetFileName(p.ProjectFileName) = Path.GetFileName(childProj.ProjectFile))

let mapped = FCS.mapToFSharpProjectOptions fsharpProject parsed
let referencedProjects = mapped.ReferencedProjects
Expect.hasLength referencedProjects 1 "Should have a reference to the F# ProjectReference lib"

match referencedProjects[0] with
| FSharpReferencedProject.FSharpReference(targetPath, _) ->
Expect.stringContains targetPath (refAssemblyForProject parentProj) "Should have found the ref assembly for the F# lib"
| FSharpReferencedProject.FSharpReference(targetPath, _) -> Expect.stringContains targetPath (refAssemblyForProject parentProj) "Should have found the ref assembly for the F# lib"
| _ -> failwith "Should have found a F# reference"
)

Expand All @@ -2180,6 +2184,47 @@ let testProjectLoadBadData =
Expect.isNone proj.Response "should have loaded, detected bad data, and defaulted to empty"
)

let canLoadMissingImports toolsPath loaderType (workspaceFactory: ToolsPath -> IWorkspaceLoader) =
testCase
$"Can load projects with missing Imports - {loaderType}"
(fun () ->
let proj = ``Console app with missing direct Import``
let projPath = pathForProject proj

let loader = workspaceFactory toolsPath
let logger = Log.create (sprintf "Test '%s'" $"Can load projects with missing Imports - {loaderType}")

loader.Notifications.Add(
function
| WorkspaceProjectState.Failed(projPath, errors) ->
logger.error (
Message.eventX "Failed to load project {project} with {errors}"
>> Message.setField "project" projPath
>> Message.setField "errors" errors
)
| WorkspaceProjectState.Loading p ->
logger.info (
Message.eventX "Loading project {project}"
>> Message.setField "project" p
)
| WorkspaceProjectState.Loaded(p, knownProjects, fromCache) ->
logger.info (
Message.eventX "Loaded project {project}(fromCache: {fromCache})"
>> Message.setField "project" p
>> Message.setField "fromCache" fromCache
)
)

let parsed =
loader.LoadProjects [ projPath ]
|> Seq.toList

Expect.equal parsed.Length 1 "Should have loaded the project"
let parsed = parsed[0]
Expect.equal 3 parsed.SourceFiles.Length "Should have Program.fs, AssemblyInfo, and AssemblyAttributes"
Expect.stringEnds parsed.SourceFiles[2] "Program.fs" "Filename should be Program.fs"
)

let tests toolsPath =
let testSample3WorkspaceLoaderExpected = [
ExpectNotification.loading "c1.fsproj"
Expand Down Expand Up @@ -2297,7 +2342,10 @@ let tests toolsPath =
expensiveTests toolsPath WorkspaceLoader.Create
csharpLibTest toolsPath WorkspaceLoader.Create

referenceAssemblySupportTest toolsPath (nameof(WorkspaceLoader)) WorkspaceLoader.Create
referenceAssemblySupportTest toolsPath (nameof(WorkspaceLoaderViaProjectGraph)) WorkspaceLoaderViaProjectGraph.Create
referenceAssemblySupportTest toolsPath (nameof (WorkspaceLoader)) WorkspaceLoader.Create
referenceAssemblySupportTest toolsPath (nameof (WorkspaceLoaderViaProjectGraph)) WorkspaceLoaderViaProjectGraph.Create

// tests that cover our ability to handle missing imports
canLoadMissingImports toolsPath (nameof (WorkspaceLoader)) WorkspaceLoader.Create
canLoadMissingImports toolsPath (nameof (WorkspaceLoaderViaProjectGraph)) WorkspaceLoaderViaProjectGraph.Create
]
3 changes: 3 additions & 0 deletions test/examples/missing-import/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[<EntryPoint>]
let main args =
1
14 changes: 14 additions & 0 deletions test/examples/missing-import/missing-import.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>missing_import</RootNamespace>
</PropertyGroup>

<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>

<Import Project="$(MSBuildExtensionsPath)Foo\Foo.targets" />

</Project>
Loading