spectreconsole / spectre.console

A .NET library that makes it easier to create beautiful console applications.
https://spectreconsole.net
MIT License
8.92k stars 454 forks source link

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

Closed AraHaan closed 4 months ago

AraHaan commented 4 months ago

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

WorkloadSettings.cs: ```cs namespace Elskom.Check; internal class WorkloadSettings : CommandSettings { [CommandOption("--sdk")] public string? SdkVersion { get; set; } [CommandOption("--rid")] public string? RuntimeIdentifier { get; set; } } ```
InstallCommand.cs: ```cs namespace Elskom.Check; public class InstallCommand : AsyncCommand { public override async Task 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: ```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("install").WithDescription("Installs the Workload."); config.AddCommand("uninstall").WithDescription("Uninstalls the Workload."); config.AddCommand("update").WithDescription("Updates the Workload."); }); // This args stuff could probably be simplified. var finalArgs = new List(); 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; } ```
AraHaan commented 4 months ago

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.

AraHaan commented 4 months ago

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.

patriksvensson commented 4 months ago

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.