Dotnet Global Tools Extension for ASPIRE–part 2–code and usage

First thing – – usage must be simple . So this is something that can be reproduces easy on each ASPIRE project :

builder.AddDotnetGlobalTools(“dotnet-ef”, “dotnet-depends”);

I cannot imagine simpler than this  – and , of course, you can add many more other dotnet tools –  see https://www.nuget.org/packages?q=&includeComputedFrameworks=true&packagetype=dotnettool&prerel=true&sortby=relevance 

What happens:

Now a Aspire resource will be created with a command to install the specified global tools. Also, a All command will be created to install all specified global tools – or you can click to install one by one

GlobalTool

Now , how this is executed : I have created a new class, derived from ExecutableResource , that executes

dotnet tool list -g

in order to see the global tools.

public class DotnetGlobalToolResource: ExecutableResource
{
    public DotnetGlobalToolResource(): base("DotnetGlobalTool","dotnet","")
    {
    }
    
}
public static IResourceBuilder<DotnetGlobalToolResource> AddDotnetGlobalTools(
    this IDistributedApplicationBuilder builder,
    params string[] arr
    )
{
    ArgumentNullException.ThrowIfNull(builder);
    var resource = new DotnetGlobalToolResource();
    var res = builder.AddResource(resource).WithArgs(new string[]
    {
        "tool",
        "list",
        "-g"
    })
        .ExcludeFromManifest()            
        ;

    if ((arr?.Length ?? 0) == 0)
        return res;
    //more code, see below arr

Also, for each tool enumerated in

builder.AddDotnetGlobalTools(“dotnet-ef”, “dotnet-depends”);

I have created a command to execute.

foreach (var toolName in arr)
{
    res.WithCommand(toolName, toolName,async (ExecuteCommandContext ecc)=>
    {
        var loggerService = ecc.ServiceProvider.GetService(typeof(ResourceLoggerService)) as ResourceLoggerService;
        var logger = loggerService?.GetLogger(resource);

        if (logger == null)
        {
            Console.WriteLine($"Logger not found for {resource.Name}");
            return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
        }
        
        return await FromTool(toolName, logger);
    });
}
        

Finally, I have created an ALL command to install all at once

  res.WithCommand("All", "!All!", async ecc =>
  {
      var loggerService = ecc.ServiceProvider.GetService(typeof(ResourceLoggerService)) as ResourceLoggerService;
      var logger = loggerService?.GetLogger(resource);

      if (logger == null)
      {
          Console.WriteLine($"Logger not found for {resource.Name}");
          return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
      }
      var commandService = ecc.ServiceProvider.GetService(typeof(ResourceCommandService)) as ResourceCommandService;
      if (commandService == null)
      {
          Console.WriteLine($"command service not found for {resource.Name}");
          return new ExecuteCommandResult() { Success = false, ErrorMessage = "Logger not found" };
      }
      logger.LogInformation("Starting full install...");
      var nrSuccess = 0;
      foreach (var toolName in arr)
      {
          var resTool = await commandService.ExecuteCommandAsync(resource, toolName);
          if (resTool.Success)
          {
              nrSuccess++;
              logger.LogInformation($"Installing {toolName} succeeded.");
          }
          else
          {
              logger.LogError($"Installing {toolName} failed: {resTool.ErrorMessage}");
          }
      }
      if (nrSuccess == arr.Length)
      {
          logger.LogInformation("All tools installed successfully.");
          return new ExecuteCommandResult() { Success = true };
      }
      else
      {
          //logger.LogWarning($"Only {nrSuccess} out of {arr.Length} tools were installed successfully.");
          return new ExecuteCommandResult() { Success = false, ErrorMessage = $"Only {nrSuccess} out of {arr.Length} tools were installed successfully." };
      }

  });

You find the nuget package at https://www.nuget.org/packages/DotnetGlobalToolsExtensionAspire – and the source code at https://github.com/ignatandrei/aspireExtensions 

Enjoy !


Posted

in

, , ,

by

Tags: