Blog

Make a .NET Core CLI Extensions

21 Dec, 2016
Xebia Background Header Wave

.NET Core comes with a new tool chain for software development. These tools run from the CLI (Command Line Interface). Out of the box you have command line restore, build, etc. These tools are the primary tools on which higher-level tools, such as Integrated Development Environments (IDEs), editors and build orchestrators can build on. The tools set in extendable on project level. That means that you can add tools in the context of your project by adding it to your project file. The tool you want to run with the from the CLI is called a verb (dotnet-verb). Running a verb is done by: dotnet verb.

No more, it works on my machine!

Not all tools you need are installed out of the box. The .NET Core CLI comes with an extension model that enables you to add your own tools. On project level you can add tools distributed with NuGet. Add the NuGet package configuration to your project file and run dotnet restore to get the tool on your system. The tool will be installed the same way your project NuGet packages are installed for your project. The tools in now available in the scope of your project. The tools will be installed on all the machines where the project is developed. This way you have the same tools on your build server as on your developer workstation. With the new model you do not need to have administrative privileges to install tooling for your project.

Create an simple extension
To show how this works I have created an example in which we will see this. Project can be found at github dotnet-allversions.

using System;
using System.Diagnostics;
using System.Linq;
using System.IO;
using Microsoft.DotNet.PlatformAbstractions;
namespace dotnetallversion
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Installed .Net versions are:");
            string clipath = Path.GetDirectoryName(new Microsoft.DotNet.Cli.Utils.Muxer().MuxerPath);
            DirectoryInfo di = new DirectoryInfo(Path.Combine(clipath,"sdk"));
            Console.WriteLine("Active version: " + Microsoft.DotNet.Cli.Utils.Product.Version);
            Console.WriteLine();
            foreach (var item in di.GetDirectories()){
                string versionfile = Path.Combine(item.FullName,".version");
                if (IsVersionFilePresent(versionfile))
                {
                    string version = item.Name;
                    string hash = GetHash(versionfile);
                    string template = $@"Product Information:
 Version:            {version}
 Commit SHA-1 hash:  {hash}
";
                    Console.WriteLine(template);
                }
            }
            Console.WriteLine($@"Runtime Environment:
 OS Name:     {RuntimeEnvironment.OperatingSystem}
 OS Version:  {RuntimeEnvironment.OperatingSystemVersion}
 OS Platform: {RuntimeEnvironment.OperatingSystemPlatform}
 RID:         {RuntimeEnvironment.GetRuntimeIdentifier()}");
        }
        static string GetHash(string versionfile)
        {
            var lines = File.ReadAllLines(versionfile);
            return lines[0].Substring(0,8);
        }
        static bool IsVersionFilePresent(string versionfile){
            return File.Exists(versionfile);
        }
    }
}

To make a .NET CLI extension from the program, you have to make a NuGet package. This can be done by getting the needed packages and then run the pack command:

dotnet restore
dotnet pack

Now you have to upload the NuGet package to a NuGet server to be used in your projects.

Add the extension to your project
Now you can add the tool to you project by adding the following configuration to your project file:

<ItemGroup>
    <DotNetCliToolReference Include="dotnet-allversions">
         <Version>0.1.1-*</Version>
    </DotNetCliToolReference>
</ItemGroup>

Then run:

dotnet restore

This will download and install the tool from NuGet. Next you can run the program in your project scope:

dotnet allversions

Conclusion
.NET CLI Extension are a powerful way of extending your command within your project. For example you can enforce that all developers and build servers are using the same command versions. Using NuGet to download the give all team members access to the same set of tools everywhere.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts