Browse Source

Merge pull request #1295 from Xeevis/cli

Improve CLI version checking
pull/1305/head
Yunus Emre Kalkan 7 years ago
committed by GitHub
parent
commit
bca58a9081
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj
  2. 163
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs
  3. 24
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs
  4. 5
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

1
framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj

@ -15,6 +15,7 @@
<PackageReference Include="Ionic.Zip" Version="1.9.1.8" />
<PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="NuGet.Versioning" Version="5.1.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
<PackageReference Include="System.Security.Permissions" Version="4.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.1.0" />

163
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs

@ -1,12 +1,12 @@
using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NuGet.Versioning;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands;
using Volo.Abp.Cli.NuGet;
@ -18,7 +18,6 @@ namespace Volo.Abp.Cli
public class CliService : ITransientDependency
{
public ILogger<CliService> Logger { get; set; }
protected ICommandLineArgumentParser CommandLineArgumentParser { get; }
protected ICommandSelector CommandSelector { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
@ -40,11 +39,10 @@ namespace Volo.Abp.Cli
public async Task RunAsync(string[] args)
{
Logger.LogInformation($"ABP CLI, version {GetCliVersion()}.");
Logger.LogInformation("ABP CLI (https://abp.io)");
Logger.LogInformation("https://abp.io");
await CheckForNewVersion();
await CheckCliVersionAsync();
CheckDependencies();
var commandLineArgs = CommandLineArgumentParser.Parse(args);
@ -72,7 +70,7 @@ namespace Volo.Abp.Cli
private void CheckDependencies()
{
var installedNpmPackages = CmdHelper.RunCmdAndGetOutput("npm list -g --depth 0");
if (!installedNpmPackages.Contains(" yarn@"))
{
InstallYarn();
@ -95,47 +93,144 @@ namespace Volo.Abp.Cli
CmdHelper.RunCmd("npm install gulp -g");
}
private async Task CheckForNewVersion()
private async Task CheckCliVersionAsync()
{
var assembly = typeof(CliService).Assembly;
var toolPath = GetToolPath(assembly);
var currentCliVersion = await GetCurrentCliVersion(toolPath, assembly);
var updateChannel = GetUpdateChannel(currentCliVersion);
Logger.LogInformation($"Version {currentCliVersion} ({updateChannel} channel)");
try
{
var currentVersion = GetCliVersion();
var latestVersion = await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli");
var latestVersion = await GetLatestVersion(updateChannel);
if (!latestVersion.IsNullOrEmpty() && currentVersion != latestVersion)
if (latestVersion != null & latestVersion > currentCliVersion)
{
Logger.LogInformation("");
Logger.LogWarning("ABP CLI has a newer version (" + latestVersion + "). Please update to get the latest features and fixes.");
Logger.LogWarning("");
Logger.LogWarning("Update Command: ");
Logger.LogWarning(" dotnet tool update -g Volo.Abp.Cli");
Logger.LogWarning("");
LogNewVersionInfo(updateChannel, latestVersion, toolPath);
}
}
catch (Exception e)
{
Logger.LogWarning("Could not get the latest version infom from NuGet.org:");
Logger.LogWarning("Unable to retrieve the latest version");
Logger.LogWarning(e.Message);
}
}
private static string GetCliVersion()
private static string GetToolPath(Assembly assembly)
{
var version = typeof(CliService)
.Assembly
.GetFileVersion();
if (!assembly.Location.Contains(".store"))
{
return null;
}
/* Assembly versions are like "2.4.0.0", but NuGet removes the last "0" here,
* like "2.4.0".
* So, we need to remove it from the assembly version to match to the NuGet version.
*/
return assembly.Location.Substring(0, assembly.Location.IndexOf(".store", StringComparison.Ordinal));
}
if (version.Split('.').Length == 4)
private async Task<SemanticVersion> GetCurrentCliVersion(string toolPath, Assembly assembly)
{
SemanticVersion currentCliVersion = default;
if (!string.IsNullOrEmpty(toolPath))
{
version = version.RemovePostFix(".0");
var consoleOutput = new StringReader(CmdHelper.RunCmdAndGetOutput($"dotnet tool list --tool-path {toolPath}"));
string line;
while ((line = await consoleOutput.ReadLineAsync()) != null)
{
if (line.StartsWith("Volo.Abp.Cli", StringComparison.InvariantCultureIgnoreCase))
{
var version = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries)[1];
SemanticVersion.TryParse(version, out currentCliVersion);
break;
}
}
}
if (currentCliVersion == null)
{
// If not a tool executable, fallback to assembly version and treat as dev without updates
// Assembly revisions are not supported by SemVer scheme required for NuGet, trim to {major}.{minor}.{patch}
var assemblyVersion = string.Join(".", assembly.GetFileVersion().Split('.').Take(3));
return SemanticVersion.Parse(assemblyVersion + "-dev");
}
return version;
return currentCliVersion;
}
private static UpdateChannel GetUpdateChannel(SemanticVersion currentCliVersion)
{
if (!currentCliVersion.IsPrerelease)
{
return UpdateChannel.Stable;
}
if (currentCliVersion.Release.Contains("preview"))
{
return UpdateChannel.Nightly;
}
if (currentCliVersion.Release.Contains("dev"))
{
return UpdateChannel.Development;
}
return UpdateChannel.Prerelease;
}
private async Task<SemanticVersion> GetLatestVersion(UpdateChannel updateChannel)
{
switch (updateChannel)
{
case UpdateChannel.Stable:
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli");
case UpdateChannel.Prerelease:
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli", includePreviews: true);
case UpdateChannel.Nightly:
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli", includeNightly: true);
default:
return default;
}
}
private void LogNewVersionInfo(UpdateChannel updateChannel, SemanticVersion latestVersion, string toolPath)
{
Logger.LogWarning(
$"ABP CLI has a newer {updateChannel.ToString().ToLowerInvariant()} version {latestVersion}, please update to get the latest features and fixes.");
Logger.LogWarning("");
Logger.LogWarning("Update Command: ");
// Update command doesn't support prerelease versions https://github.com/dotnet/sdk/issues/2551 workaround is to uninstall & install
switch (updateChannel)
{
case UpdateChannel.Stable:
Logger.LogWarning($" dotnet tool update --tool-path {toolPath} Volo.Abp.Cli");
break;
case UpdateChannel.Prerelease:
Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli");
Logger.LogWarning($" dotnet tool install --tool-path {toolPath} --version {latestVersion} Volo.Abp.Cli");
break;
case UpdateChannel.Nightly:
Logger.LogWarning($" dotnet tool uninstall --tool-path {toolPath} Volo.Abp.Cli");
Logger.LogWarning(
$" dotnet tool install --tool-path {toolPath} --add-source https://www.myget.org/F/abp-nightly/api/v3/index.json --version {latestVersion} Volo.Abp.Cli");
break;
}
Logger.LogWarning("");
}
protected enum UpdateChannel
{
Development,
Stable,
Prerelease,
Nightly
}
}
}
}

24
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using NuGet.Versioning;
using System;
using System.Collections.Generic;
using System.Linq;
@ -23,16 +24,17 @@ namespace Volo.Abp.Cli.NuGet
CancellationTokenProvider = cancellationTokenProvider;
}
public async Task<string> GetLatestVersionOrNullAsync(string packageId, bool includePreviews = false)
public async Task<SemanticVersion> GetLatestVersionOrNullAsync(string packageId, bool includePreviews = false, bool includeNightly = 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
);
var url = includeNightly ?
$"https://www.myget.org/F/abp-nightly/api/v3/flatcontainer/{packageId.ToLowerInvariant()}/index.json" :
$"https://api.nuget.org/v3-flatcontainer/{packageId.ToLowerInvariant()}/index.json";
var responseMessage = await client.GetAsync(url, CancellationTokenProvider.Token);
if (!responseMessage.IsSuccessStatusCode)
{
@ -41,16 +43,14 @@ namespace Volo.Abp.Cli.NuGet
var result = await responseMessage.Content.ReadAsStringAsync();
var versions = JsonSerializer.Deserialize<NuGetVersionResultDto>(result).Versions;
var versions = JsonSerializer.Deserialize<NuGetVersionResultDto>(result).Versions.Select(x => SemanticVersion.Parse(x));
if (!includePreviews)
if (!includePreviews && !includeNightly)
{
versions = versions
.Where(x => !x.Contains("beta") && !x.Contains("preview") && !x.Contains("alpha") && !x.Contains("rc"))
.ToList();
versions = versions.Where(x => !x.IsPrerelease);
}
return versions.Count > 0 ? versions.Last() : null;
return versions.Any() ? versions.Max() : null;
}
}
@ -60,4 +60,4 @@ namespace Volo.Abp.Cli.NuGet
public List<string> Versions { get; set; }
}
}
}
}

5
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

@ -3,6 +3,7 @@ using System.IO;
using System.Text;
using Volo.Abp.Cli.NuGet;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.ProjectModification
{
@ -75,8 +76,8 @@ namespace Volo.Abp.Cli.ProjectModification
content = content.Substring(indexAfterSecondQuote);
var indexOfThirdQuote = content.IndexOf("\"", StringComparison.Ordinal);
var version = _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews);
var version = AsyncHelper.RunSync(() => _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews));
returningText.Append(version);
index = indexOfPackageReference + packageReferenceStartText.Length + indexAfterQuote + indexAfterSecondQuote + indexOfThirdQuote;

Loading…
Cancel
Save