diff --git a/src/Spectre.Console/Cli/CommandApp.cs b/src/Spectre.Console/Cli/CommandApp.cs index 3e857fb..a4766d0 100644 --- a/src/Spectre.Console/Cli/CommandApp.cs +++ b/src/Spectre.Console/Cli/CommandApp.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; using Spectre.Console.Rendering; diff --git a/src/Spectre.Console/Cli/ConfiguratorExtensions.cs b/src/Spectre.Console/Cli/ConfiguratorExtensions.cs index 24a5b09..1ab577b 100644 --- a/src/Spectre.Console/Cli/ConfiguratorExtensions.cs +++ b/src/Spectre.Console/Cli/ConfiguratorExtensions.cs @@ -25,6 +25,23 @@ namespace Spectre.Console.Cli return configurator; } + /// + /// Overrides the auto-detected version of the application. + /// + /// The configurator. + /// The version of application. + /// A configurator that can be used to configure the application further. + public static IConfigurator SetApplicationVersion(this IConfigurator configurator, string version) + { + if (configurator == null) + { + throw new ArgumentNullException(nameof(configurator)); + } + + configurator.Settings.ApplicationVersion = version; + return configurator; + } + /// /// Configures the console. /// diff --git a/src/Spectre.Console/Cli/ICommandAppSettings.cs b/src/Spectre.Console/Cli/ICommandAppSettings.cs index d355d43..7d3af6c 100644 --- a/src/Spectre.Console/Cli/ICommandAppSettings.cs +++ b/src/Spectre.Console/Cli/ICommandAppSettings.cs @@ -10,6 +10,11 @@ namespace Spectre.Console.Cli /// string? ApplicationName { get; set; } + /// + /// Gets or sets the application version (use it to override auto-detected value). + /// + string? ApplicationVersion { get; set; } + /// /// Gets or sets the . /// diff --git a/src/Spectre.Console/Cli/Internal/CommandExecutor.cs b/src/Spectre.Console/Cli/Internal/CommandExecutor.cs index 01612b1..b0a4bb1 100644 --- a/src/Spectre.Console/Cli/Internal/CommandExecutor.cs +++ b/src/Spectre.Console/Cli/Internal/CommandExecutor.cs @@ -44,7 +44,7 @@ namespace Spectre.Console.Cli firstArgument.Equals("-v", StringComparison.OrdinalIgnoreCase)) { var console = configuration.Settings.Console.GetConsole(); - console.WriteLine(VersionHelper.GetVersion(Assembly.GetEntryAssembly())); + console.WriteLine(ResolveApplicationVersion(configuration)); return Task.FromResult(0); } } @@ -83,6 +83,13 @@ namespace Spectre.Console.Cli return Execute(leaf, parsedResult.Tree, context, resolver, configuration); } + private static string ResolveApplicationVersion(IConfiguration configuration) + { + return + configuration.Settings.ApplicationVersion ?? // potential override + VersionHelper.GetVersion(Assembly.GetEntryAssembly()); + } + private static Task Execute( CommandTree leaf, CommandTree tree, diff --git a/src/Spectre.Console/Cli/Internal/Configuration/CommandAppSettings.cs b/src/Spectre.Console/Cli/Internal/Configuration/CommandAppSettings.cs index 7fbf26d..5f07cb2 100644 --- a/src/Spectre.Console/Cli/Internal/Configuration/CommandAppSettings.cs +++ b/src/Spectre.Console/Cli/Internal/Configuration/CommandAppSettings.cs @@ -5,6 +5,7 @@ namespace Spectre.Console.Cli internal sealed class CommandAppSettings : ICommandAppSettings { public string? ApplicationName { get; set; } + public string? ApplicationVersion { get; set; } public IAnsiConsole? Console { get; set; } public ICommandInterceptor? Interceptor { get; set; } public ITypeRegistrarFrontend Registrar { get; set; } diff --git a/src/Spectre.Console/Cli/Internal/Modelling/CommandModel.cs b/src/Spectre.Console/Cli/Internal/Modelling/CommandModel.cs index 4dfac7d..902c2ca 100644 --- a/src/Spectre.Console/Cli/Internal/Modelling/CommandModel.cs +++ b/src/Spectre.Console/Cli/Internal/Modelling/CommandModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; @@ -28,7 +29,23 @@ namespace Spectre.Console.Cli public string GetApplicationName() { - return ApplicationName ?? Path.GetFileName(Assembly.GetEntryAssembly()?.Location) ?? "?"; + return + ApplicationName ?? + Path.GetFileName(GetApplicationFile()) ?? // null is propagated by GetFileName + "?"; + } + + private static string? GetApplicationFile() + { + var location = Assembly.GetEntryAssembly()?.Location; + if (string.IsNullOrWhiteSpace(location)) + { + // this is special case for single file executable + // (Assembly.Location returns empty string) + return Process.GetCurrentProcess().MainModule?.FileName; + } + + return location; } } } diff --git a/src/Spectre.Console/Cli/Internal/VersionHelper.cs b/src/Spectre.Console/Cli/Internal/VersionHelper.cs index 39ce465..ddcd790 100644 --- a/src/Spectre.Console/Cli/Internal/VersionHelper.cs +++ b/src/Spectre.Console/Cli/Internal/VersionHelper.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.Reflection; namespace Spectre.Console.Cli @@ -7,20 +6,9 @@ namespace Spectre.Console.Cli { public static string GetVersion(Assembly? assembly) { - if (assembly == null) - { - return "?"; - } - - try - { - var info = FileVersionInfo.GetVersionInfo(assembly.Location); - return info.ProductVersion ?? assembly?.GetName()?.Version?.ToString() ?? "?"; - } - catch - { - return "?"; - } + return assembly? + .GetCustomAttribute()? + .InformationalVersion ?? "?"; } } }