Merge pull request #4782 from abpframework/abp-prerelease-compatibility

Abp prerelease compatibility
pull/4842/head
İsmail ÇAĞDAŞ 5 years ago committed by GitHub
commit ba484e737b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -90,6 +90,7 @@ abp new Acme.BookStore
* **`console`**: [Console template](Startup-Templates/Console.md).
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
* `--preview`: Use latest pre-release version (Only if `--version ` is not specified and there is at least one pre-release after latest stable version).
* `--template-source` or `-ts`: Specifies a custom template source to use to build the project. Local and network sources can be used(Like `D:\local-template` or `https://.../my-template-file.zip`).
* `--create-solution-folder` or `-csf`: Specifies if the project will be in a new folder in the output folder or directly the output folder.
* `--connection-string` or `-cs`: Overwrites the default connection strings in all `appsettings.json` files. The default connection string is `Server=localhost;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true` for EF Core and it is configured to use the SQL Server. If you want to use the EF Core, but need to change the DBMS, you can change it as [described here](Entity-Framework-Core-Other-DBMS.md) (after creating the solution).
@ -196,12 +197,12 @@ abp generate-proxy --apiUrl https://localhost:44305 --ui angular --module all
### switch-to-preview
You can use this command to switch your project to latest preview version of the ABP framework packages.
You can use this command to switch your project to latest **nightly** preview version of the ABP framework packages.
Usage:
````bash
abp switch-to-preview [options]
abp switch-to-nightly [options]
````
#### Options
@ -210,7 +211,7 @@ abp switch-to-preview [options]
### switch-to-stable
If you're using the ABP Framework preview packages, you can switch back to stable version using this command.
If you're using the ABP Framework preview packages, you can switch back to latest stable version using this command.
Usage:

@ -1,5 +1,4 @@
using System;
using System.Text;
using System.Text;
using Volo.Abp.Cli.Commands;
using Volo.Abp.Domain;
using Volo.Abp.IdentityModel;
@ -31,8 +30,9 @@ namespace Volo.Abp.Cli
options.Commands["logout"] = typeof(LogoutCommand);
options.Commands["generate-proxy"] = typeof(GenerateProxyCommand);
options.Commands["suite"] = typeof(SuiteCommand);
options.Commands["switch-to-preview"] = typeof(SwitchNightlyPreviewCommand);
options.Commands["switch-to-stable"] = typeof(SwitchStableCommand);
options.Commands["switch-to-preview"] = typeof(SwitchToPreviewCommand);
options.Commands["switch-to-stable"] = typeof(SwitchToStableCommand);
options.Commands["switch-to-nightly"] = typeof(SwitchToNightlyCommand);
options.Commands["translate"] = typeof(TranslateCommand);
});
}

@ -158,7 +158,7 @@ namespace Volo.Abp.Cli
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli");
case UpdateChannel.Prerelease:
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli", includePreviews: true);
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli", includeReleaseCandidates: true);
case UpdateChannel.Nightly:
return await NuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Cli", includeNightly: true);

@ -75,6 +75,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(" -s|--solution <solution-file> Specify the solution file explicitly.");
sb.AppendLine(" --skip-db-migrations <boolean> Specify if a new migration will be added or not.");
sb.AppendLine(" -sp|--startup-project <startup-project-path> Relative path to the project folder of the startup project. Default value is the current folder.");
sb.AppendLine(" -v|--version <version> Specify the version of the module. Default is your project's ABP version.");
sb.AppendLine("");
sb.AppendLine("Examples:");
sb.AppendLine("");
@ -152,7 +153,7 @@ namespace Volo.Abp.Cli.Commands
public const string Skip = "skip-db-migrations";
}
public static class StartupProject
public static class StartupProject
{
public const string Short = "sp";
public const string Long = "startup-project";

@ -34,9 +34,12 @@ namespace Volo.Abp.Cli.Commands
);
}
var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long);
await ProjectNugetPackageAdder.AddAsync(
GetProjectFile(commandLineArgs),
commandLineArgs.Target
commandLineArgs.Target,
version
);
}
@ -55,6 +58,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("Options:");
sb.AppendLine("");
sb.AppendLine(" -p|--project <project-file> Specify the project file explicitly.");
sb.AppendLine(" -v|--version <version> Specify the version of the package. Default is your project's ABP version or latest ABP version.");
sb.AppendLine("");
sb.AppendLine("Examples:");
sb.AppendLine("");
@ -119,6 +123,12 @@ namespace Volo.Abp.Cli.Commands
public const string Short = "p";
public const string Long = "project";
}
public static class Version
{
public const string Short = "v";
public const string Long = "version";
}
}
}
}
}

@ -61,7 +61,7 @@ namespace Volo.Abp.Cli.Commands
}
commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command);
await _sourceCodeDownloadService.DownloadAsync(
commandLineArgs.Target, outputFolder, version, gitHubAbpLocalRepositoryPath, gitHubVoloLocalRepositoryPath, commandLineArgs.Options);
}
@ -99,6 +99,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("");
sb.AppendLine("-o|--output-folder <output-folder> (default: current folder)");
sb.AppendLine("-v|--version <version> (default: latest version)");
sb.AppendLine("--preview (Use latest pre-release version if there is at least one pre-release after latest stable version)");
sb.AppendLine("");
sb.AppendLine("Examples:");
sb.AppendLine("");
@ -138,6 +139,11 @@ namespace Volo.Abp.Cli.Commands
public const string Short = "v";
public const string Long = "version";
}
public static class Preview
{
public const string Long = "preview";
}
}
}
}

