Daniel VH
Daniel VH

Reputation: 121

How to pack command line tools with NuGet?

This is sort of a use-case. Not sure if NuGet was originally created for this so I can imagine that the consensus will be that I should not do what I'd like.

Goal:

Package and distribute simple console applications as tools for other projects. I expect them to be runnable from command prompt. Something like Nunit's console runner (nunit-console.exe).

I use C# targeting net461 and netcore2.

Questions:

I will reference to my tooling app and it's package as MyApp and MyPkg.

  1. Can you confirm that the convention is that MyApp binaries should go into the tools folder in the NuGet package?
  2. Whatever dependency I add to MyApp (such as CommandLineArgumentsParser), they will show up in the dependent projects as references/dependencies. I wish they didn't - can it be prevented?
  3. There are other dependency dlls in the bin folder next to MyApp binary. They are dlls from other packages. Is it a good practice to include those in my package as well?
  4. If I specify package X as dependency to MyPkg, package X will be installed for the project depending on MyPkg. Can X's DLLs be referenced somehow so that I don't have to pack them with MyApp?

I hope that my questions are clear. Please, ask for clarification if what I wrote doesn't quite make sense to you - can't expect that you are a mindreader:)

Also, if you have any online resources that I could read that tackles that subject, I would be super happy to chew through them.

Thanks!

Upvotes: 12

Views: 4473

Answers (2)

Jacob Foshee
Jacob Foshee

Reputation: 2773

dotnet tool

The approach which has likely superseded walterlv's answer is .NET Tools.

A .NET tool is a special NuGet package that contains a console application. You can install a tool on your machine [locally] or [globally].

The creation process, described fully at Tutorial: Create a .NET tool, is minimally:

  1. Create a new .NET Console app (.NET Core 3 or newer)
  2. Add <PackAsTool>true</PackAsTool> to the csproj
  3. Build with dotnet pack

The nupkg can then be published to NuGet or referenced by adding its directory as a "source".

Installing Globally

dotnet tool install -g Example.MyTool

Other members of your team would need to run the same command.

Installing Locally

# First time only, create dotnet-tools.json
dotnet new tool-manifest
dotnet tool install Example.MyTool

Other members of your team would need to run dotnet tool restore.

Running the tool

dotnet Example.MyTool

See the linked documentation for more details and options.

Upvotes: 4

walterlv
walterlv

Reputation: 2376

Direct Answer

1.Can you confirm that the convention is that MyApp binaries should go into the tools folder in the NuGet package?

Yes, it's recommended to put your command line binaries into the tools folder.

See the NuGet official docs: How to create a NuGet package - Microsoft Docs. For tools folder, it said that:

Powershell scripts and programs accessible from the Package Manager Console.

The tools folder is added to the PATH environment variable for the Package Manager Console only (Specifically, not to the PATH as set for MSBuild when building the project).

2.Whatever dependency I add to MyApp (such as CommandLineArgumentsParser), they will show up in the dependent projects as references/dependencies. I wish they didn't - can it be prevented?

You should add PrivateAssets="All" to prevent your package dependencies be converted to NuGet dependencies.

See the NuGet official docs: NuGet PackageReference format (package references in project files) | Microsoft Docs. Just add this code to any dependencies that you don't want to be referenced by your target project.

<PackageReference Include="CommandLineArgumentsParser" Version="3.0.18" PriavateAssets="All">

If all of your dependencies should not be converted to package dependencies, Add this line to the end of all your PackageReference nodes:

<PackageReference Update="@(PackageReference)" PrivateAssets="All" />

3.There are other dependency dlls in the bin folder next to MyApp binary. They are dlls from other packages. Is it a good practice to include those in my package as well?

NuGet doesn't provide us the ability to resolve dependencies automatically, so we should put our dependency dlls into our tools folder, too. If you want to know how to add dependencies, read Nate McMaster's post to learn: MSBuild tasks with dependencies.

4.If I specify package X as dependency to MyPkg, package X will be installed for the project depending on MyPkg. Can X's DLLs be referenced somehow so that I don't have to pack them with MyApp?

This question is the same as the 2nd one, just follow the 2nd answer.

Additional References

I've written such a post to help us pack command line tools with NuGet, but it's not in English. I'm glad to translate it into English today so that you can read to learn.

This is the temp Google Translate version and I'll translate it into English as soon as possible and post it here.

These are more articles for you to learn the NuGet packing skills. They do not directly answer your questions but they are still useful:

Upvotes: 11

Related Questions