question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow `dotnet restore` to also invoke `dotnet tool restore`

See original GitHub issue

Issue

No Guaranteed Availability for Local Tool during Build

Currently, we are in the process of upgrading our application from Core 2.2 to Core 3.1. One of the functionalities we depend on in 2.2 is the ability to reference a tool as a project dependency for guaranteed availability during build. Specifically, we reference Swashbuckle.AspNetCore.Cli and then have a MSBuild extension to execute it using a <Target> node in the .csproj. In 2.2 it looks like:

<PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
    <OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
  <DotNetCliToolReference Include="Swashbuckle.AspNetCore.Cli" Version="2.1.0-beta1" />
</ItemGroup>

<Target Name="SwaggerToFile" AfterTargets="AfterBuild">
    <Exec Command="dotnet swagger tofile --output $(TargetDir)openapi.json &quot;$(TargetPath)&quot; v1" />
</Target>

However, with the move to local tools in Core 3.x there is no longer a guarantee the tool is installed prior to the build. Though we have added the requisite local tool manifest to the repository root and removed the DotNetCliToolReference as required by the upgrade to 3.1, without modification to the custom Target the build will error unless the developer has manually run dotnet tool restore.

Solutions

Option 1 - Extend Custom Target (Works, Non-Ideally)

The solution that does currently work is to modify the custom Target to also call dotnet tool restore. This looks like this:

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<Target Name="SwaggerToFile" AfterTargets="AfterBuild">
    <Exec Command="dotnet tool restore" />
    <Exec Command="dotnet swagger tofile --output $(TargetDir)openapi.json &quot;$(TargetPath)&quot; v1" />
</Target>

This however is not ideal as it prevents the developer from using the tool directly until they have built once or manually run dotnet tool restore themselves. While a minor inconvenience, this is a gotcha that requires extra documentation and developer training to avoid–it is, to borrow a phrase, not the pit of success.

Option 2 - Add 2nd Custom Target to Extend Restore (Doesn’t Currently Work, Ideal)

The ideal solution would then be to extend the dotnet restore command to also call dotnet tool restore when this project is being restored. This is better because Visual Studio will automatically restore a solution/project when it is loaded and developers are already in the habit of running dotnet restore when they see complaints about missing packages. I tried to do this myself with a 2nd custom target but MSBuild does not seem to respect the extension of the Restore target which I assume exists based on this documentation. My attempt at making this work looks like:

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

<!-- Doesn't work :( -->
<Target Name="LocalToolRestore" AfterTargets="Restore">
    <Exec Command="dotnet tool restore" />
</Target>

<Target Name="SwaggerToFile" AfterTargets="AfterBuild">
    <Exec Command="dotnet swagger tofile --output $(TargetDir)openapi.json &quot;$(TargetPath)&quot; v1" />
</Target>

Why this doesn’t currently work I’m not sure, though I guess there may be a problem with the working directory or context in which dotnet restore is run; that, or the Restore target simply isn’t currently extensible via a .csproj the way Build and similar targets are. Whatever the case, I believe that for tools which will be used during or after build it would be a significantly improved experience if this extension were possible (it does not have to be mandatory behavior, an opt-in is fine).

Disclaimer

It is entirely possible that I have forgotten a key step to making Option 2 work or have not fully understood the implications of the move to local tooling in 3.x. If this is the case, I welcome instruction on how Option 2 is possible today or explanation about how this is an abuse of local tooling (which I expect would then lead to an issue on the Swashbuckle repo).

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:22
  • Comments:5

github_iconTop GitHub Comments

2reactions
mgravellcommented, May 24, 2020

The other way of thinking about this, perhaps, is for the dotnet tooling itself to detect that a: there is a tool defined in the config with that name (in the config), and b: that is isn’t already installed: just… install it? So: on demand install of the tool. Then the question of whether or not it is already installed becomes invisible to the consumer.

0reactions
diogocpcommented, Dec 20, 2021

Related: #4241

Read more comments on GitHub >

github_iconTop Results From Across the Web

dotnet tool restore command - .NET CLI
The dotnet tool restore command installs on your machine the .NET local tools that are in scope for the current directory.
Read more >
How to Get Rid of dotnet tool restore error Under Entity ...
Clean the solution then rebuild the solution or go to the project folder find "bin" folder and delete it, then clean and rebuild...
Read more >
10 commands you don't want to be without in .Net Core
Here's a full list of commands that runs restore implicitly: dotnet new; dotnet build; dotnet build-server; dotnet run; dotnet test; dotnet publish; dotnet...
Read more >
Restores the dependencies and tools of a .NET project
The "dotnet restore" command is a part of the .NET development framework and is used to restore the dependencies and tools required by...
Read more >
Install as .NET tool - Introduction to SpecSync for Azure DevOps
This can be performed using the dotnet tool restore command, that restores all .NET local tools of the project. See more information about...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found