@ -62,6 +62,12 @@ namespace Volo.Abp.Cli.Commands
Logger.LogInformation("Tiered: yes");
}
var preview = commandLineArgs.Options.ContainsKey(Options.Preview.Long);
if (preview)
{
Logger.LogInformation("Preview: yes if any exist for next version.");
}
var databaseProvider = GetDatabaseProvider(commandLineArgs);
if (databaseProvider != DatabaseProvider.NotSpecified)
{
@ -218,6 +224,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("-d|--database-provider <database-provider> (if supported by the template)");
sb.AppendLine("-o|--output-folder <output-folder> (default: current folder)");
sb.AppendLine("-v|--version <version> (default: latest version)");
sb.AppendLine("--preview (Use latest pre-release version if there is at least one pre-release after latest stable version)");
sb.AppendLine("-ts|--template-source <template-source> (your local or network abp template source)");
sb.AppendLine("-csf|--create-solution-folder (default: true)");
sb.AppendLine("-cs|--connection-string <connection-string> (your database connection string)");
@ -369,6 +376,11 @@ namespace Volo.Abp.Cli.Commands
{
public const string Long = "tiered";
}
public static class Preview
{
public const string Long = "preview";
}
}
}
}

@ -6,18 +6,18 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands
{
public class SwitchNightlyPreviewCommand : IConsoleCommand, ITransientDependency
public class SwitchToNightlyCommand : IConsoleCommand, ITransientDependency
{
private readonly PackageSourceSwitcher _packageSourceSwitcher;
private readonly PackagePreviewSwitcher _packagePreviewSwitcher;
public SwitchNightlyPreviewCommand(PackageSourceSwitcher packageSourceSwitcher)
public SwitchToNightlyCommand(PackagePreviewSwitcher packagePreviewSwitcher)
{
_packageSourceSwitcher = packageSourceSwitcher;
_packagePreviewSwitcher = packagePreviewSwitcher;
}
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
await _packageSourceSwitcher.SwitchToPreview(commandLineArgs);
await _packagePreviewSwitcher.SwitchToNightlyPreview(commandLineArgs);
}
public string GetUsageInfo()
@ -26,8 +26,8 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("");
sb.AppendLine("Usage:");
sb.AppendLine(" abp switch-to-preview [options]");
sb.AppendLine("");
sb.AppendLine(" abp switch-to-nightly [options]");
sb.AppendLine("");
sb.AppendLine("Options:");
sb.AppendLine("-sd|--solution-directory");
sb.AppendLine("");
@ -41,4 +41,4 @@ namespace Volo.Abp.Cli.Commands
return "Switches packages to nightly preview ABP version.";
}
}
}
}

@ -0,0 +1,44 @@
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands
{
public class SwitchToPreviewCommand : IConsoleCommand, ITransientDependency
{
private readonly PackagePreviewSwitcher _packagePreviewSwitcher;
public SwitchToPreviewCommand(PackagePreviewSwitcher packagePreviewSwitcher)
{
_packagePreviewSwitcher = packagePreviewSwitcher;
}
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
await _packagePreviewSwitcher.SwitchToPreview(commandLineArgs);
}
public string GetUsageInfo()
{
var sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("Usage:");
sb.AppendLine(" abp switch-to-preview [options]");
sb.AppendLine("");
sb.AppendLine("Options:");
sb.AppendLine("-sd|--solution-directory");
sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
return sb.ToString();
}
public string GetShortDescription()
{
return "Switches packages to preview ABP version.";
}
}
}

@ -6,18 +6,18 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands
{
public class SwitchStableCommand : IConsoleCommand, ITransientDependency
public class SwitchToStableCommand : IConsoleCommand, ITransientDependency
{
private readonly PackageSourceSwitcher _packageSourceSwitcher;
private readonly PackagePreviewSwitcher _packagePreviewSwitcher;
public SwitchStableCommand(PackageSourceSwitcher packageSourceSwitcher)
public SwitchToStableCommand(PackagePreviewSwitcher packagePreviewSwitcher)
{
_packageSourceSwitcher = packageSourceSwitcher;
_packagePreviewSwitcher = packagePreviewSwitcher;
}
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
await _packageSourceSwitcher.SwitchToStable(commandLineArgs);
await _packagePreviewSwitcher.SwitchToStable(commandLineArgs);
}
public string GetUsageInfo()
@ -41,4 +41,4 @@ namespace Volo.Abp.Cli.Commands
return "Switches packages to stable ABP version from preview version.";
}
}
}
}

@ -39,7 +39,7 @@ namespace Volo.Abp.Cli.NuGet
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.Instance;
}
public async Task<SemanticVersion> GetLatestVersionOrNullAsync(string packageId, bool includePreviews = false, bool includeNightly = false)
public async Task<SemanticVersion> GetLatestVersionOrNullAsync(string packageId, bool includeNightly = false, bool includeReleaseCandidates = false)
{
if (AuthService.IsLoggedIn())
{
@ -78,11 +78,12 @@ namespace Volo.Abp.Cli.NuGet
var versions = JsonSerializer
.Deserialize<NuGetVersionResultDto>(responseContent)
.Versions
.Select(SemanticVersion.Parse);
.Select(SemanticVersion.Parse)
.OrderByDescending(v=> v, new VersionComparer()).ToList();
if (!includePreviews && !includeNightly)
if (!includeNightly && !includeReleaseCandidates)
{
versions = versions.Where(x => !x.IsPrerelease);
versions = versions.Where(x => !x.IsPrerelease).ToList();
}
var semanticVersions = versions.ToList();

@ -52,10 +52,11 @@ namespace Volo.Abp.Cli.ProjectBuilding
string name,
string type,
string version = null,
string templateSource = null)
string templateSource = null,
bool includePreReleases = false)
{
DirectoryHelper.CreateIfNotExists(CliPaths.TemplateCache);
var latestVersion = version ?? await GetLatestSourceCodeVersionAsync(name, type);
var latestVersion = version ?? await GetLatestSourceCodeVersionAsync(name, type, null, includePreReleases);
if (version == null)
{
@ -110,7 +111,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
Name = name,
Type = type,
TemplateSource = templateSource,
Version = version
Version = version,
IncludePreReleases = includePreReleases
}
);
@ -122,7 +124,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
return new TemplateFile(fileContent, version, latestVersion, nugetVersion);
}
private async Task<string> GetLatestSourceCodeVersionAsync(string name, string type, string url = null)
private async Task<string> GetLatestSourceCodeVersionAsync(string name, string type, string url = null, bool includePreReleases = false)
{
if (url == null)
{
@ -137,7 +139,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
url,
new StringContent(
JsonSerializer.Serialize(
new GetLatestSourceCodeVersionDto { Name = name }
new GetLatestSourceCodeVersionDto { Name = name, IncludePreReleases = includePreReleases }
),
Encoding.UTF8,
MimeTypes.Application.Json
@ -171,7 +173,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
url,
new StringContent(
JsonSerializer.Serialize(
new GetTemplateNugetVersionDto { Name = name, Version = version }
new GetTemplateNugetVersionDto { Name = name, Version = version}
),
Encoding.UTF8,
MimeTypes.Application.Json
@ -260,11 +262,15 @@ namespace Volo.Abp.Cli.ProjectBuilding
public string Type { get; set; }
public string TemplateSource { get; set; }
public bool IncludePreReleases { get; set; }
}
public class GetLatestSourceCodeVersionDto
{
public string Name { get; set; }
public bool IncludePreReleases { get; set; }
}
public class GetTemplateNugetVersionDto
@ -272,6 +278,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
public string Name { get; set; }
public string Version { get; set; }
public bool IncludePreReleases { get; set; }
}
public class GetVersionResultDto

@ -9,7 +9,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
string name,
string type,
[CanBeNull] string version = null,
[CanBeNull] string templateSource = null
[CanBeNull] string templateSource = null,
bool includePreReleases = false
);
}
}
}

@ -48,7 +48,9 @@ namespace Volo.Abp.Cli.ProjectBuilding
var templateFile = await SourceCodeStore.GetAsync(
args.TemplateName,
SourceCodeTypes.Module,
args.Version
args.Version,
null,
args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long)
);
var apiKeyResult = await ApiKeyService.GetApiKeyOrNullAsync();

