nuke-build / nuke

🏗 The AKEless Build System for C#/.NET
https://nuke.build
MIT License
2.9k stars 354 forks source link

ToolPathResolver.GetPackageExecutable fails on SingleOrDefault #102

Closed romatthe closed 6 years ago

romatthe commented 6 years ago

I'm trying to set up a Nuke build for the very first time, and I'm following along with the Getting Started page on the website. More specifically, I'm trying to build a target to execute all unit tests.

Target UnitTest => _ => _
   .DependsOn(Compile)
   .Executes(() =>
   {
      var assemblies = GlobFiles(SolutionDirectory, $"*/bin/{Configuration}/net*/*.Tests.dll").NotEmpty();
      var xunitSettings = new Xunit2Settings()
                .AddTargetAssemblies(assemblies)
                .AddResultReport(Xunit2ResultFormat.Xml, OutputDirectory / "tests.xml");

      XunitTasks.Xunit2(s => xunitSettings);
   });

But this always throws a System.InvalidOperationException.

_  _ _  _ _ ___ ___ ____ ____ ___
|  | |\ | |  |   |  |___ [__   |
|__| | \| |  |   |  |___ ___]  |

Sequence contains more than one element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Build.<get_UnitTest>b__8_1() in /Users/romatthe/Source/reniver-i4-opcua/build/Build.cs:line 60
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at Nuke.Common.Execution.BuildExecutor.Execute(IEnumerable`1 executionList)
   at Nuke.Common.Execution.BuildExecutor.Execute[T](Expression`1 defaultTargetExpression)

Looking a bit deeper, it seems like this thrown from inside the ToolPathResolver.GetPackageExecutable method, more specifically on this exact line.

Now, in my case, Directory.GetFiles is looking inside /Users/romatthe/.nuget/packages/xunit.runner.console/2.4.0 for xunit.console.exe. Obviously this doesn't yield a single return value, as I have multiple versions of this package in the tools directory.

/Users/romatthe/.nuget/packages/xunit.runner.console/2.4.0
├── build
│   └── xunit.runner.console.props
├── tools
│   ├── net452
│   ├── net46
│   ├── net461
│   ├── net462
│   ├── net47
│   ├── net471
│   ├── net472
│   ├── netcoreapp1.0
│   └── netcoreapp2.0
├── xunit.runner.console.2.4.0.nupkg
├── xunit.runner.console.2.4.0.nupkg.sha512
└── xunit.runner.console.nuspec

Whats the proper way to work around this? Setting the toolpath manually seems like a rather tricky thing to do, especially because this build should be working on both Windows, OSX and Linux.

As you've probably noticed, I'm currently working on OSX. Nuke version is 0.5.3

matkoch commented 6 years ago

@romatthe thanks for your report.

Yes, this is a bug. Mistakenly, the Xunit tasks currently assume that there is only one matching executable in the whole package folder. We will change this so that you can call SetFramework("net472") to pick the executable from any framework directory you want.

I'm not sure if we should fallback to any default value here. Or if we should always throw an exception if Framework was not set. /cc @arodus

We will fix this rather quickly. Anyway we plan to release within this week. In the meantime, you can use SetToolPath in combination with NuGetPackageResolver.

romatthe commented 6 years ago

Thanks for the quick response, I'll give the workaround a whirl.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.