From aac3b9584a7d6be611ca3a72f753f21a98f936de Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Feb 2020 13:38:58 +0300 Subject: [PATCH 1/3] ABP CLI Replace Packages with Previews resolves https://github.com/abpframework/abp/issues/2837 --- .../Volo/Abp/Cli/AbpCliCoreModule.cs | 2 + .../Commands/SwitchNightlyPreviewCommand.cs | 44 +++++ .../Abp/Cli/Commands/SwitchStableCommand.cs | 44 +++++ .../Volo/Abp/Cli/Commands/UpdateCommand.cs | 2 +- .../PackageSourceSwitcher.cs | 179 ++++++++++++++++++ 5 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchNightlyPreviewCommand.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchStableCommand.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 34bf95fdf1..63fb4f8eee 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -30,6 +30,8 @@ namespace Volo.Abp.Cli options.Commands["login"] = typeof(LoginCommand); options.Commands["logout"] = typeof(LogoutCommand); options.Commands["suite"] = typeof(SuiteCommand); + options.Commands["switch-to-preview"] = typeof(SwitchNightlyPreviewCommand); + options.Commands["switch-to-stable"] = typeof(SwitchStableCommand); }); } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchNightlyPreviewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchNightlyPreviewCommand.cs new file mode 100644 index 0000000000..9f0862258f --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchNightlyPreviewCommand.cs @@ -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 SwitchNightlyPreviewCommand : IConsoleCommand, ITransientDependency + { + private readonly PackageSourceSwitcher _packageSourceSwitcher; + + public SwitchNightlyPreviewCommand(PackageSourceSwitcher packageSourceSwitcher) + { + _packageSourceSwitcher = packageSourceSwitcher; + } + + public async Task ExecuteAsync(CommandLineArgs commandLineArgs) + { + await _packageSourceSwitcher.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("-sp|--solution-path"); + 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 nightly preview ABP version."; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchStableCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchStableCommand.cs new file mode 100644 index 0000000000..333583e96d --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchStableCommand.cs @@ -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 SwitchStableCommand : IConsoleCommand, ITransientDependency + { + private readonly PackageSourceSwitcher _packageSourceSwitcher; + + public SwitchStableCommand(PackageSourceSwitcher packageSourceSwitcher) + { + _packageSourceSwitcher = packageSourceSwitcher; + } + + public async Task ExecuteAsync(CommandLineArgs commandLineArgs) + { + await _packageSourceSwitcher.SwitchToStable(commandLineArgs); + } + + public string GetUsageInfo() + { + var sb = new StringBuilder(); + + sb.AppendLine(""); + sb.AppendLine("Usage:"); + sb.AppendLine(" abp switch-to-stable [options]"); + sb.AppendLine(""); + sb.AppendLine("Options:"); + sb.AppendLine("-sp|--solution-path"); + 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 stable ABP version from preview version."; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index d201790c94..5e15c25a0c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -94,7 +94,7 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine(""); sb.AppendLine("Usage:"); sb.AppendLine(""); - sb.AppendLine(" abp update [options]"); + sb.AppendLine(" abp update [options]"); sb.AppendLine(""); sb.AppendLine("Options:"); sb.AppendLine("-p|--include-previews (if supported by the template)"); 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 new file mode 100644 index 0000000000..605459b6c4 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Xml; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Cli.Args; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.ProjectModification +{ + public class PackageSourceSwitcher : ITransientDependency + { + public ILogger Logger { get; set; } + + public PackageSourceSwitcher() + { + Logger = NullLogger.Instance; + } + + public async Task SwitchToPreview(CommandLineArgs commandLineArgs) + { + await Switch(commandLineArgs, SwitchTarget.Preview); + } + + public async Task SwitchToStable(CommandLineArgs commandLineArgs) + { + await Switch(commandLineArgs, SwitchTarget.Stable); + } + + private async Task Switch(CommandLineArgs commandLineArgs, SwitchTarget target) + { + var solutionPath = GetSolutionPath(commandLineArgs); + + Logger.LogInformation($"Packages on solution \"{Path.GetFileName(solutionPath)}\" are being switched to {target}."); + Logger.LogInformation(""); + + var projectFiles = GetCsprojFiles(solutionPath); + + foreach (var projectFile in projectFiles) + { + Logger.LogInformation($"Packages on project \"{Path.GetFileName(projectFile)}\" are being switched to {target}."); + + var content = File.ReadAllText(projectFile); + + var doc = new XmlDocument() { PreserveWhitespace = true }; + + doc.Load(GenerateStreamFromString(content)); + + doc = SwitchPackagesInDocument(doc, content, target); + + 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) + { + Check.NotNull(content, nameof(content)); + + var nodes = doc.SelectNodes("/Project/ItemGroup/PackageReference[@Include]"); + + foreach (XmlNode node in nodes) + { + var packageName = node.Attributes["Include"].Value; + + if (!packageName.StartsWith("Volo.Abp")) + { + continue; + } + + var version = node.Attributes["Version"].Value; + + XmlNode newNode = GetNewReferenceNode(doc, packageName, version, target); + + node.ParentNode.ReplaceChild(newNode, node); + } + + return doc; + } + + private XmlElement GetNewReferenceNode(XmlDocument doc, string packageName, string version, SwitchTarget target) + { + 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; + newNode.Attributes.Append(includeAttr); + + var versionAttr = doc.CreateAttribute("Version"); + versionAttr.Value = newVersion; + newNode.Attributes.Append(versionAttr); + return newNode; + } + + private string GetFormattedDate() + { + var formattedDate = ""; + var today = DateTime.Now; + + formattedDate += today.Year; + formattedDate += (today.Month < 10 ? "0" + today.Month : today.Month.ToString()); + formattedDate += (today.Day < 10 ? "0" + today.Day : today.Day.ToString()); + + return formattedDate; + } + + private List GetCsprojFiles(string slnPath) + { + return Directory.GetFiles(Path.GetDirectoryName(slnPath), "*.csproj", SearchOption.AllDirectories).ToList(); + } + + private string GetSolutionPath(CommandLineArgs commandLineArgs) + { + var solutionPath = commandLineArgs.Options.GetOrNull(Options.SolutionPath.Short, Options.SolutionPath.Long); + + if (solutionPath == null) + { + try + { + solutionPath = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln").Single(); + } + catch (Exception) + { + Logger.LogError("There is no solution or more that one solution in current directory."); + throw; + } + } + + return solutionPath; + } + + 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; + } + + public static class Options + { + public static class SolutionPath + { + public const string Short = "sp"; + public const string Long = "solution-path"; + } + } + + enum SwitchTarget + { + Preview, + Stable + } + } +} From 06196ceb6509491ee64a177a21d1ede8586f7a05 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Feb 2020 15:31:12 +0300 Subject: [PATCH 2/3] 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); + } } } From a835d6bca485478ac4a7f1e3d03ebec625d22095 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 3 Mar 2020 13:11:52 +0300 Subject: [PATCH 3/3] switch Preview npm package & Refactor npm previews are not tested yet --- .../Volo/Abp/Cli/Commands/UpdateCommand.cs | 6 +- .../MyGetPackageListFinder.cs | 1 + .../ProjectModification/NpmPackagesUpdater.cs | 58 +++++-- .../PackageSourceSwitcher.cs | 149 +++--------------- .../VoloNugetPackagesVersionUpdater.cs | 18 +-- 5 files changed, 78 insertions(+), 154 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index 5e15c25a0c..c44f77b749 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -42,13 +42,13 @@ namespace Volo.Abp.Cli.Commands if (updateNpm || !updateNuget) { - UpdateNpmPackages(directory); + await UpdateNpmPackages(directory); } } - private void UpdateNpmPackages(string directory) + private async Task UpdateNpmPackages(string directory) { - _npmPackagesUpdater.Update(directory); + await _npmPackagesUpdater.Update(directory); } private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs, string directory) 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 index 17a43e6dc7..41907276f4 100644 --- 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 @@ -46,5 +46,6 @@ namespace Volo.Abp.Cli.ProjectModification return _response; } + } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs index 41fd33b4fb..91eaec48e7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Newtonsoft.Json; @@ -18,18 +19,20 @@ namespace Volo.Abp.Cli.ProjectModification private readonly PackageJsonFileFinder _packageJsonFileFinder; private readonly NpmGlobalPackagesChecker _npmGlobalPackagesChecker; + private readonly MyGetPackageListFinder _myGetPackageListFinder; private readonly Dictionary _fileVersionStorage = new Dictionary(); - public NpmPackagesUpdater(PackageJsonFileFinder packageJsonFileFinder, NpmGlobalPackagesChecker npmGlobalPackagesChecker) + public NpmPackagesUpdater(PackageJsonFileFinder packageJsonFileFinder, NpmGlobalPackagesChecker npmGlobalPackagesChecker, MyGetPackageListFinder myGetPackageListFinder) { _packageJsonFileFinder = packageJsonFileFinder; _npmGlobalPackagesChecker = npmGlobalPackagesChecker; + _myGetPackageListFinder = myGetPackageListFinder; Logger = NullLogger.Instance; } - public void Update(string rootDirectory) + public async Task Update(string rootDirectory, bool includePreviews = false, bool switchToStable = false) { var fileList = _packageJsonFileFinder.Find(rootDirectory); @@ -42,7 +45,7 @@ namespace Volo.Abp.Cli.ProjectModification foreach (var file in fileList) { - UpdatePackagesInFile(file, out var packagesUpdated); + var packagesUpdated = await UpdatePackagesInFile(file, includePreviews, switchToStable); if (packagesUpdated) { @@ -64,21 +67,21 @@ namespace Volo.Abp.Cli.ProjectModification return File.Exists(Path.Combine(fileDirectory, "angular.json")); } - protected virtual void UpdatePackagesInFile(string file, out bool packagesUpdated) + protected virtual async Task UpdatePackagesInFile(string file, bool includePreviews = false, bool switchToStable = false) { - packagesUpdated = false; + var packagesUpdated = false; var fileContent = File.ReadAllText(file); var packageJson = JObject.Parse(fileContent); var abpPackages = GetAbpPackagesFromPackageJson(packageJson); if (!abpPackages.Any()) { - return; + return packagesUpdated; } foreach (var abpPackage in abpPackages) { - TryUpdatePackage(file, abpPackage, out var updated); + var updated = await TryUpdatePackage(file, abpPackage, includePreviews, switchToStable); if (updated) { @@ -89,18 +92,23 @@ namespace Volo.Abp.Cli.ProjectModification var modifiedFileContent = packageJson.ToString(Formatting.Indented); File.WriteAllText(file, modifiedFileContent); + + return packagesUpdated; } - protected virtual void TryUpdatePackage(string file, JProperty package, out bool updated) + protected virtual async Task TryUpdatePackage(string file, JProperty package, + bool includePreviews = false, bool switchToStable = false) { - var version = GetLatestVersion(package); + var updated = false; + var currentVersion = (string)package.Value; + + var version = await GetLatestVersion(package, currentVersion, includePreviews, switchToStable); var versionWithPrefix = $"^{version}"; - if (versionWithPrefix == (string)package.Value) + if (versionWithPrefix == currentVersion) { - updated = false; - return; + return false; } else { @@ -110,25 +118,41 @@ namespace Volo.Abp.Cli.ProjectModification package.Value.Replace(versionWithPrefix); Logger.LogInformation($"Updated {package.Name} to {version} in {file.Replace(Directory.GetCurrentDirectory(), "")}."); + return updated; } - protected virtual string GetLatestVersion(JProperty package) + protected virtual async Task GetLatestVersion(JProperty package, string currentVersion, + bool includePreviews = false, bool switchToStable = false) { if (_fileVersionStorage.ContainsKey(package.Name)) { return _fileVersionStorage[package.Name]; } - var version = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} version"); + string newVersion = currentVersion; + + if (includePreviews || (!switchToStable && currentVersion.Contains("-preview"))) + { + var mygetPackage = (await _myGetPackageListFinder.GetPackages()).Packages.FirstOrDefault(p => p.Id == package.Name); + if (mygetPackage != null) + { + newVersion = mygetPackage.Versions.Last(); + } + } + else + { + newVersion = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} version"); + } + - _fileVersionStorage[package.Name] = version; + _fileVersionStorage[package.Name] = newVersion; - return version; + return newVersion; } protected virtual List GetAbpPackagesFromPackageJson(JObject fileObject) { - var dependencyList = new [] { "dependencies", "devDependencies", "peerDependencies" }; + var dependencyList = new[] { "dependencies", "devDependencies", "peerDependencies" }; var abpPackages = new List(); foreach (var dependencyListName in dependencyList) 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 0baef6841a..e860a68ba8 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 @@ -1,30 +1,29 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -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; + private readonly NpmPackagesUpdater _npmPackagesUpdater; + private readonly VoloNugetPackagesVersionUpdater _nugetPackagesVersionUpdater; public ILogger Logger { get; set; } - public PackageSourceSwitcher(MyGetPackageListFinder myGetPackageListFinder, NuGetService nuGetService, PackageSourceAdder packageSourceAdder) + public PackageSourceSwitcher(PackageSourceAdder packageSourceAdder, + NpmPackagesUpdater npmPackagesUpdater, + VoloNugetPackagesVersionUpdater nugetPackagesVersionUpdater) { - _myGetPackageListFinder = myGetPackageListFinder; - _nuGetService = nuGetService; _packageSourceAdder = packageSourceAdder; + _npmPackagesUpdater = npmPackagesUpdater; + _nugetPackagesVersionUpdater = nugetPackagesVersionUpdater; Logger = NullLogger.Instance; } @@ -32,113 +31,29 @@ namespace Volo.Abp.Cli.ProjectModification { _packageSourceAdder.Add("ABP Nightly", "https://www.myget.org/F/abp-nightly/api/v3/index.json"); - await Switch(commandLineArgs, SwitchTarget.Preview); - } - - public async Task SwitchToStable(CommandLineArgs commandLineArgs) - { - await Switch(commandLineArgs, SwitchTarget.Stable); - } - - 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(""); - - var projectFiles = GetCsprojFiles(solutionPath); - - foreach (var projectFile in projectFiles) - { - Logger.LogInformation($"Packages on project \"{Path.GetFileName(projectFile)}\" are being switched to {target}."); - - var content = File.ReadAllText(projectFile); - - var doc = new XmlDocument() { PreserveWhitespace = true }; - - doc.Load(GenerateStreamFromString(content)); - - 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 async Task SwitchPackagesInDocument(XmlDocument doc, string content, SwitchTarget target, string latestStableAbpVersion = null) - { - Check.NotNull(content, nameof(content)); - - var nodes = doc.SelectNodes("/Project/ItemGroup/PackageReference[@Include]"); - - foreach (XmlNode node in nodes) - { - var packageName = node.Attributes["Include"].Value; - - if (!packageName.StartsWith("Volo.Abp")) - { - continue; - } + await _nugetPackagesVersionUpdater.UpdateSolutionAsync( + GetSolutionPath(commandLineArgs), + true); - var version = node.Attributes["Version"].Value; - - 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); - } - - return doc; - } - - private XmlElement GetNewStableReferenceNode(XmlDocument doc, string packageName, string version, string newVersion) - { - var newNode = doc.CreateElement("PackageReference"); - - var includeAttr = doc.CreateAttribute("Include"); - includeAttr.Value = packageName; - newNode.Attributes.Append(includeAttr); - - var versionAttr = doc.CreateAttribute("Version"); - versionAttr.Value = newVersion; - newNode.Attributes.Append(versionAttr); - return newNode; + await _npmPackagesUpdater.Update( + Path.GetFileName(GetSolutionPath(commandLineArgs)), + true); } - private XmlElement GetNewPreviewReferenceNode(XmlDocument doc, string packageName, string version, List packageList) - { - var newVersion = packageList.FirstOrDefault(p => p.Id == packageName)?.Versions.LastOrDefault() ?? version; - - var newNode = doc.CreateElement("PackageReference"); - - var includeAttr = doc.CreateAttribute("Include"); - includeAttr.Value = packageName; - newNode.Attributes.Append(includeAttr); - - var versionAttr = doc.CreateAttribute("Version"); - versionAttr.Value = newVersion; - newNode.Attributes.Append(versionAttr); - return newNode; - } - - private List GetCsprojFiles(string slnPath) + public async Task SwitchToStable(CommandLineArgs commandLineArgs) { - return Directory.GetFiles(Path.GetDirectoryName(slnPath), "*.csproj", SearchOption.AllDirectories).ToList(); + await _nugetPackagesVersionUpdater.UpdateSolutionAsync( + GetSolutionPath(commandLineArgs), + false, + true); + + await _npmPackagesUpdater.Update( + Path.GetFileName(GetSolutionPath(commandLineArgs)), + false, + true); } + private string GetSolutionPath(CommandLineArgs commandLineArgs) { var solutionPath = commandLineArgs.Options.GetOrNull(Options.SolutionPath.Short, Options.SolutionPath.Long); @@ -159,16 +74,6 @@ namespace Volo.Abp.Cli.ProjectModification return solutionPath; } - 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; - } - public static class Options { public static class SolutionPath @@ -177,11 +82,5 @@ namespace Volo.Abp.Cli.ProjectModification public const string Long = "solution-path"; } } - - enum SwitchTarget - { - Preview, - Stable - } } } 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 3d1f2ff4ca..da8ded6a20 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 @@ -24,29 +24,29 @@ namespace Volo.Abp.Cli.ProjectModification Logger = NullLogger.Instance; } - public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews) + public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool switchToStable = false) { var projectPaths = ProjectFinder.GetProjectFiles(solutionPath); foreach (var filePath in projectPaths) { - await UpdateInternalAsync(filePath, includePreviews); + await UpdateInternalAsync(filePath, includePreviews, switchToStable); } } - public async Task UpdateProjectAsync(string projectPath, bool includePreviews) + public async Task UpdateProjectAsync(string projectPath, bool includePreviews = false, bool switchToStable = false) { - await UpdateInternalAsync(projectPath, includePreviews); + await UpdateInternalAsync(projectPath, includePreviews, switchToStable); } - protected virtual async Task UpdateInternalAsync(string projectPath, bool includePreviews) + protected virtual async Task UpdateInternalAsync(string projectPath, bool includePreviews = false, bool switchToStable = false) { var fileContent = File.ReadAllText(projectPath); - File.WriteAllText(projectPath, await UpdateVoloPackagesAsync(fileContent, includePreviews)); + File.WriteAllText(projectPath, await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable)); } - private async Task UpdateVoloPackagesAsync(string content, bool includePreviews) + private async Task UpdateVoloPackagesAsync(string content, bool includePreviews = false, bool switchToStable = false) { string packageId = null; @@ -79,7 +79,7 @@ namespace Volo.Abp.Cli.ProjectModification Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, packageVersion); - if (currentVersion.Contains("preview") || includePreviews) + if (includePreviews || (currentVersion.Contains("-preview") && !switchToStable)) { var latestVersion = (await _myGetPackageListFinder.GetPackages()).Packages .FirstOrDefault(p => p.Id == packageId) @@ -99,7 +99,7 @@ namespace Volo.Abp.Cli.ProjectModification { var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId); - if (latestVersion != null && packageVersion < latestVersion) + if (latestVersion != null && (currentVersion.Contains("-preview") || packageVersion < latestVersion)) { Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, packageVersion.ToString(), latestVersion.ToString()); versionAttribute.Value = latestVersion.ToString();