@ -57,7 +57,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
args.TemplateName,
SourceCodeTypes.Template,
args.Version,
args.TemplateSource
args.TemplateSource,
args.ExtraProperties.ContainsKey(NewCommand.Options.Preview.Long)
);
DeveloperApiKeyResult apiKeyResult = null;
@ -119,6 +120,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
var options = args.ExtraProperties
.Where(x => !x.Key.Equals(CliConsts.Command, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.Tiered.Long, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.Preview.Long, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.DatabaseProvider.Long, StringComparison.InvariantCultureIgnoreCase) &&
!x.Key.Equals(NewCommand.Options.DatabaseProvider.Short, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.OutputFolder.Long, StringComparison.InvariantCultureIgnoreCase) &&

@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Versioning;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
@ -42,7 +43,7 @@ namespace Volo.Abp.Cli.ProjectModification
Logger = NullLogger<NpmPackagesUpdater>.Instance;
}
public async Task Update(string rootDirectory, bool includePreviews = false, bool switchToStable = false)
public async Task Update(string rootDirectory, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false)
{
var fileList = _packageJsonFileFinder.Find(rootDirectory);
@ -57,7 +58,7 @@ namespace Volo.Abp.Cli.ProjectModification
async Task UpdateAsync(string file)
{
var updated = await UpdatePackagesInFile(file, includePreviews, switchToStable);
var updated = await UpdatePackagesInFile(file, includePreviews,includeReleaseCandidates, switchToStable);
packagesUpdated.TryAdd(file, updated);
}
@ -176,7 +177,10 @@ namespace Volo.Abp.Cli.ProjectModification
return File.Exists(Path.Combine(fileDirectory, "angular.json"));
}
protected virtual async Task<bool> UpdatePackagesInFile(string filePath, bool includePreviews = false,
protected virtual async Task<bool> UpdatePackagesInFile(
string filePath,
bool includePreviews = false,
bool includeReleaseCandidates = false,
bool switchToStable = false)
{
var packagesUpdated = false;
@ -191,7 +195,7 @@ namespace Volo.Abp.Cli.ProjectModification
foreach (var abpPackage in abpPackages)
{
var updated = await TryUpdatingPackage(filePath, abpPackage, includePreviews, switchToStable);
var updated = await TryUpdatingPackage(filePath, abpPackage, includePreviews, includeReleaseCandidates, switchToStable);
if (updated)
{
@ -210,18 +214,26 @@ namespace Volo.Abp.Cli.ProjectModification
string filePath,
JProperty package,
bool includePreviews = false,
bool includeReleaseCandidates = false,
bool switchToStable = false)
{
var currentVersion = (string) package.Value;
var version = "";
if (includePreviews || (!switchToStable && currentVersion.Contains("-preview")))
if ((includePreviews || (!switchToStable && currentVersion.Contains("-preview"))) && !includeReleaseCandidates)
{
version = "preview";
}
else
{
version = await GetLatestVersion(package);
if (!switchToStable && SemanticVersion.Parse(currentVersion).IsPrerelease)
{
version = await GetLatestVersion(package, true);
}
else
{
version = await GetLatestVersion(package, includeReleaseCandidates);
}
}
if (version == currentVersion)
@ -237,14 +249,22 @@ namespace Volo.Abp.Cli.ProjectModification
}
protected virtual async Task<string> GetLatestVersion(
JProperty package)
JProperty package,
bool includeReleaseCandidates = false)
{
if (_fileVersionStorage.ContainsKey(package.Name))
{
return _fileVersionStorage[package.Name];
}
var newVersion = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} version");
var versionListAsJson = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} versions");
var versionList = JsonConvert.DeserializeObject<string[]>(versionListAsJson)
.OrderByDescending(SemanticVersion.Parse, new VersionComparer()).ToList();
var newVersion = includeReleaseCandidates
? versionList.First()
: versionList.FirstOrDefault(v => !SemanticVersion.Parse(v).IsPrerelease);
var newVersionWithPrefix = $"~{newVersion}";
_fileVersionStorage[package.Name] = newVersionWithPrefix;

@ -9,31 +9,46 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.ProjectModification
{
public class PackageSourceSwitcher : ITransientDependency
public class PackagePreviewSwitcher : ITransientDependency
{
private readonly PackageSourceAdder _packageSourceAdder;
private readonly PackageSourceManager _packageSourceManager;
private readonly NpmPackagesUpdater _npmPackagesUpdater;
private readonly VoloNugetPackagesVersionUpdater _nugetPackagesVersionUpdater;
public ILogger<PackageSourceSwitcher> Logger { get; set; }
public ILogger<PackagePreviewSwitcher> Logger { get; set; }
public PackageSourceSwitcher(PackageSourceAdder packageSourceAdder,
public PackagePreviewSwitcher(PackageSourceManager packageSourceManager,
NpmPackagesUpdater npmPackagesUpdater,
VoloNugetPackagesVersionUpdater nugetPackagesVersionUpdater)
{
_packageSourceAdder = packageSourceAdder;
_packageSourceManager = packageSourceManager;
_npmPackagesUpdater = npmPackagesUpdater;
_nugetPackagesVersionUpdater = nugetPackagesVersionUpdater;
Logger = NullLogger<PackageSourceSwitcher>.Instance;
Logger = NullLogger<PackagePreviewSwitcher>.Instance;
}
public async Task SwitchToPreview(CommandLineArgs commandLineArgs)
{
_packageSourceAdder.Add("ABP Nightly", "https://www.myget.org/F/abp-nightly/api/v3/index.json");
var solutionPath = GetSolutionPath(commandLineArgs);
var solutionFolder = GetSolutionFolder(commandLineArgs);
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(
solutionPath,
includeReleaseCandidates: true);
await _npmPackagesUpdater.Update(
solutionFolder,
false,
true);
}
public async Task SwitchToNightlyPreview(CommandLineArgs commandLineArgs)
{
var solutionPath = GetSolutionPath(commandLineArgs);
var solutionFolder = GetSolutionFolder(commandLineArgs);
_packageSourceManager.Add(solutionFolder, "ABP Nightly", "https://www.myget.org/F/abp-nightly/api/v3/index.json");
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(
solutionPath,
true);
@ -48,14 +63,18 @@ namespace Volo.Abp.Cli.ProjectModification
var solutionPath = GetSolutionPath(commandLineArgs);
var solutionFolder = GetSolutionFolder(commandLineArgs);
_packageSourceManager.Remove(solutionFolder, "ABP Nightly");
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(
solutionPath,
false,
false,
true);
await _npmPackagesUpdater.Update(
solutionFolder,
false,
false,
true);
}

@ -1,76 +0,0 @@
using System;
using System.IO;
using System.Xml;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.ProjectModification
{
public class PackageSourceAdder: ITransientDependency
{
public ILogger<PackageSourceAdder> Logger { get; set; }
public PackageSourceAdder()
{
Logger = NullLogger<PackageSourceAdder>.Instance;
}
public void Add(string sourceKey, string sourceValue)
{
var nugetConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"NuGet", "NuGet.Config");
if (!File.Exists(nugetConfigPath))
{
return;
}
var fileContent = File.ReadAllText(nugetConfigPath);
if (fileContent.Contains($"\"{sourceValue}\""))
{
return;
}
Logger.LogInformation($"Adding \"{sourceValue}\" ({sourceKey}) to nuget sources...");
try
{
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(GenerateStreamFromString(fileContent));
var sourceNodes = doc.SelectNodes("/configuration/packageSources");
var newNode = doc.CreateElement("add");
var includeAttr = doc.CreateAttribute("key");
includeAttr.Value = sourceKey;
newNode.Attributes.Append(includeAttr);
var versionAttr = doc.CreateAttribute("value");
versionAttr.Value = sourceValue;
newNode.Attributes.Append(versionAttr);
sourceNodes?[0]?.AppendChild(newNode);
File.WriteAllText(nugetConfigPath, doc.OuterXml);
}
catch
{
Logger.LogWarning($"Adding \"{sourceValue}\" ({sourceKey}) to nuget sources FAILED.");
}
}
private static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
}
}

@ -0,0 +1,126 @@
using System;
using System.IO;
using System.Xml;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.ProjectModification
{
public class PackageSourceManager: ITransientDependency
{
public ILogger<PackageSourceManager> Logger { get; set; }
public PackageSourceManager()
{
Logger = NullLogger<PackageSourceManager>.Instance;
}
public void Add(string solutionFolder, string sourceKey, string sourceValue)
{
var nugetConfigPath = GetNugetConfigPath(solutionFolder);
Logger.LogInformation($"Adding \"{sourceValue}\" ({sourceKey}) to nuget sources...");
if (!File.Exists(nugetConfigPath))
{
File.WriteAllText(nugetConfigPath, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<configuration>\n" +
" <packageSources>\n" +
" <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n" +
$" <add key=\"{sourceKey}\" value=\"{sourceValue}\" />\n" +
" </packageSources>\n" +
"</configuration>");
return;
}
var fileContent = File.ReadAllText(nugetConfigPath);
if (fileContent.Contains($"\"{sourceValue}\""))
{
return;
}
try
{
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(GenerateStreamFromString(fileContent));
var sourceNodes = doc.SelectNodes("/configuration/packageSources");
var newNode = doc.CreateElement("add");
var includeAttr = doc.CreateAttribute("key");
includeAttr.Value = sourceKey;
newNode.Attributes.Append(includeAttr);
var versionAttr = doc.CreateAttribute("value");
versionAttr.Value = sourceValue;
newNode.Attributes.Append(versionAttr);
sourceNodes?[0]?.AppendChild(newNode);
File.WriteAllText(nugetConfigPath, doc.OuterXml);
}
catch
{
Logger.LogWarning($"Adding \"{sourceValue}\" ({sourceKey}) to nuget sources FAILED.");
}
}
public void Remove(string solutionFolder, string sourceKey)
{
var nugetConfigPath = GetNugetConfigPath(solutionFolder);
if (!File.Exists(nugetConfigPath))
{
return;
}
var fileContent = File.ReadAllText(nugetConfigPath);
if (!fileContent.Contains($"\"{sourceKey}\""))
{
return;
}
Logger.LogInformation($"Removing \"{sourceKey}\" from nuget sources...");
try
{
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(GenerateStreamFromString(fileContent));
var nodes = doc.SelectNodes($"/configuration/packageSources/add[@key='{sourceKey}']");
if (nodes != null && nodes.Count > 0)
{
nodes[0].ParentNode.RemoveChild(nodes[0]);
}
File.WriteAllText(nugetConfigPath, doc.OuterXml);
}
catch
{
Logger.LogWarning($"Removing \"{sourceKey}\" from nuget sources FAILED.");
}
}
private static string GetNugetConfigPath(string solutionFolder)
{
return Path.Combine(solutionFolder, "NuGet.Config");
}
private static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
}
}

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Http;
@ -40,26 +41,36 @@ namespace Volo.Abp.Cli.ProjectModification
Logger = NullLogger<ProjectNugetPackageAdder>.Instance;
}
public async Task AddAsync(string projectFile, string packageName)
public async Task AddAsync(string projectFile, string packageName, string version = null)
{
await AddAsync(
projectFile,
await FindNugetPackageInfoAsync(packageName)
await FindNugetPackageInfoAsync(packageName),
version
);
}
public Task AddAsync(string projectFile, NugetPackageInfo package)
public Task AddAsync(string projectFile, NugetPackageInfo package, string version = null)
{
if (File.ReadAllText(projectFile).Contains($"\"{package.Name}\""))
var projectFileContent = File.ReadAllText(projectFile);
if (projectFileContent.Contains($"\"{package.Name}\""))
{
return Task.CompletedTask;
}
if (version == null)
{
version = GetAbpVersionOrNull(projectFileContent);
}
using (DirectoryHelper.ChangeCurrentDirectory(Path.GetDirectoryName(projectFile)))
{
Logger.LogInformation($"Installing '{package.Name}' package to the project '{Path.GetFileNameWithoutExtension(projectFile)}'...");
CmdHelper.Run("dotnet", "add package " + package.Name);
var versionOption = version == null ? "" : $" -v {version}";
CmdHelper.Run("dotnet", $"add package {package.Name}{versionOption}");
var moduleFiles = ModuleClassFinder.Find(projectFile, "AbpModule");
if (moduleFiles.Count == 0)
@ -80,11 +91,22 @@ namespace Volo.Abp.Cli.ProjectModification
return Task.CompletedTask;
}
protected virtual async Task<NugetPackageInfo> FindNugetPackageInfoAsync(string moduleName)
private string GetAbpVersionOrNull(string projectFileContent)
{
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(StreamHelper.GenerateStreamFromString(projectFileContent));
var nodes = doc.SelectNodes("/Project/ItemGroup/PackageReference[starts-with(@Include, 'Volo.')]");
return nodes?[0]?.Attributes?["Version"]?.Value;
}
protected virtual async Task<NugetPackageInfo> FindNugetPackageInfoAsync(string packageName)
{
using (var client = new CliHttpClient())
{
var url = $"{CliUrls.WwwAbpIo}api/app/nugetPackage/byName/?name=" + moduleName;
var url = $"{CliUrls.WwwAbpIo}api/app/nugetPackage/byName/?name=" + packageName;
var response = await client.GetAsync(url);
@ -92,7 +114,7 @@ namespace Volo.Abp.Cli.ProjectModification
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new CliUsageException($"'{moduleName}' nuget package could not be found!");
throw new CliUsageException($"'{packageName}' nuget package could not be found!");
}
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
@ -103,4 +125,4 @@ namespace Volo.Abp.Cli.ProjectModification
}
}
}
}
}

