From 06196ceb6509491ee64a177a21d1ede8586f7a05 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Feb 2020 15:31:12 +0300 Subject: [PATCH] refactor & enhancements --- .../Volo/Abp/Cli/Commands/SuiteCommand.cs | 1 - .../ProjectModification/MyGetApiResponse.cs | 11 +++ .../Cli/ProjectModification/MyGetPackage.cs | 15 ++++ .../MyGetPackageListFinder.cs | 50 ++++++++++++ .../ProjectModification/PackageSourceAdder.cs | 76 +++++++++++++++++++ .../PackageSourceSwitcher.cs | 68 +++++++++-------- .../VoloNugetPackagesVersionUpdater.cs | 42 +++++++--- 7 files changed, 223 insertions(+), 40 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetApiResponse.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackage.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceAdder.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs index a13621ea22..227f006307 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetApiResponse.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetApiResponse.cs new file mode 100644 index 0000000000..9a32d8d6fc --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetApiResponse.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Cli.ProjectModification +{ + public class MyGetApiResponse + { + public string _date { get; set; } + + public List Packages { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackage.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackage.cs new file mode 100644 index 0000000000..e5ef40ca17 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackage.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Cli.ProjectModification +{ + public class MyGetPackage + { + public string PackageType { get; set; } + + public string Id { get; set; } + + public List Versions { get; set; } + + public List Dates { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs new file mode 100644 index 0000000000..17a43e6dc7 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs @@ -0,0 +1,50 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Newtonsoft.Json; +using Volo.Abp.Cli.Http; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.ProjectModification +{ + public class MyGetPackageListFinder : ISingletonDependency + { + private MyGetApiResponse _response; + + public ILogger Logger { get; set; } + + public MyGetPackageListFinder() + { + Logger = NullLogger.Instance; + } + + public async Task GetPackages() + { + if (_response != null) + { + return _response; + } + + try + { + using (var client = new CliHttpClient(TimeSpan.FromMinutes(10))) + { + var responseMessage = await client.GetAsync( + $"{CliUrls.WwwAbpIo}api/myget/packages/" + ); + + _response = JsonConvert.DeserializeObject(Encoding.Default.GetString(await responseMessage.Content.ReadAsByteArrayAsync())); + } + } + catch (Exception) + { + Logger.LogError("Unable to get latest preview version."); + throw; + } + + return _response; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceAdder.cs new file mode 100644 index 0000000000..3e651b3bf1 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceAdder.cs @@ -0,0 +1,76 @@ +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 Logger { get; set; } + + public PackageSourceAdder() + { + Logger = NullLogger.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; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs index 605459b6c4..0baef6841a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs @@ -7,21 +7,31 @@ using System.Xml; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.NuGet; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.ProjectModification { public class PackageSourceSwitcher : ITransientDependency { + private readonly MyGetPackageListFinder _myGetPackageListFinder; + private readonly NuGetService _nuGetService; + private readonly PackageSourceAdder _packageSourceAdder; + public ILogger Logger { get; set; } - public PackageSourceSwitcher() + public PackageSourceSwitcher(MyGetPackageListFinder myGetPackageListFinder, NuGetService nuGetService, PackageSourceAdder packageSourceAdder) { + _myGetPackageListFinder = myGetPackageListFinder; + _nuGetService = nuGetService; + _packageSourceAdder = packageSourceAdder; Logger = NullLogger.Instance; } public async Task SwitchToPreview(CommandLineArgs commandLineArgs) { + _packageSourceAdder.Add("ABP Nightly", "https://www.myget.org/F/abp-nightly/api/v3/index.json"); + await Switch(commandLineArgs, SwitchTarget.Preview); } @@ -33,6 +43,7 @@ namespace Volo.Abp.Cli.ProjectModification private async Task Switch(CommandLineArgs commandLineArgs, SwitchTarget target) { var solutionPath = GetSolutionPath(commandLineArgs); + var latestStableAbpVersion = target == SwitchTarget.Stable ? (await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp")).ToString() : null; Logger.LogInformation($"Packages on solution \"{Path.GetFileName(solutionPath)}\" are being switched to {target}."); Logger.LogInformation(""); @@ -49,17 +60,16 @@ namespace Volo.Abp.Cli.ProjectModification doc.Load(GenerateStreamFromString(content)); - doc = SwitchPackagesInDocument(doc, content, target); + doc = await SwitchPackagesInDocument(doc, content, target, latestStableAbpVersion); File.WriteAllText(projectFile, doc.OuterXml); } - Logger.LogInformation(""); Logger.LogInformation($"Packages on solution \"{Path.GetFileName(solutionPath)}\" are switched to {target}."); } - private XmlDocument SwitchPackagesInDocument(XmlDocument doc, string content, SwitchTarget target) + private async Task SwitchPackagesInDocument(XmlDocument doc, string content, SwitchTarget target, string latestStableAbpVersion = null) { Check.NotNull(content, nameof(content)); @@ -76,33 +86,27 @@ namespace Volo.Abp.Cli.ProjectModification var version = node.Attributes["Version"].Value; - XmlNode newNode = GetNewReferenceNode(doc, packageName, version, target); + XmlNode newNode = null; + + if (target == SwitchTarget.Stable) + { + newNode = GetNewStableReferenceNode(doc, packageName, version, latestStableAbpVersion); + } + else if (target == SwitchTarget.Preview) + { + var packageList = (await _myGetPackageListFinder.GetPackages()).Packages; + newNode = GetNewPreviewReferenceNode(doc, packageName, version, packageList); + } - node.ParentNode.ReplaceChild(newNode, node); + node.ParentNode?.ReplaceChild(newNode, node); } return doc; } - private XmlElement GetNewReferenceNode(XmlDocument doc, string packageName, string version, SwitchTarget target) + private XmlElement GetNewStableReferenceNode(XmlDocument doc, string packageName, string version, string newVersion) { var newNode = doc.CreateElement("PackageReference"); - var newVersion = ""; - - if (target == SwitchTarget.Stable) - { - var versonSplitted = version.Split("-"); - - newVersion = versonSplitted.Length >= 2 ? - version.Split("-")[0] : version; - } - if (target == SwitchTarget.Preview) - { - var versonSplitted = version.Split("-"); - - newVersion = versonSplitted.Length < 2 ? - version + $"-preview{GetFormattedDate()}" : version; - } var includeAttr = doc.CreateAttribute("Include"); includeAttr.Value = packageName; @@ -114,16 +118,20 @@ namespace Volo.Abp.Cli.ProjectModification return newNode; } - private string GetFormattedDate() + private XmlElement GetNewPreviewReferenceNode(XmlDocument doc, string packageName, string version, List packageList) { - var formattedDate = ""; - var today = DateTime.Now; + var newVersion = packageList.FirstOrDefault(p => p.Id == packageName)?.Versions.LastOrDefault() ?? version; - formattedDate += today.Year; - formattedDate += (today.Month < 10 ? "0" + today.Month : today.Month.ToString()); - formattedDate += (today.Day < 10 ? "0" + today.Day : today.Day.ToString()); + var newNode = doc.CreateElement("PackageReference"); + + var includeAttr = doc.CreateAttribute("Include"); + includeAttr.Value = packageName; + newNode.Attributes.Append(includeAttr); - return formattedDate; + var versionAttr = doc.CreateAttribute("Version"); + versionAttr.Value = newVersion; + newNode.Attributes.Append(versionAttr); + return newNode; } private List GetCsprojFiles(string slnPath) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs index d5756a4566..3d1f2ff4ca 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs @@ -1,6 +1,7 @@ using System; using NuGet.Versioning; using System.IO; +using System.Linq; using System.Threading.Tasks; using System.Xml; using Volo.Abp.Cli.NuGet; @@ -13,11 +14,13 @@ namespace Volo.Abp.Cli.ProjectModification public class VoloNugetPackagesVersionUpdater : ITransientDependency { private readonly NuGetService _nuGetService; + private readonly MyGetPackageListFinder _myGetPackageListFinder; public ILogger Logger { get; set; } - public VoloNugetPackagesVersionUpdater(NuGetService nuGetService) + public VoloNugetPackagesVersionUpdater(NuGetService nuGetService, MyGetPackageListFinder myGetPackageListFinder) { _nuGetService = nuGetService; + _myGetPackageListFinder = myGetPackageListFinder; Logger = NullLogger.Instance; } @@ -67,23 +70,44 @@ namespace Volo.Abp.Cli.ProjectModification continue; } - var versionAttribute = package.Attributes["Version"]; - packageId = package.Attributes["Include"].Value; - var packageVersion = SemanticVersion.Parse(versionAttribute.Value); + + var versionAttribute = package.Attributes["Version"]; + var currentVersion = versionAttribute.Value; + var packageVersion = SemanticVersion.Parse(currentVersion); Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, packageVersion); - var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId, includePreviews); - if (latestVersion != null && packageVersion < latestVersion) + if (currentVersion.Contains("preview") || includePreviews) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, packageVersion.ToString(), latestVersion.ToString()); - versionAttribute.Value = latestVersion.ToString(); + var latestVersion = (await _myGetPackageListFinder.GetPackages()).Packages + .FirstOrDefault(p => p.Id == packageId) + ?.Versions.LastOrDefault(); + + if (currentVersion != latestVersion) + { + Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, latestVersion); + versionAttribute.Value = latestVersion; + } + else + { + Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, currentVersion); + } } else { - Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, packageVersion); + var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId); + + if (latestVersion != null && packageVersion < latestVersion) + { + Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, packageVersion.ToString(), latestVersion.ToString()); + versionAttribute.Value = latestVersion.ToString(); + } + else + { + Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, packageVersion); + } } }