Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an MSBuild Task that package authors can use to verify that a .NET Tool is able to be invoked #38883

Open
baronfel opened this issue Feb 19, 2024 · 2 comments
Assignees
Labels
Area-Tools untriaged Request triage from a team member

Comments

@baronfel
Copy link
Member

Is your feature request related to a problem? Please describe.

Despite not being able to make a direct reference on .NET SDK Tools, some NuGet packages have build logic that depends on such tools. Examples might include:

  • linting/formatting
  • code generation
  • ???

A specific example is the Monogame Compute project, which includes a package MonoGame.Content.Builder.Task.Compute, which relies on the .NET Tool mgcb-compute in its targets.

Targets like these are often not sophisticated, and invoke dotnet tools via the Exec task. When the matching tool isn't available, which can happen either because the tool isn't restored, or the tool isn't part of the .NET Tools config file, or other PATH-related reasons, users get build errors that are not very actionable. These errors are multi-line and look something like this:

Could not execute because the specified command or file was not found.
Possible reasons for this include:
  * You misspelled a built-in dotnet command.
  * You intended to execute a .NET program, but dotnet-do-the-thing does not exist.
  * You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on the PATH.

which do not render well in editors like VS at all.

Describe the solution you'd like

The SDK should provide a Task that would allow MSBuild logic authors to quickly check if a tool (and optionally some minimum version of a tool) was available to the current build context. This would involve reading the tool manifest and checking against it. Something like the following would be useful (taken from the actual targets of the package linked above):

<Target Name="RunContentBuilder" DependsOnTargets="PrepareContentBuilder">
    <CheckToolExists ToolName="mgcb-compute" />
	
    <!-- rest of build logic unchanged -->
    <!-- Remove this line if they make dotnet tool restore part of dotnet restore build -->
    <!-- https://github.com/dotnet/sdk/issues/4241 -->
    <Exec Command="$(DotnetCommand) tool restore" />


    <!-- Execute MGCB from the project directory so we use the correct manifest. -->
    <Exec
      Condition="'%(ContentReference.FullPath)' != ''"
      Command="$(DotnetCommand) $(MGCBCommand) $(MonoGameMGCBAdditionalArguments) /@:&quot;%(ContentReference.FullPath)&quot; /platform:$(MonoGamePlatform) /outputDir:&quot;%(ContentReference.ContentOutputDir)&quot; /intermediateDir:&quot;%(ContentReference.ContentIntermediateOutputDir)&quot; /workingDir:&quot;%(ContentReference.FullDir)&quot;"
      WorkingDirectory="$(MSBuildProjectDirectory)" />

    <ItemGroup>
      <ExtraContent
        Condition="'%(ContentReference.ContentOutputDir)' != ''"
        Include="%(ContentReference.ContentOutputDir)\**\*.*">
        <ContentDir>%(ContentReference.ContentDir)</ContentDir>
      </ExtraContent>
    </ItemGroup>

  </Target>

If the requested tool (and optionally version) is not present, the Task should log an actionable build error with a code that should say something like

The .NET SDK tool '<TOOLNAME>' is not available in the local tool config <PATH> or the global tool cache. Install the tool via `<COMMAND>` to resolve this error.

Additional context

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Tools untriaged Request triage from a team member labels Feb 19, 2024
@baronfel baronfel added untriaged Request triage from a team member and removed untriaged Request triage from a team member labels Feb 19, 2024
@MattKotsenas
Copy link
Member

I'll +1 this as well. I currently have separate projects that do this, one for https://www.nuget.org/packages/PackedPrettier, and the other for https://www.nuget.org/packages/OptiPNG.Tool

@NickCraver
Copy link
Member

I wonder if instead of a check if it exists, this should be an invocation task that checks if it exists, or at least better wraps the error that it doesn't then runs the check. Given this would almost invariably be followed by the exec anyway, that seems like a potentially cleaner overall option.

@marcpopMSFT marcpopMSFT self-assigned this Jun 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Tools untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

4 participants