@ -25,23 +25,30 @@ namespace Volo.Abp.Cli.ProjectModification
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.Instance;
}
public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool switchToStable = false, bool checkAll = false)
public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false)
{
var projectPaths = ProjectFinder.GetProjectFiles(solutionPath);
if (checkAll)
{
Task.WaitAll(projectPaths.Select(projectPath => UpdateInternalAsync(projectPath, includePreviews, switchToStable)).ToArray());
Task.WaitAll(projectPaths.Select(projectPath => UpdateInternalAsync(projectPath, includePreviews, includeReleaseCandidates, switchToStable)).ToArray());
}
else
{
var latestVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core");
var latestVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates : includeReleaseCandidates);
var latestReleaseCandidateVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates : true);
var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core");
async Task UpdateAsync(string filePath)
{
var fileContent = File.ReadAllText(filePath);
var updatedContent = await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable, latestVersionFromNuget, latestVersionFromMyGet);
var updatedContent = await UpdateVoloPackagesAsync(fileContent,
includePreviews,
includeReleaseCandidates,
switchToStable,
latestVersionFromNuget,
latestReleaseCandidateVersionFromNuget,
latestVersionFromMyGet);
File.WriteAllText(filePath, updatedContent);
}
@ -50,33 +57,47 @@ namespace Volo.Abp.Cli.ProjectModification
}
}
public async Task UpdateProjectAsync(string projectPath, bool includePreviews = false, bool switchToStable = false, bool checkAll = false)
public async Task UpdateProjectAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false)
{
if (checkAll)
{
await UpdateInternalAsync(projectPath, includePreviews, switchToStable);
await UpdateInternalAsync(projectPath, includeNightlyPreviews, includeReleaseCandidates, switchToStable);
}
else
{
var latestVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core");
var latestReleaseCandidateVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates : true);
var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core");
var fileContent = File.ReadAllText(projectPath);
var updatedContent = await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable, latestVersionFromNuget, latestVersionFromMyGet);
var updatedContent = await UpdateVoloPackagesAsync(fileContent,
includeNightlyPreviews,
includeReleaseCandidates,
switchToStable,
latestVersionFromNuget,
latestReleaseCandidateVersionFromNuget,
latestVersionFromMyGet);
File.WriteAllText(projectPath, updatedContent);
}
}
protected virtual async Task UpdateInternalAsync(string projectPath, bool includePreviews = false, bool switchToStable = false)
protected virtual async Task UpdateInternalAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false)
{
var fileContent = File.ReadAllText(projectPath);
var updatedContent = await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable);
var updatedContent = await UpdateVoloPackagesAsync(fileContent, includeNightlyPreviews, includeReleaseCandidates, switchToStable);
File.WriteAllText(projectPath, updatedContent);
}
private async Task<string> UpdateVoloPackagesAsync(string content, bool includePreviews = false, bool switchToStable = false, SemanticVersion latestNugetVersion = null, string latestMyGetVersion = null)
private async Task<string> UpdateVoloPackagesAsync(string content,
bool includeNightlyPreviews = false,
bool includeReleaseCandidates = false,
bool switchToStable = false,
SemanticVersion latestNugetVersion = null,
SemanticVersion latestNugetReleaseCandidateVersion = null,
string latestMyGetVersion = null)
{
string packageId = null;
@ -108,7 +129,7 @@ namespace Volo.Abp.Cli.ProjectModification
Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, currentSemanticVersion);
if (includePreviews || (currentVersion.Contains("-preview") && !switchToStable))
if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates)
{
var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId);
@ -124,9 +145,17 @@ namespace Volo.Abp.Cli.ProjectModification
}
else
{
var latestVersion = latestNugetVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId);
SemanticVersion latestVersion;
if (currentSemanticVersion.IsPrerelease && !switchToStable)
{
latestVersion = latestNugetReleaseCandidateVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: true);
}
else
{
latestVersion = latestNugetVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: includeReleaseCandidates);
}
if (latestVersion != null && (currentVersion.Contains("-preview") || currentSemanticVersion < latestVersion))
if (latestVersion != null && (currentSemanticVersion < latestVersion || (currentSemanticVersion.IsPrerelease && switchToStable)))
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentSemanticVersion.ToString(), latestVersion.ToString());
versionAttribute.Value = latestVersion.ToString();

@ -86,11 +86,6 @@ namespace Volo.Docs.Projects
}
}
if (versions.Any() && !string.IsNullOrEmpty(project.LatestVersionBranchName))
{
versions.First().Name = project.LatestVersionBranchName;
}
return versions;
}
@ -126,4 +121,4 @@ namespace Volo.Docs.Projects
);
}
}
}
}

@ -53,7 +53,7 @@
<nav class="navbar navbar-logo">
@if (!Model.Project.Name.IsNullOrWhiteSpace())
{
<a class="navbar-brand w-100" href="@Model.CreateVersionLink(Model.LatestVersionInfo, Model.GetSpecificVersionOrLatest())">
<a class="navbar-brand w-100" href="@Model.CreateVersionLink(Model.LatestStableVersionInfo, Model.GetSpecificVersionOrLatest())">
<span id="ProjectName">@Model.Project.Name</span><br>
<strong class="display-block">
@L["Documents"]
@ -173,7 +173,7 @@
else
{
<ul root-node="@Model.Navigation"
version="@(Model.LatestVersionInfo == null || Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version)"
version="@(Model.LatestStableVersionInfo == null || Model.LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version)"
project-name="@Model.ProjectName"
project-format="@Model.Project.Format"
selected-document-name="@Model.DocumentNameWithExtension"
@ -242,8 +242,8 @@
}
</div>
</div>
</div>
</div>
@ -374,7 +374,7 @@ else
model = new ErrorPageModel
{
RedirectUrl = Model.DocumentsUrlPrefix + Model.LanguageCode + "/" + Model.ProjectName + "/"
+ (Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version),
+ (Model.LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version),
ErrorCode = "404",
ErrorMessage = L.GetString("DocumentNotFound"),
AutoRedirect = !Model.DocumentName.IsNullOrWhiteSpace()

@ -16,6 +16,9 @@ using Volo.Docs.Documents;
using Volo.Docs.HtmlConverting;
using Volo.Docs.Models;
using Volo.Docs.Projects;
using Volo.Docs.Utils;
using NuGet.Versioning;
using Volo.Docs.Version;
namespace Volo.Docs.Pages.Documents.Project
{
@ -57,7 +60,7 @@ namespace Volo.Docs.Pages.Documents.Project
public NavigationNode Navigation { get; private set; }
public VersionInfoViewModel LatestVersionInfo { get; private set; }
public VersionInfoViewModel LatestStableVersionInfo { get; private set; }
public string DocumentsUrlPrefix { get; set; }
@ -76,6 +79,7 @@ namespace Volo.Docs.Pages.Documents.Project
private readonly IDocumentToHtmlConverterFactory _documentToHtmlConverterFactory;
private readonly IProjectAppService _projectAppService;
private readonly IDocumentSectionRenderer _documentSectionRenderer;
private readonly IVersionHelper _versionHelper;
private readonly DocsUiOptions _uiOptions;
public IndexModel(
@ -83,7 +87,8 @@ namespace Volo.Docs.Pages.Documents.Project
IDocumentToHtmlConverterFactory documentToHtmlConverterFactory,
IProjectAppService projectAppService,
IOptions<DocsUiOptions> options,
IDocumentSectionRenderer documentSectionRenderer)
IDocumentSectionRenderer documentSectionRenderer,
IVersionHelper versionHelper)
{
ObjectMapperContext = typeof(DocsWebModule);
@ -91,6 +96,7 @@ namespace Volo.Docs.Pages.Documents.Project
_documentToHtmlConverterFactory = documentToHtmlConverterFactory;
_projectAppService = projectAppService;
_documentSectionRenderer = documentSectionRenderer;
_versionHelper = versionHelper;
_uiOptions = options.Value;
}
@ -201,7 +207,7 @@ namespace Volo.Docs.Pages.Documents.Project
private IActionResult ReloadPageWithCulture()
{
var returnUrl = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/"
+ (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" +
+ (LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" +
DocumentName;
return Redirect("/Abp/Languages/Switch?culture=" + LanguageCode + "&uiCulture=" + LanguageCode + "&returnUrl=" + returnUrl);
@ -212,7 +218,7 @@ namespace Volo.Docs.Pages.Documents.Project
return RedirectToPage(new
{
projectName = ProjectName,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
version = (LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
languageCode = DefaultLanguageCode,
documentName = DocumentName
});
@ -223,7 +229,7 @@ namespace Volo.Docs.Pages.Documents.Project
return RedirectToPage(new
{
projectName = ProjectName,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
version = (LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
documentName = "",
languageCode = DefaultLanguageCode
});
@ -250,19 +256,22 @@ namespace Volo.Docs.Pages.Documents.Project
}
var output = await _projectAppService.GetVersionsAsync(Project.ShortName);
var versions = output.Items
var versions = _versionHelper.OrderByDescending(output.Items.ToList())
.Select(v => new VersionInfoViewModel(v.DisplayName, v.Name))
.ToList();
if (versions.Any())
{
LatestVersionInfo = versions.First();
LatestVersionInfo.DisplayText = $"{LatestVersionInfo.DisplayText} ({DocsAppConsts.Latest})";
LatestStableVersionInfo = versions.FirstOrDefault(v => !_versionHelper.IsPreRelease(v.Version)) ?? versions.First();
SetLatestVersionBranchName(versions);
LatestStableVersionInfo.DisplayText = $"{LatestStableVersionInfo.DisplayText} ({DocsAppConsts.Latest})";
if (string.Equals(Version, DocsAppConsts.Latest, StringComparison.OrdinalIgnoreCase))
{
LatestVersionInfo.IsSelected = true;
Version = LatestVersionInfo.Version;
LatestStableVersionInfo.IsSelected = true;
Version = LatestStableVersionInfo.Version;
}
else
{
@ -274,14 +283,16 @@ namespace Volo.Docs.Pages.Documents.Project
}
else
{
versions.First().IsSelected = true;
Version = versions.First().Version;
LatestStableVersionInfo.IsSelected = true;
Version = LatestStableVersionInfo.Version;
}
}
}
else
{
LatestVersionInfo = new VersionInfoViewModel(
SetLatestVersionBranchName(versions);
LatestStableVersionInfo = new VersionInfoViewModel(
$"{DocsAppConsts.Latest}",
DocsAppConsts.Latest,
true);
@ -290,11 +301,19 @@ namespace Volo.Docs.Pages.Documents.Project
VersionSelectItems = versions.Select(v => new SelectListItem
{
Text = v.DisplayText,
Value = CreateVersionLink(LatestVersionInfo, v.Version, DocumentName),
Value = CreateVersionLink(LatestStableVersionInfo, v.Version, DocumentName),
Selected = v.IsSelected
}).ToList();
}
private void SetLatestVersionBranchName(List<VersionInfoViewModel> versions)
{
if (versions.Any() && !string.IsNullOrEmpty(Project.LatestVersionBranchName))
{
versions.First(v=> !_versionHelper.IsPreRelease(v.Version)).Version = Project.LatestVersionBranchName;
}
}
private async Task SetNavigationAsync()
{
try
@ -338,7 +357,7 @@ namespace Volo.Docs.Pages.Documents.Project
return DocsAppConsts.Latest;
}
return Document.Version == LatestVersionInfo.Version ?
return Document.Version == LatestStableVersionInfo.Version ?
DocsAppConsts.Latest :
Document.Version;
}
@ -377,7 +396,7 @@ namespace Volo.Docs.Pages.Documents.Project
LanguageSelectListItems.Add(
new SelectListItem(
language.DisplayName,
DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" + DocumentName,
DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + (LatestStableVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" + DocumentName,
language.Code == LanguageCode
)
);
@ -546,7 +565,7 @@ namespace Volo.Docs.Pages.Documents.Project
}
}
public async Task SetDocumentPreferencesAsync()
private async Task SetDocumentPreferencesAsync()
{
var projectParameters = await _documentAppService.GetParametersAsync(
new GetParametersDocumentInput

@ -10,6 +10,8 @@ using Volo.Docs.Documents;
using Volo.Docs.HtmlConverting;
using Volo.Docs.Models;
using Volo.Docs.Projects;
using Volo.Docs.Utils;
using Volo.Docs.Version;
namespace Volo.Docs.Pages.Documents
{
@ -32,14 +34,17 @@ namespace Volo.Docs.Pages.Documents
private readonly IProjectAppService _projectAppService;
private readonly IDocumentAppService _documentAppService;
private readonly HtmlEncoder _encoder;
private readonly IVersionHelper _versionHelper;
public SearchModel(IProjectAppService projectAppService,
IDocumentAppService documentAppService,
HtmlEncoder encoder)
HtmlEncoder encoder,
IVersionHelper versionHelper)
{
_projectAppService = projectAppService;
_documentAppService = documentAppService;
_encoder = encoder;
_versionHelper = versionHelper;
}
public List<DocumentSearchOutput> SearchOutputs { get; set; } = new List<DocumentSearchOutput>();
@ -61,7 +66,9 @@ namespace Volo.Docs.Pages.Documents
if (versions.Any() && string.Equals(Version, DocsAppConsts.Latest, StringComparison.OrdinalIgnoreCase))
{
Version = versions.First().Name;
Version = string.IsNullOrEmpty(Project.LatestVersionBranchName) ?
(versions.FirstOrDefault(v=> !_versionHelper.IsPreRelease(v.Name)) ?? versions.First()).Name :
Project.LatestVersionBranchName;
}
SearchOutputs = await _documentAppService.SearchAsync(new DocumentSearchInput

@ -0,0 +1,14 @@
using System.Collections.Generic;
using Volo.Docs.Projects;
namespace Volo.Docs.Version
{
public interface IVersionHelper
{
List<string> OrderByDescending(List<string> versions);
List<VersionInfoDto> OrderByDescending(List<VersionInfoDto> versions);
bool IsPreRelease(string version);
}
}

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NuGet.Versioning;
using Volo.Abp.DependencyInjection;
using Volo.Docs.Projects;
namespace Volo.Docs.Version
{
public class SemanticVersionHelper : IVersionHelper, ITransientDependency
{
public List<string> OrderByDescending(List<string> versions)
{
return versions.OrderByDescending(v=> SemanticVersion.Parse(NormalizeVersion(v)), new VersionComparer()).ToList();
}
public List<VersionInfoDto> OrderByDescending(List<VersionInfoDto> versions)
{
return versions.OrderByDescending(v => SemanticVersion.Parse(NormalizeVersion(v.Name)), new VersionComparer()).ToList();
}
public bool IsPreRelease(string version)
{
return SemanticVersion.Parse(NormalizeVersion(version)).IsPrerelease;
}
private string NormalizeVersion(string version)
{
version = version.RemovePreFix("v");
var normalizedVersion = "";
var versionParts = version.Split("-");
if (versionParts[0].Split(".").Length > 3)
{
normalizedVersion = string.Join(".",versionParts[0].Split(".").Take(3));
}
else
{
normalizedVersion = versionParts[0];
}
if (versionParts.Length > 1)
{
return normalizedVersion + "-" + string.Join("-", versionParts.Skip(1));
}
return normalizedVersion;
}
}
}

@ -25,6 +25,7 @@
<PackageReference Include="Markdig.Signed" Version="0.20.0" />
<PackageReference Include="Scriban" Version="2.1.3" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.5" />
<PackageReference Include="NuGet.Versioning" Version="5.6.0" />
</ItemGroup>

Loading…
Cancel
Save