|
|
|
@ -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 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|