NuGet Packaging: CLI Tool Packages
How to package and install the CLI tools
Dec 8, 2023
Engineering
NuGet Packaging Series
This article is part of the Creating NuGet Packages series. You can find the complete list of articles in the series at the end.
Introduction
So, you have developed a command line tool, and now you want to distribute it in a way that is convenient for your end users. You also want to ensure the installation process is smooth, whether done manually or through an installation script in a CI/CD pipeline. Luckily, .NET provides a great solution for both of these challenges.
I've developed a basic CLI tool for this exercise that computes the nth zero-based Fibonacci number. The final outcome in the terminal will be a straightforward command fibonacci
with the input argument --iterations
, which takes the number of iterations to calculate.
Once installed, one can open up the terminal and call it: fibonacci --iterations 3
which would produce:
Said that, let's dive into producing such a tool...
Setting Up the Project for Tool Packaging
The 99% of packaging is done the same way for regular projects, as described in the first article. There are only three extra properties needed to pack a tool:
PackAsTool
This boolean property tells the packager that this project is a CLI tool and to package it that way. Simple as that.
ToolCommandName
The <ToolCommandName>
property is an optional component that allows you to specify the command that will be used to invoke the tool after it has been installed.
If this element is not provided, the default command name for the tool will be the assembly name. The assembly name is typically the project file name without the .csproj
extension.
PackageOutputPath
The <PackageOutputPath>
is an optional property that specifies the location where the NuGet package will be generated. In our case, the package will be created in the ./nupkgs directory.
All Together
Putting it all together, your .csproj file should look something like this (note that for this example, I used the CommandLineParser library for easier parsing of passed arguments):
Tool Installation and Uninstallation
Installation
Once the NuGet package tool is created, it can be installed. .NET offers two methods for installing tools: local and global. In this example, we will install the tool globally, automatically adding it to the PATH environment variable and making it accessible globally.
This can be achieved with a simple command used in the project root:
After this, your tool will be available to use globally. In our case, and as previously demonstrated, like this:
The Parameters
global
--global
parameter tells the installer to install the CLI tool package globally
add-source
The --add-source
parameter tells the .NET CLI to use the ./nupkg directory as the source feed for NuGet packages where to find the Packaging.Tools
library and install the tool from it.
If omitted, it will try to search the Nuget.org site for the tool library with that ID.
Uninstallation
To uninstall the installed global tool, write this line providing the package ID of the tool (NOT the tool name):
Additional
I have included in the solution's root directory both .bat and .sh scripts for packaging, installing, and uninstalling the example CLI tool. These scripts will help streamline the process and make interacting with the example tool easier.
You can run the package.bat
script on Windows or package.sh
on Unix-based systems. These scripts will generate the NuGet package that can be distributed and installed on other machines.
Once the package is created, you can use the install.bat
script on Windows or the install.sh
script on Unix-based systems to install the CLI tool. This script will handle the installation process, including any dependencies or configurations required.
If you need to remove the CLI tool from your system, you can use the uninstall.bat
script on Windows or the uninstall.sh
script on Unix-based systems. Running these scripts will cleanly remove all traces of the tool from your machine.
Other Things to Consider
RID
RID, short for runtime identifier, is used to identify the target platforms an application runs on. These identifiers are crucial for .NET packages as they help represent platform-specific assets in NuGet packages. Examples of RIDs include linux-x64
, win-x64
, and osx-x64
.
In the case of packages with native dependencies, the RID specifies the platforms on which the package can be restored.
.NET Runtime Identifier (RID) catalog - .NET | Microsoft Learn
What Have We Learned?
As you see, creating CLI tools and packaging them as NuGets is really easy and straightforward in .NET. In this article, we learned:
How to prepare the CLI project to be packed as a NuGet package
Packing, Installing, and Uninstalling
Using the globally installed .NET tool
Example Project on GitHub
An example project for this article can be found here:
Creating NuGet Packages Series
This article is part of the Creating NuGet Packages series. If you enjoyed this one and want more, here is the complete list in the series:
Happy Coding!