File: Commands\Tool\List\ToolListLocalCommand.cs
Web Access
Project: src\src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.CommandLine;
using Microsoft.DotNet.Cli.ToolManifest;
using Microsoft.DotNet.Cli.ToolPackage;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.Extensions.EnvironmentAbstractions;

namespace Microsoft.DotNet.Cli.Commands.Tool.List;

internal sealed class ToolListLocalCommand : CommandBase<ToolListCommandDefinition>
{
    private readonly IToolManifestInspector _toolManifestInspector;
    private readonly IReporter _reporter;
    private const string CommandDelimiter = ", ";

    public ToolListLocalCommand(
        ParseResult parseResult,
        IToolManifestInspector toolManifestInspector = null,
        IReporter reporter = null)
        : base(parseResult)
    {
        _reporter = reporter ?? Reporter.Output;

        _toolManifestInspector = toolManifestInspector ??
                                 new ToolManifestFinder(new DirectoryPath(Directory.GetCurrentDirectory()));
    }

    public override int Execute()
    {
        var packageIdArgument = _parseResult.GetValue(Definition.PackageIdArgument);
        PackageId? packageId = string.IsNullOrWhiteSpace(packageIdArgument) ? null : new(packageIdArgument);

        IEnumerable<(ToolManifestPackage package, FilePath path)> packages = _toolManifestInspector.Inspect();
        if (packageId != null)
        {
            packages = packages.Where(t => t.package.PackageId.Equals(packageId));
        }

        var formatValue = _parseResult.GetValue(Definition.ToolListFormatOption);
        if (formatValue is ToolListOutputFormat.json)
        {
            PrintJson(packages);
        }
        else
        {
            PrintTable(packages);
        }

        if (packageId.HasValue && !packages.Any())
        {
            // return 1 if target package was not found
            return 1;
        }

        return 0;
    }

    private void PrintTable(IEnumerable<(ToolManifestPackage toolManifestPackage, FilePath SourceManifest)> packageEnumerable)
    {
        var table = new PrintableTable<(ToolManifestPackage toolManifestPackage, FilePath SourceManifest)>();
        table.AddColumn(
            CliCommandStrings.ToolListPackageIdColumn,
            p => p.toolManifestPackage.PackageId.ToString());
        table.AddColumn(
            CliCommandStrings.ToolListVersionColumn,
            p => p.toolManifestPackage.Version.ToNormalizedString());
        table.AddColumn(
            CliCommandStrings.ToolListCommandsColumn,
            p => string.Join(CommandDelimiter, p.toolManifestPackage.CommandNames.Select(c => c.Value)));
        table.AddColumn(
            CliCommandStrings.ManifestFileColumn,
            p => p.SourceManifest.Value);
        table.PrintRows(packageEnumerable, l => _reporter.WriteLine(l));
    }

    private void PrintJson(IEnumerable<(ToolManifestPackage toolManifestPackage, FilePath SourceManifest)> packageEnumerable)
    {
        var jsonData = new VersionedDataContract<LocalToolListJsonContract[]>()
        {
            Data = [.. packageEnumerable.Select(p => new LocalToolListJsonContract
            {
                PackageId = p.toolManifestPackage.PackageId.ToString(),
                Version = p.toolManifestPackage.Version.ToNormalizedString(),
                Commands = [.. p.toolManifestPackage.CommandNames.Select(c => c.Value)],
                Manifest = p.SourceManifest.Value
            })]
        };
        var jsonText = System.Text.Json.JsonSerializer.Serialize(jsonData, JsonHelper.JsonContext.VersionedDataContractLocalToolListJsonContractArray);
        _reporter.WriteLine(jsonText);
    }
}