diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index abcd641d07..e86eccdf2c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.NuGet; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli @@ -17,15 +18,18 @@ namespace Volo.Abp.Cli protected ICommandLineArgumentParser CommandLineArgumentParser { get; } protected ICommandSelector CommandSelector { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; } + protected NuGetService NuGetService { get; } public CliService( ICommandLineArgumentParser commandLineArgumentParser, ICommandSelector commandSelector, - IHybridServiceScopeFactory serviceScopeFactory) + IHybridServiceScopeFactory serviceScopeFactory, + NuGetService nugetService) { CommandLineArgumentParser = commandLineArgumentParser; CommandSelector = commandSelector; ServiceScopeFactory = serviceScopeFactory; + NuGetService = nugetService; Logger = NullLogger.Instance; } @@ -35,6 +39,8 @@ namespace Volo.Abp.Cli Logger.LogInformation($"ABP CLI, version {GetCliVersion()}."); Logger.LogInformation("https://abp.io"); + await CheckHasNewVersion(); + var commandLineArgs = CommandLineArgumentParser.Parse(args); var commandType = CommandSelector.Select(commandLineArgs); @@ -57,6 +63,19 @@ namespace Volo.Abp.Cli } } + private async Task CheckHasNewVersion() + { + var currentVersion = GetCliVersion(); + var latestVersion = await NuGetService.GetLatestVersionAsync("Volo.Abp.Cli"); + + if (!string.IsNullOrEmpty(latestVersion) && currentVersion != latestVersion) + { + Logger.LogInformation(""); + Logger.LogWarning("Cli has a new version. Please update."); + Logger.LogWarning("Update Command: dotnet tool update -g Volo.Abp.Cli"); + } + } + private static string GetCliVersion() { return typeof(CliService) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs new file mode 100644 index 0000000000..e9130ac8b6 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Volo.Abp.Json; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; + +namespace Volo.Abp.Cli.NuGet +{ + public class NuGetService : ISingletonDependency + { + protected IJsonSerializer JsonSerializer { get; } + protected ICancellationTokenProvider CancellationTokenProvider { get; } + + + public NuGetService( + IJsonSerializer jsonSerializer, + ICancellationTokenProvider cancellationTokenProvider) + { + JsonSerializer = jsonSerializer; + CancellationTokenProvider = cancellationTokenProvider; + } + + public async Task GetLatestVersionAsync(string packageId,bool includePreviews = false) + { + using (var client = new HttpClient()) + { + client.Timeout = TimeSpan.FromSeconds(30); + + var responseMessage = await client.GetAsync( + $"https://api.nuget.org/v3-flatcontainer/{packageId.ToLowerInvariant()}/index.json", + CancellationTokenProvider.Token); + if (!responseMessage.IsSuccessStatusCode) + { + throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); + } + + var result = await responseMessage.Content.ReadAsStringAsync(); + + var versions = JsonSerializer.Deserialize(result).Versions; + if (!includePreviews) + { + versions = versions + .Where(x => !x.Contains("beta") && !x.Contains("preview") && !x.Contains("alpha") && !x.Contains("rc")) + .ToList(); + } + + return versions.Count > 0 ? versions.Last() : null; + } + } + + public class NuGetVersionResultDto + { + [JsonProperty("versions")] + public List Versions { get; set; } + } + } +} \ No newline at end of file