DEV Community

Jamie Nordmeyer
Jamie Nordmeyer

Posted on • Originally published at jamienordmeyer.net on

.NET Global CLI’s

UPDATE: This project has now been upgraded to .NET 8. I’ve blogged about it here.

Merry Christmas and Happy Holidays to everyone!!! I know that it’s Christmas day, but as the day winds down, and I sit here after a fabulous Chrismas dinner, I have some time to kill, so I thought I’d get out this short post. :)

The other day I was watching this video from the talented Nick Chapsas:

I’ve created CLI applications before with .NET Core as well as .NET Framework, but I’ve never thought about doing so using the .NET tooling infrastructure. This is actually a really nice way to package up a CLI as a Nuget package, distribute it, and install it globally on your system so that instead of having to use dotnet run, you can just use a chosen name for the CLI without having to compile it to a native application on each operating system. In this post, I’m going to cover how I used the tools shown by Nick to create an extremely simple CLI for generating GUID’s.

I created a new .NET 6 console application with the dotnet new console command. To this project, I added a reference to the CommandLineParser Nuget package. When this project is built, it creates a Nuget package, so I included the following PropertyGroup section to the .csproj file to define the Nuget attriutes displayed with the package:

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net6.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <PackAsTool>true</PackAsTool>
  <ToolCommandName>guid</ToolCommandName>
  <PackageOutputPath>./dist</PackageOutputPath>
  <DefaultNamespace>StaticSphere.Cli.Guid</DefaultNamespace>
</PropertyGroup>
<PropertyGroup>
  <PackageVersion>1.0.0</PackageVersion>
  <PackageId>StaticSphere.Cli.Guid</PackageId>
  <Title>GUID Command Line Interface</Title>
  <Company>StaticSphere</Company>
  <Authors>Jamie Nordmeyer</Authors>
  <Copyright>Jamie Nordmeyer © 2021</Copyright>
  <Description>A global .NET based tool for generating GUID's</Description>
  <PackageTags>c#;core;cli</PackageTags>
  <PackageCopyright>Jamie Nordmeyer © 2021</PackageCopyright>
  <PackageProjectUrl>https://github.com/StaticSphere/guid-cli</PackageProjectUrl>
  <PackageLicenseExpression>MIT</PackageLicenseExpression>
  <RepositoryType>git</RepositoryType>
  <RepositoryUrl>https://github.com/StaticSphere/guid-cli</RepositoryUrl>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode

Next, I created a class called CommandLineOptions that tells my application how to display the command line parameters that I want the applications user to optionally provide. When the CLI is run with the --help parameter, it uses the settings specified in this class to show the user the parameters that they can define:

using CommandLine;

public class CommandLineOptions
{
    [Option('l', "lowercase", Required = false, HelpText = "If specified, the guid is created with lowercase letters")]
    public bool LowerCase { get; set; }

    [Option('n', "nodashes", Required = false, HelpText = "If specified, the guid is created with no dashes")]
    public bool NoDashes { get; set; }
}

Enter fullscreen mode Exit fullscreen mode

I really like how the CommandLineParser project wraps these options, as it’s extremely easy to specify the options that you want to provide, and to read the code and determine how to use the various parameters are being used.

Finally, the Program.cs file itself is using C# pattern matching syntax, along with the provided options if defined by the user, to create a GUID with the proper output format:

using CommandLine;

Parser
    .Default
    .ParseArguments<CommandLineOptions>(Environment.GetCommandLineArgs())
    .WithParsed(o =>
    {
        var guid = o switch
        {
            { LowerCase: false, NoDashes: false } => Guid.NewGuid().ToString().ToUpper(),
            { LowerCase: false, NoDashes: true } => Guid.NewGuid().ToString("N").ToUpper(),
            { LowerCase: true, NoDashes: false } => Guid.NewGuid().ToString(),
            { LowerCase: true, NoDashes: true } => Guid.NewGuid().ToString("N")
        };

        Console.WriteLine(guid);
    });

Enter fullscreen mode Exit fullscreen mode

You can still run this application without installing it:

cd <<source location>>
dotnet run
dotnet run --lowercase
dotnet run -n
dotnet run -ln
Enter fullscreen mode Exit fullscreen mode

But if you want to install it as a global tool, you’ll need to pack it and install it:

cd <<source location>>
dotnet pack # This creates a Nuget package under the ./dist folder
dotnet tool install --global --add-source ./dist StaticSphere.Cli.Guid
Enter fullscreen mode Exit fullscreen mode

But of course, you can install it from Nuget.org if you’d rather have the already compiled version:

dotnet tool install --global StaticSphere.Cli.Guid
Enter fullscreen mode Exit fullscreen mode

You can find the source on GitHub here, and the Nuget package, ready to be installed, via the above command line, here.

Top comments (0)