mirror of
				https://github.com/velopack/velopack.git
				synced 2025-10-25 15:19:22 +00:00 
			
		
		
		
	Adding flow API command
This provide a hidden Velopack Flow API command. This allows for easier scripting directly against the API as it leveraging the built in auth.
This commit is contained in:
		| @@ -34,7 +34,7 @@ public class PublishTask : MSBuildAsyncTask | |||||||
|             AllowInteractiveLogin = false, |             AllowInteractiveLogin = false, | ||||||
|             VelopackBaseUrl = ServiceUrl, |             VelopackBaseUrl = ServiceUrl, | ||||||
|             ApiKey = ApiKey |             ApiKey = ApiKey | ||||||
|         }, cancellationToken).ConfigureAwait(false)) { |         }, false, cancellationToken).ConfigureAwait(false)) { | ||||||
|             Logger.LogWarning("Not logged into Velopack Flow service, skipping publish. Please run vpk login."); |             Logger.LogWarning("Not logged into Velopack Flow service, skipping publish. Please run vpk login."); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ using NuGet.Versioning; | |||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| using System.Text; | using System.Text; | ||||||
| using System.IO; | using System.IO; | ||||||
|  | using Markdig.Helpers; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if NET6_0_OR_GREATER | #if NET6_0_OR_GREATER | ||||||
| @@ -17,11 +19,15 @@ namespace Velopack.Packaging.Flow; | |||||||
| 
 | 
 | ||||||
| public interface IVelopackFlowServiceClient | public interface IVelopackFlowServiceClient | ||||||
| { | { | ||||||
|     Task<bool> LoginAsync(VelopackLoginOptions? options, CancellationToken cancellationToken); |     Task<bool> LoginAsync(VelopackLoginOptions? options, bool suppressOutput, CancellationToken cancellationToken); | ||||||
|     Task LogoutAsync(VelopackServiceOptions? options, CancellationToken cancellationToken); |     Task LogoutAsync(VelopackServiceOptions? options, CancellationToken cancellationToken); | ||||||
| 
 | 
 | ||||||
|     Task<Profile?> GetProfileAsync(VelopackServiceOptions? options, CancellationToken cancellationToken); |     Task<Profile?> GetProfileAsync(VelopackServiceOptions? options, CancellationToken cancellationToken); | ||||||
| 
 | 
 | ||||||
|  |     Task<string> InvokeEndpointAsync(VelopackServiceOptions? options, string endpointUri, | ||||||
|  |         string method, | ||||||
|  |         string? body, | ||||||
|  |         CancellationToken cancellationToken); | ||||||
|     Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, RuntimeOs os, CancellationToken cancellationToken); |     Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, RuntimeOs os, CancellationToken cancellationToken); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -33,10 +39,12 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
| 
 | 
 | ||||||
|     private AuthConfiguration? AuthConfiguration { get; set; } |     private AuthConfiguration? AuthConfiguration { get; set; } | ||||||
| 
 | 
 | ||||||
|     public async Task<bool> LoginAsync(VelopackLoginOptions? options, CancellationToken cancellationToken) |     public async Task<bool> LoginAsync(VelopackLoginOptions? options, bool suppressOutput, CancellationToken cancellationToken) | ||||||
|     { |     { | ||||||
|         options ??= new VelopackLoginOptions(); |         options ??= new VelopackLoginOptions(); | ||||||
|         Logger.LogInformation("Preparing to login to Velopack ({ServiceUrl})", options.VelopackBaseUrl); |         if (!suppressOutput) { | ||||||
|  |             Logger.LogInformation("Preparing to login to Velopack ({ServiceUrl})", options.VelopackBaseUrl); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         var authConfiguration = await GetAuthConfigurationAsync(options, cancellationToken); |         var authConfiguration = await GetAuthConfigurationAsync(options, cancellationToken); | ||||||
| 
 | 
 | ||||||
| @@ -45,7 +53,9 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
|         if (!string.IsNullOrWhiteSpace(options.ApiKey)) { |         if (!string.IsNullOrWhiteSpace(options.ApiKey)) { | ||||||
|             HttpClient.DefaultRequestHeaders.Authorization = new(HmacHelper.HmacScheme, options.ApiKey); |             HttpClient.DefaultRequestHeaders.Authorization = new(HmacHelper.HmacScheme, options.ApiKey); | ||||||
|             var profile = await GetProfileAsync(options, cancellationToken); |             var profile = await GetProfileAsync(options, cancellationToken); | ||||||
|             Logger.LogInformation("{UserName} logged into Velopack with API key", profile?.GetDisplayName()); |             if (!suppressOutput) { | ||||||
|  |                 Logger.LogInformation("{UserName} logged into Velopack with API key", profile?.GetDisplayName()); | ||||||
|  |             } | ||||||
|             return true; |             return true; | ||||||
|         } else { |         } else { | ||||||
|             AuthenticationResult? rv = null; |             AuthenticationResult? rv = null; | ||||||
| @@ -63,7 +73,9 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
|                 HttpClient.DefaultRequestHeaders.Authorization = new("Bearer", rv.IdToken ?? rv.AccessToken); |                 HttpClient.DefaultRequestHeaders.Authorization = new("Bearer", rv.IdToken ?? rv.AccessToken); | ||||||
|                 var profile = await GetProfileAsync(options, cancellationToken); |                 var profile = await GetProfileAsync(options, cancellationToken); | ||||||
| 
 | 
 | ||||||
|                 Logger.LogInformation("{UserName} logged into Velopack", profile?.GetDisplayName()); |                 if (!suppressOutput) { | ||||||
|  |                     Logger.LogInformation("{UserName} logged into Velopack", profile?.GetDisplayName()); | ||||||
|  |                 } | ||||||
|                 return true; |                 return true; | ||||||
|             } else { |             } else { | ||||||
|                 Logger.LogError("Failed to login to Velopack"); |                 Logger.LogError("Failed to login to Velopack"); | ||||||
| @@ -94,6 +106,35 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
|         return await HttpClient.GetFromJsonAsync<Profile>(endpoint, cancellationToken); |         return await HttpClient.GetFromJsonAsync<Profile>(endpoint, cancellationToken); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public async Task<string> InvokeEndpointAsync( | ||||||
|  |         VelopackServiceOptions? options, | ||||||
|  |         string endpointUri, | ||||||
|  |         string method, | ||||||
|  |         string? body, | ||||||
|  |         CancellationToken cancellationToken) | ||||||
|  |     { | ||||||
|  |         AssertAuthenticated(); | ||||||
|  |         var endpoint = GetEndpoint(endpointUri, options?.VelopackBaseUrl); | ||||||
|  | 
 | ||||||
|  |         HttpRequestMessage request = new(new HttpMethod(method), endpoint); | ||||||
|  |         if (body is not null) { | ||||||
|  |             request.Content = new StringContent(body, Encoding.UTF8, "application/json"); | ||||||
|  |         } | ||||||
|  |         HttpResponseMessage response = await HttpClient.SendAsync(request, cancellationToken); | ||||||
|  | 
 | ||||||
|  | #if NET6_0_OR_GREATER | ||||||
|  |         string responseBody = await response.Content.ReadAsStringAsync(cancellationToken); | ||||||
|  | #else | ||||||
|  |         string responseBody = await response.Content.ReadAsStringAsync(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |         if (response.IsSuccessStatusCode) { | ||||||
|  |             return responseBody; | ||||||
|  |         } else { | ||||||
|  |             throw new InvalidOperationException($"Failed to invoke endpoint {endpointUri} with status code {response.StatusCode}{Environment.NewLine}{responseBody}"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public async Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, |     public async Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, | ||||||
|         RuntimeOs os, CancellationToken cancellationToken) |         RuntimeOs os, CancellationToken cancellationToken) | ||||||
|     { |     { | ||||||
| @@ -164,7 +205,10 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
|         var endpoint = GetEndpoint("v1/releaseGroups/create", velopackBaseUrl); |         var endpoint = GetEndpoint("v1/releaseGroups/create", velopackBaseUrl); | ||||||
|         var response = await HttpClient.PostAsJsonAsync(endpoint, request, cancellationToken); |         var response = await HttpClient.PostAsJsonAsync(endpoint, request, cancellationToken); | ||||||
| 
 | 
 | ||||||
|         response.EnsureSuccessStatusCode(); |         if (!response.IsSuccessStatusCode) { | ||||||
|  |             string content = await response.Content.ReadAsStringAsync(cancellationToken); | ||||||
|  |             throw new InvalidOperationException($"Failed to create release group with version {version.ToNormalizedString()}{Environment.NewLine}Response status code: {response.StatusCode}{Environment.NewLine}{content}"); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return await response.Content.ReadFromJsonAsync<ReleaseGroup>(cancellationToken: cancellationToken) |         return await response.Content.ReadFromJsonAsync<ReleaseGroup>(cancellationToken: cancellationToken) | ||||||
|             ?? throw new InvalidOperationException($"Failed to create release group with version {version.ToNormalizedString()}"); |             ?? throw new InvalidOperationException($"Failed to create release group with version {version.ToNormalizedString()}"); | ||||||
| @@ -182,7 +226,7 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : | |||||||
|         var latestPath = Path.Combine(releaseDirectory, fileName); |         var latestPath = Path.Combine(releaseDirectory, fileName); | ||||||
| 
 | 
 | ||||||
|         using var fileStream = File.OpenRead(latestPath); |         using var fileStream = File.OpenRead(latestPath); | ||||||
|          | 
 | ||||||
|         using var fileContent = new StreamContent(fileStream); |         using var fileContent = new StreamContent(fileStream); | ||||||
|         formData.Add(fileContent, "File", fileName); |         formData.Add(fileContent, "File", fileName); | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -36,5 +36,10 @@ public static class HttpClientExtensions | |||||||
|         var json = await content.ReadAsStringAsync(); |         var json = await content.ReadAsStringAsync(); | ||||||
|         return Newtonsoft.Json.JsonConvert.DeserializeObject<TValue>(json); |         return Newtonsoft.Json.JsonConvert.DeserializeObject<TValue>(json); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static async Task<string> ReadAsStringAsync(this HttpContent content, CancellationToken _) | ||||||
|  |     { | ||||||
|  |         return await content.ReadAsStringAsync(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiCommand.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiCommand.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | #nullable enable | ||||||
|  | 
 | ||||||
|  | using System.Net.Http; | ||||||
|  | using Serilog.Core; | ||||||
|  | 
 | ||||||
|  | namespace Velopack.Vpk.Commands.Flow; | ||||||
|  | public class ApiCommand : VelopackServiceCommand | ||||||
|  | { | ||||||
|  |     public string Method { get; private set; } = ""; | ||||||
|  | 
 | ||||||
|  |     public string Endpoint { get; private set; } = ""; | ||||||
|  | 
 | ||||||
|  |     public string? Body { get; private set; } | ||||||
|  | 
 | ||||||
|  |     public ApiCommand() | ||||||
|  |         : base("api", "Invoke velopack flow API endpoints") | ||||||
|  |     { | ||||||
|  |         AddOption<string>(v => Method = v, "--method", "-m") | ||||||
|  |             .SetDescription("The HTTP method for the endpoint") | ||||||
|  |             .SetArgumentHelpName("METHOD") | ||||||
|  |             .SetRequired() | ||||||
|  |             .SetDefault(HttpMethod.Get.Method); | ||||||
|  | 
 | ||||||
|  |         AddOption<string>(v => Endpoint = v, "--endpoint", "-e") | ||||||
|  |             .SetDescription("The relative URI for the endpoint") | ||||||
|  |             .SetArgumentHelpName("URI") | ||||||
|  |             .SetRequired(); | ||||||
|  | 
 | ||||||
|  |         AddOption<string>(v => Body = v, "--body", "-b") | ||||||
|  |             .SetDescription("The body of the HTTP message") | ||||||
|  |             .SetArgumentHelpName("BODY"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public override void Initialize(LoggingLevelSwitch logLevelSwitch) | ||||||
|  |     { | ||||||
|  |         base.Initialize(logLevelSwitch); | ||||||
|  |         logLevelSwitch.MinimumLevel = Serilog.Events.LogEventLevel.Warning; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiCommandRunner.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiCommandRunner.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | using System.Threading; | ||||||
|  | using Serilog.Core; | ||||||
|  | using Velopack.Packaging.Abstractions; | ||||||
|  | using Velopack.Packaging.Flow; | ||||||
|  | 
 | ||||||
|  | namespace Velopack.Vpk.Commands.Flow; | ||||||
|  | public class ApiCommandRunner(IVelopackFlowServiceClient Client) : ICommand<ApiOptions> | ||||||
|  | { | ||||||
|  |     public async Task Run(ApiOptions options) | ||||||
|  |     { | ||||||
|  |         CancellationToken token = CancellationToken.None; | ||||||
|  |         if (!await Client.LoginAsync(new VelopackLoginOptions() { | ||||||
|  |             AllowCacheCredentials = true, | ||||||
|  |             AllowDeviceCodeFlow = false, | ||||||
|  |             AllowInteractiveLogin = false, | ||||||
|  |             ApiKey = options.ApiKey, | ||||||
|  |             VelopackBaseUrl = options.VelopackBaseUrl | ||||||
|  |         }, true, token)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         string response = await Client.InvokeEndpointAsync(options, options.Endpoint, options.Method, options.Body, token); | ||||||
|  |         Console.WriteLine(response); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										11
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/vpk/Velopack.Vpk/Commands/Flow/ApiOptions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | #nullable enable | ||||||
|  | using Velopack.Packaging.Flow; | ||||||
|  | 
 | ||||||
|  | namespace Velopack.Vpk.Commands.Flow; | ||||||
|  | 
 | ||||||
|  | public sealed class ApiOptions : VelopackServiceOptions | ||||||
|  | { | ||||||
|  |     public string Endpoint { get; set; } = ""; | ||||||
|  |     public string Method { get; set; } = ""; | ||||||
|  |     public string? Body { get; set; } | ||||||
|  | } | ||||||
| @@ -12,6 +12,6 @@ public class LoginCommandRunner(IVelopackFlowServiceClient Client) : ICommand<Lo | |||||||
|         await Client.LoginAsync(new() { |         await Client.LoginAsync(new() { | ||||||
|             VelopackBaseUrl = options.VelopackBaseUrl, |             VelopackBaseUrl = options.VelopackBaseUrl, | ||||||
|             ApiKey = options.ApiKey, |             ApiKey = options.ApiKey, | ||||||
|         }, CancellationToken.None); |         }, false, CancellationToken.None); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ public class PublishCommandRunner(IVelopackFlowServiceClient Client) : ICommand< | |||||||
|             AllowInteractiveLogin = false, |             AllowInteractiveLogin = false, | ||||||
|             ApiKey = options.ApiKey, |             ApiKey = options.ApiKey, | ||||||
|             VelopackBaseUrl = options.VelopackBaseUrl |             VelopackBaseUrl = options.VelopackBaseUrl | ||||||
|         }, token)) { |         }, false, token)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| using Humanizer; | using Humanizer; | ||||||
| using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||||
|  | using Serilog.Core; | ||||||
| 
 | 
 | ||||||
| namespace Velopack.Vpk.Commands; | namespace Velopack.Vpk.Commands; | ||||||
| 
 | 
 | ||||||
| @@ -70,6 +71,9 @@ public class BaseCommand : CliCommand | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public virtual void Initialize(LoggingLevelSwitch logLevelSwitch) | ||||||
|  |     { } | ||||||
|  | 
 | ||||||
|     public ParseResult ParseAndApply(string command, IConfiguration config = null, RuntimeOs? targetOs = null) |     public ParseResult ParseAndApply(string command, IConfiguration config = null, RuntimeOs? targetOs = null) | ||||||
|     { |     { | ||||||
|         var x = Parse(command); |         var x = Parse(command); | ||||||
|   | |||||||
| @@ -7,11 +7,11 @@ using Spectre.Console.Rendering; | |||||||
| 
 | 
 | ||||||
| namespace Velopack.Vpk.Logging; | namespace Velopack.Vpk.Logging; | ||||||
| 
 | 
 | ||||||
| public class MySpectreConsoleSink : ILogEventSink | public class SpectreConsoleSink : ILogEventSink | ||||||
| { | { | ||||||
|     private readonly string _dirtmp; |     private readonly string _dirtmp; | ||||||
| 
 | 
 | ||||||
|     public MySpectreConsoleSink() |     public SpectreConsoleSink() | ||||||
|     { |     { | ||||||
|         _dirtmp = Path.GetTempPath(); |         _dirtmp = Path.GetTempPath(); | ||||||
|     } |     } | ||||||
| @@ -53,13 +53,13 @@ public class MySpectreConsoleSink : ILogEventSink | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| public static class MySpectreConsoleSinkExtensions | public static class SpectreConsoleSinkExtensions | ||||||
| { | { | ||||||
|     public static LoggerConfiguration Spectre( |     public static LoggerConfiguration Spectre( | ||||||
|         this LoggerSinkConfiguration loggerConfiguration, |         this LoggerSinkConfiguration loggerConfiguration, | ||||||
|         LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, |         LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, | ||||||
|         LoggingLevelSwitch levelSwitch = null) |         LoggingLevelSwitch levelSwitch = null) | ||||||
|     { |     { | ||||||
|         return loggerConfiguration.Sink(new MySpectreConsoleSink(), restrictedToMinimumLevel, levelSwitch); |         return loggerConfiguration.Sink(new SpectreConsoleSink(), restrictedToMinimumLevel, levelSwitch); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -36,6 +36,7 @@ public static partial class OptionMapper | |||||||
|     public static partial LoginOptions ToOptions(this LoginCommand cmd); |     public static partial LoginOptions ToOptions(this LoginCommand cmd); | ||||||
|     public static partial LogoutOptions ToOptions(this LogoutCommand cmd); |     public static partial LogoutOptions ToOptions(this LogoutCommand cmd); | ||||||
|     public static partial PublishOptions ToOptions(this PublishCommand cmd); |     public static partial PublishOptions ToOptions(this PublishCommand cmd); | ||||||
|  |     public static partial ApiOptions ToOptions(this ApiCommand cmd); | ||||||
| 
 | 
 | ||||||
|     private static DirectoryInfo StringToDirectoryInfo(string t) |     private static DirectoryInfo StringToDirectoryInfo(string t) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ using Microsoft.Extensions.Configuration; | |||||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||||
| using Microsoft.Extensions.Hosting; | using Microsoft.Extensions.Hosting; | ||||||
| using Serilog; | using Serilog; | ||||||
|  | using Serilog.Core; | ||||||
| using Serilog.Events; | using Serilog.Events; | ||||||
| using Velopack.Deployment; | using Velopack.Deployment; | ||||||
| using Velopack.Packaging.Abstractions; | using Velopack.Packaging.Abstractions; | ||||||
| @@ -156,6 +157,10 @@ public class Program | |||||||
|         HideCommand(rootCommand.AddCommand<LogoutCommand, LogoutCommandRunner, LogoutOptions>(provider)); |         HideCommand(rootCommand.AddCommand<LogoutCommand, LogoutCommandRunner, LogoutOptions>(provider)); | ||||||
|         HideCommand(rootCommand.AddCommand<PublishCommand, PublishCommandRunner, PublishOptions>(provider)); |         HideCommand(rootCommand.AddCommand<PublishCommand, PublishCommandRunner, PublishOptions>(provider)); | ||||||
| 
 | 
 | ||||||
|  |         var flowCommand = new CliCommand("flow", "Commands for interacting with Velopack Flow.") { Hidden = true }; | ||||||
|  |         HideCommand(flowCommand.AddCommand<ApiCommand, ApiCommandRunner, ApiOptions>(provider)); | ||||||
|  |         rootCommand.Add(flowCommand);  | ||||||
|  | 
 | ||||||
|         var cli = new CliConfiguration(rootCommand); |         var cli = new CliConfiguration(rootCommand); | ||||||
|         return await cli.InvokeAsync(args); |         return await cli.InvokeAsync(args); | ||||||
| 
 | 
 | ||||||
| @@ -173,8 +178,11 @@ public class Program | |||||||
| 
 | 
 | ||||||
|     private static void SetupLogging(IHostApplicationBuilder builder, bool verbose, bool legacyConsole) |     private static void SetupLogging(IHostApplicationBuilder builder, bool verbose, bool legacyConsole) | ||||||
|     { |     { | ||||||
|  |         var levelSwitch = new LoggingLevelSwitch { | ||||||
|  |             MinimumLevel = verbose ? LogEventLevel.Debug : LogEventLevel.Information | ||||||
|  |         }; | ||||||
|         var conf = new LoggerConfiguration() |         var conf = new LoggerConfiguration() | ||||||
|             .MinimumLevel.Is(verbose ? LogEventLevel.Debug : LogEventLevel.Information) |             .MinimumLevel.ControlledBy(levelSwitch) | ||||||
|             .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) |             .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) | ||||||
|             .MinimumLevel.Override("System", LogEventLevel.Warning); |             .MinimumLevel.Override("System", LogEventLevel.Warning); | ||||||
| 
 | 
 | ||||||
| @@ -186,6 +194,7 @@ public class Program | |||||||
|             builder.Services.AddSingleton<IFancyConsole, SpectreConsole>(); |             builder.Services.AddSingleton<IFancyConsole, SpectreConsole>(); | ||||||
|             conf.WriteTo.Spectre(); |             conf.WriteTo.Spectre(); | ||||||
|         } |         } | ||||||
|  |         builder.Services.AddSingleton(levelSwitch); | ||||||
|         builder.Services.AddSingleton<IConsole>(sp => sp.GetRequiredService<IFancyConsole>()); |         builder.Services.AddSingleton<IConsole>(sp => sp.GetRequiredService<IFancyConsole>()); | ||||||
| 
 | 
 | ||||||
|         Log.Logger = conf.CreateLogger(); |         Log.Logger = conf.CreateLogger(); | ||||||
| @@ -247,6 +256,9 @@ public static class ProgramCommandExtensions | |||||||
|             var console = provider.GetRequiredService<IFancyConsole>(); |             var console = provider.GetRequiredService<IFancyConsole>(); | ||||||
|             var config = provider.GetRequiredService<IConfiguration>(); |             var config = provider.GetRequiredService<IConfiguration>(); | ||||||
|             var defaults = provider.GetRequiredService<VelopackDefaults>(); |             var defaults = provider.GetRequiredService<VelopackDefaults>(); | ||||||
|  |             var logLevelSwitch = provider.GetRequiredService<LoggingLevelSwitch>(); | ||||||
|  | 
 | ||||||
|  |             command.Initialize(logLevelSwitch); | ||||||
| 
 | 
 | ||||||
|             logger.LogInformation($"[bold]{Program.INTRO}[/]"); |             logger.LogInformation($"[bold]{Program.INTRO}[/]"); | ||||||
|             var updateCheck = new UpdateChecker(logger); |             var updateCheck = new UpdateChecker(logger); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user