1

I'm working on one OSS project that uses nuget to distribute its packages.

Today I encountered a problem that some projects are fine when you reference them directly, but they don't restore from nuget because of weird versioning errors.

So I'd like to prevent unusable code from being merged into master branch.

I removed all local references, and created following pre-build event:

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn/CodeGeneration.Roslyn.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Attributes/CodeGeneration.Roslyn.Attributes.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Tasks/CodeGeneration.Roslyn.Tasks.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Tool/CodeGeneration.Roslyn.Tool.csproj&quot;" />
  </Target>

Okay, now it packs all required projects. Then I want to reference them. Now my pre-build looks like:

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn/CodeGeneration.Roslyn.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Attributes/CodeGeneration.Roslyn.Attributes.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Tasks/CodeGeneration.Roslyn.Tasks.csproj&quot;" />
    <Exec Command="&quot;$(MSBuildBinPath)\msbuild.exe&quot; /t:pack &quot;$(SolutionDir)CodeGeneration.Roslyn.Tool/CodeGeneration.Roslyn.Tool.csproj&quot;" />

    <Exec Command="Install-Package CodeGeneration.Attributes -Source &quot;$(SolutionDir)../bin/Packages/$(Configuration)&quot;" />
    <Exec Command="Install-Package CodeGeneration.Tasks -Source &quot;$(SolutionDir)../bin/Packages/Packages/$(Configuration)&quot;" />
    <Exec Command="Install-Package CodeGeneration.Roslyn -Source &quot;$(SolutionDir)../bin/Packages/Packages/$(Configuration)&quot;" />
    <Exec Command="Install-Package dotnet-codegen -Source &quot;$(SolutionDir)../bin/Packages/Packages/$(Configuration)&quot;" />
  </Target>

But it doesn't work because of:

Install-Package : No match was found for the specified search criteria and package name 'CodeGeneration.Attributes'. Tr y Get-PackageSource to see all available registered package sources. At line:1 char:1 + Install-Package CodeGeneration.Attributes -Source C:\Users\Alex\Sourc ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Ex ception + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

It seems that it doesn't like prerelease packages (they look like CodeGeneration.Roslyn.0.4.38-gfe7ce5be9d.nupkg), okay, checking for documentation and trying to add -IncludePrerelease flag, but it doesn't work too:

Install-Package : A parameter cannot be found that matches parameter name 'IncludePrerelease'. At line:1 char:126 + ... os\CodeGeneration.Roslyn\src../bin/Packages/Debug -IncludePrerelease + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Install-Package], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

How could it be done? Maybe there is another approach which is way simpler and better? I have described it so detailed because I don't want fall into X-Y pitfall.

Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • I don't understand, you create packages from solution projects, and then install they in the project of same solution? May be better create a local NuGet feed and create "initial packages", then install directly through NuGet Package Manager? Also you can set floating version for packages, manually installation will once. – UserName May 04 '18 at 14:28
  • @UserName it should be completely automated and have no global implications. You propose to modify global `nuget.config` which isn't an option. It should work locally as well as on travis and those who clone this project. I'd like to not pollute their configs. – Alex Zhukovskiy May 05 '18 at 14:34
  • I misinterpreted your question - `Testing nuget packages locally`. As minimum I think you must do not use of `$(SolutionDir)` property, because it defined [only at build from IDE](https://learn.microsoft.com/en-us/cpp/ide/common-macros-for-build-commands-and-properties). Of course, if you do not override this property yourself. – UserName May 05 '18 at 15:04
  • All pre/postbuild events are free to manipulate with SolutionDir/ProjectDir/TargetDir and so on, it's quite common. And it's quite sad that this question still have no replies or answers. I have to reinvent the wheel that possibly exists somewhere. – Alex Zhukovskiy May 06 '18 at 16:36

1 Answers1

2

Testing nuget packages locally

When we build the project with Visual Studio, build event command line have the same environment settings as Command Prompt.

However, the command Install-Package [-Id] <string> [[-Source] <string>] should be executed in the NuGet Package Manager Console rather than Command Prompt. Because when we install the nuget package to the project, NuGet modifies the project file (.csproj) to include references, it needs the NuGet API in Visual Studio. When we execute the command line in the Command Prompt(Build event), nuget could not access the NuGet API in Visual Studio, so install the nuget package via build event will not successfully.

Check more info from this thread.

The workaround to automate install nuget packages to the project, you could use Visual Studio 2017 (15.3 and higher) and the PackageReference style of referencing projects, add a Directory.Build.props file into the root of your solution, file like:

<Project>
  <ItemGroup>
    <PackageReference Include="CodeGeneration.Roslyn" Version="0.4.38-gfe7ce5be9d" />
  </ItemGroup>
</Project>

See Martin's answer for some more details.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135