Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NuGet restoring PostSharp package before the build begins

I am using PostSharp and I have the following target description in my project file:

<Target Name="EnsurePostSharpImported" BeforeTargets="BeforeBuild" Condition="'$(PostSharp30Imported)' == ''">
  <Error Condition="!Exists('..\..\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://www.postsharp.net/links/nuget-restore." />
  <Error Condition="Exists('..\..\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://www.postsharp.net/links/nuget-restore." />
</Target>

As far as I understand, this is added to the project when PostSharp is referenced through NuGet, and the error conditions check the following:

  • The first error condition breaks the build when PostSharp is not available (i.e. NuGet did not restore it successfully).
  • The second error condition breaks the build when PostSharp was successfully restored by NuGet on the last build but was therefore not included in the project, so therefore a rebuild is necessary.

BUT, if I have the following configuration in NuGet.Config and .csproj file, is the second error condition even necessary?

NuGet.Config file:

<configuration>
  <packageRestore>
    <!-- Allow NuGet to download missing packages -->
    <add key="enabled" value="True" />
    <!-- Automatically check for missing packages during build in Visual Studio -->
    <add key="automatic" value="True" />
  </packageRestore>
  ...
</configuration>

.csproj file:

<RestorePackages>true</RestorePackages>

As far as I understand, NuGet will then restore the missing packages BEFORE the build even starts. The second error condition will essentially break the build for no reason at all.

Note: I am using Visual Studio 2013 and NuGet 2.8.

like image 408
Dave New Avatar asked May 09 '14 06:05

Dave New


People also ask

How do I stop a NuGet package from restoring?

Go to Tools -> Options -> NuGet Package Manager -> General -> Package Restore. The first option disables restore itself, while the 2nd option disables on build restore.

Does Msbuild restore NuGet packages?

msbuild -t:Restore will restore nuget packages for projects with PackageReference nuget management format.

What is the difference between NuGet restore and dotnet restore?

nuget restore will ensure all of your NuGet dependencies are downloaded and available to your project. Whereas dotnet restore is a complete restoration of all NuGet dependencies as well as references and project specific tools. Meaning that if you run nuget restore , you are only restoring NuGet packages.


2 Answers

It depends on how the restore is done and which version of NuGet you have installed. It looks like the error messages are trying to cover three scenarios:

  1. Building without the MSBuild based package restore enabled (which is configured inside Visual Studio by right clicking the solution and selecting Enable Package restore).
  2. Building outside of Visual Studio when the MSBuild based package restore is not enabled.
  3. Building with Visual Studio using an old version of NuGet which does not support the automatic restore before a build.

If you are using the MSBuild based package restore then the restore will occur during the build and the PostSharp files will not be imported at this point so the $(PostSharp30Imported) will be empty and the second error message will be displayed. At least I suspect that is the case.

If you building from the command line and not using the MSBuild based package restore then you would see the first error message if the NuGet packages were missing.

If you are not using the MSBuild based package restore, and are building from within Visual Studio with a recent version of NuGet, then you are correct that the packages will be restored before anything is built at all. So the PostSharp imports should be available to MSBuild before it is even executed.

like image 138
Matt Ward Avatar answered Sep 21 '22 08:09

Matt Ward


As PostSharp dlls are required during msbuild loading (so targets referencing this dlls are available during build) they must be available during final call to msbuild.

While in VS it is acceptable to click build twice, I was using PostSharp in CI environment, and requirement to call build on solution two times was frustrating (first build restore nugets but also failed build due to error).

I ended up with separate build steps:

  1. Restore nuget Packages (this downloads PostSharp packages and return success code to environment): NuGet.exe restore SolutionWithProjectsUsingPostSharp.sln
  2. Build solution.
like image 26
kwesolowski Avatar answered Sep 20 '22 08:09

kwesolowski