Build/Test Issues

NCrunch can't locate other projects referenced outside <ProjectReference>

Started by jnm236 on 3,739 views

I'm adding integration tests to SourceLink's targets packages.
Everything works as you'd expect in VS and at the command line.

NCrunch copies the projects in some way that breaks the relative path for <ProjectForPackageTesting> but not for <ProjectReference>:


  <ItemGroup>
    <ProjectReference Include="..\dotnet-sourcelink-git\dotnet-sourcelink-git.csproj" />
    <ProjectReference Include="..\dotnet-sourcelink\dotnet-sourcelink.csproj" />
    <ProjectReference Include="..\SourceLink.Create.BitBucket\SourceLink.Create.BitBucket.csproj" />
    <ProjectReference Include="..\SourceLink.Create.BitBucketServer\SourceLink.Create.BitBucketServer.csproj" />
    <ProjectReference Include="..\SourceLink.Create.GitHub\SourceLink.Create.GitHub.csproj" />
    <ProjectReference Include="..\SourceLink.Create.GitLab\SourceLink.Create.GitLab.csproj" />
  </ItemGroup>

  <Target Name="CopyPackagesForIntegrationTesting" AfterTargets="AfterBuild">
    <ItemGroup>
      <ProjectForPackageTesting Include="..\SourceLink.Create.BitBucket\SourceLink.Create.BitBucket.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Create.BitBucketServer\SourceLink.Create.BitBucketServer.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Create.CommandLine\SourceLink.Create.CommandLine.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Create.GitHub\SourceLink.Create.GitHub.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Create.GitLab\SourceLink.Create.GitLab.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Embed.AllSourceFiles\SourceLink.Embed.AllSourceFiles.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Embed.PaketFiles\SourceLink.Embed.PaketFiles.csproj" />
      <ProjectForPackageTesting Include="..\SourceLink.Test\SourceLink.Test.csproj" />
    </ItemGroup>

    <PropertyGroup>
      <IntegrationTestPackageDir>$(OutputPath)Integration\</IntegrationTestPackageDir>
    </PropertyGroup>
    <RemoveDir Directories="$(IntegrationTestPackageDir)" />
    <MSBuild Projects="@(ProjectForPackageTesting)" Targets="Pack" RemoveProperties="TargetFramework" Properties="PackageOutputPath=$([System.IO.Path]::GetFullPath($(IntegrationTestPackageDir)))" />
  </Target>


I dislike this special treatment of <ProjectReference> but in any case, what's the workaround?

Thanks!

Edited

Referencing project files directly (via project reference or in any other way accessing .proj files) is a serious problem in NCrunch workspaces.

This is because NCrunch workspaces are designed to isolate projects from their dependencies (and parent solution) to allow them to be built completely independently. Introducing any kind of dependency on referenced project files naturally breaks this isolation. When building projects in a workspace, NCrunch actually strips out all ProjectReferences and replaces them with References pointing directly at DLLs already built from these projects.

This is done because MSBuild is designed to be hierarchical; any build of a project in the solution results in projects being recursively fed through the build system. The result is extremely long build times and likely interference between the build system and other background tasks, since the build actions cannot be isolated. Thus the NCrunch engine is designed to make this impossible. When the 'Copy referenced assemblies to workspace' setting is enabled, the build-chaining behaviour of MSBuild is emulated but project references are still avoided.

So getting this to work in NCrunch will require a rethink. What are you trying to do? Can you make it work using just the DLLs and avoiding the project files?
Thus the NCrunch engine is designed to make this impossible.

So getting this to work in NCrunch will require a rethink. What are you trying to do? Can you make it work using just the DLLs and avoiding the project files?


It's not possible to use just the DLLs because what's being tested is the .nupkg outputs themselves.

This integration test ensures that if you add a package reference to any of these nupkgs from a net462 project, you won't get extra lib references.
It requires running dotnet restore --source actual_nupkg_folder and dotnet msbuild:

https://github.com/ctaggart/SourceLink/blob/62c3efa3c08d819dbdd8eae98fd2569a1f084cd5/Tests/Integration/When_package_without_lib_is_installed.cs#L19

I suppose using NCrunch with the SourceLink project isn't necessary. I just would prefer not to block all contributers from using NCrunch, but integration testing is more important.

Edited

If you had a way to find all the project directories of these referenced projects (containing the nupkgs) inside the NCrunch workspaces, would you be able to use this instead of hard-coding build references to these projects?

NCrunch has a concept called 'Implicit project references' that is designed to allow you to do this. The caveat here is that implicit project references are only available at run-time, not build-time.

Check it out - http://www.ncrunch.net/documentation/V3/reference_project-configuration_implicit-project-dependencies.

The idea would be that you'd set implicit project references from your test project to the projects containing the nupkgs, then you could enumerate these using NCrunch.Framework.NCrunchEnvironment.GetImplicitlyReferencedAssemblyLocations() and working back from the DLL to the project directory. Such an approach would only work under NCrunch, so you'd need to have two different versions of your test if you want it to be run outside NCrunch.

Note that if you already have project references pointing at the nupkg projects, then you won't need to specify an implicit project reference .. you'd just use NCrunch.Framework.GetAllAssemblyLocations() instead.

Post a reply

Log in to reply.