spectreconsole / spectre.console

A .NET library that makes it easier to create beautiful console applications.

Home Page:https://spectreconsole.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Document if one can define their custom CommandSettings subtypes as "internal".

AraHaan opened this issue · comments

I would love to be able to do this on one of my programs:

WorkloadSettings.cs:
namespace Elskom.Check;

internal class WorkloadSettings : CommandSettings
{
    [CommandOption("--sdk")]
    public string? SdkVersion { get; set; }

    [CommandOption("--rid")]
    public string? RuntimeIdentifier { get; set; }
}
InstallCommand.cs:
namespace Elskom.Check;

public class InstallCommand : AsyncCommand<WorkloadSettings>
{
    public override async Task<int> ExecuteAsync([NotNull] CommandContext context, [NotNull] WorkloadSettings settings)
    {
        DotNetSdkHelper.GetOrUpdateSdkVersion(ref settings);
        var workloadInfos = await NuGetHelper.ResolveWildcardWorkloadPackageVersionsAsync(settings.RuntimeIdentifier!).ConfigureAwait(false);
        await workloadInfos.InstallAsync(settings.SdkVersion!, settings.RuntimeIdentifier!).ConfigureAwait(false);
        return 0;
    }
}
Program.cs:
// set the console title.
Console.Title = "Elskom workload cross-platform installer";

// Need to register the code pages provider for code that parses
// and later needs ISO-8859-2
Encoding.RegisterProvider(
    CodePagesEncodingProvider.Instance);

// Test that it loads
_ = Encoding.GetEncoding("ISO-8859-2");
var app = new CommandApp();
app.Configure(config =>
{
    config.AddCommand<InstallCommand>("install").WithDescription("Installs the Workload.");
    config.AddCommand<UninstallCommand>("uninstall").WithDescription("Uninstalls the Workload.");
    config.AddCommand<UpdateCommand>("update").WithDescription("Updates the Workload.");
});

// This args stuff could probably be simplified.
var finalArgs = new List<string>();
var firstArg = args.FirstOrDefault()?.Trim().ToLowerInvariant() ?? string.Empty;
if (firstArg != "install" && firstArg != "uninstall" && firstArg != "update")
{
    finalArgs.Add("install");
}

if (args.Any())
{
    finalArgs.AddRange(args);
}

using (NuGetHelper.HttpClient = new HttpClient())
{
    var result = await app.RunAsync(finalArgs).ConfigureAwait(false);
    Console.Title = "";
    return result;
}

It seems if I made the settings type internal without making the types in my cli program (like InstallCommand) internal as well that the code does not compile, but unclear that if I do that as well if Spectre would recognize those as commands too.

Ok, I did some testing by moving all the real code that the cli program project itself uses into a separate library project (including the command classes and made them all internal, added InternalsVisibleTo on that separate project for the cli project to see the internals), then built and debug went smoothly.

Either both command and settings need to be internal, or command and settings public. Mixing internal and public will not compile, and is nothibg that we will try to support.