Browse Source

Merge pull request #2868 from abpframework/ABP-CLI-Replace-Packages-with-Previews

ABP CLI Replace Packages with Previews
pull/2986/head
Halil İbrahim Kalkan 7 years ago
committed by GitHub
parent
commit
346958bd28
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs
  2. 44
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchNightlyPreviewCommand.cs
  3. 44
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchStableCommand.cs
  4. 8
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs
  5. 11
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetApiResponse.cs
  6. 15
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackage.cs
  7. 51
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs
  8. 58
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
  9. 76
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceAdder.cs
  10. 86
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs
  11. 56
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

2
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);
});
}
}

44
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.";
}
}
}

44
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.";
}
}
}

8
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)
@ -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)");

11
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<MyGetPackage> Packages { get; set; }
}
}

15
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<string> Versions { get; set; }
public List<string> Dates { get; set; }
}
}

51
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs

@ -0,0 +1,51 @@
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<MyGetPackageListFinder> Logger { get; set; }
public MyGetPackageListFinder()
{
Logger = NullLogger<MyGetPackageListFinder>.Instance;
}
public async Task<MyGetApiResponse> 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<MyGetApiResponse>(Encoding.Default.GetString(await responseMessage.Content.ReadAsByteArrayAsync()));
}
}
catch (Exception)
{
Logger.LogError("Unable to get latest preview version.");
throw;
}
return _response;
}
}
}

58
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<string, string> _fileVersionStorage = new Dictionary<string, string>();
public NpmPackagesUpdater(PackageJsonFileFinder packageJsonFileFinder, NpmGlobalPackagesChecker npmGlobalPackagesChecker)
public NpmPackagesUpdater(PackageJsonFileFinder packageJsonFileFinder, NpmGlobalPackagesChecker npmGlobalPackagesChecker, MyGetPackageListFinder myGetPackageListFinder)
{
_packageJsonFileFinder = packageJsonFileFinder;
_npmGlobalPackagesChecker = npmGlobalPackagesChecker;
_myGetPackageListFinder = myGetPackageListFinder;
Logger = NullLogger<NpmPackagesUpdater>.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<bool> 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<bool> 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<string> 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<JProperty> GetAbpPackagesFromPackageJson(JObject fileObject)
{
var dependencyList = new [] { "dependencies", "devDependencies", "peerDependencies" };
var dependencyList = new[] { "dependencies", "devDependencies", "peerDependencies" };
var abpPackages = new List<JProperty>();
foreach (var dependencyListName in dependencyList)

76
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<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;
}
}
}

86
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageSourceSwitcher.cs

@ -0,0 +1,86 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
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
{
private readonly PackageSourceAdder _packageSourceAdder;
private readonly NpmPackagesUpdater _npmPackagesUpdater;
private readonly VoloNugetPackagesVersionUpdater _nugetPackagesVersionUpdater;
public ILogger<PackageSourceSwitcher> Logger { get; set; }
public PackageSourceSwitcher(PackageSourceAdder packageSourceAdder,
NpmPackagesUpdater npmPackagesUpdater,
VoloNugetPackagesVersionUpdater nugetPackagesVersionUpdater)
{
_packageSourceAdder = packageSourceAdder;
_npmPackagesUpdater = npmPackagesUpdater;
_nugetPackagesVersionUpdater = nugetPackagesVersionUpdater;
Logger = NullLogger<PackageSourceSwitcher>.Instance;
}
public async Task SwitchToPreview(CommandLineArgs commandLineArgs)
{
_packageSourceAdder.Add("ABP Nightly", "https://www.myget.org/F/abp-nightly/api/v3/index.json");
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(
GetSolutionPath(commandLineArgs),
true);
await _npmPackagesUpdater.Update(
Path.GetFileName(GetSolutionPath(commandLineArgs)),
true);
}
public async Task SwitchToStable(CommandLineArgs commandLineArgs)
{
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);
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;
}
public static class Options
{
public static class SolutionPath
{
public const string Short = "sp";
public const string Long = "solution-path";
}
}
}
}

56
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,37 +14,39 @@ namespace Volo.Abp.Cli.ProjectModification
public class VoloNugetPackagesVersionUpdater : ITransientDependency
{
private readonly NuGetService _nuGetService;
private readonly MyGetPackageListFinder _myGetPackageListFinder;
public ILogger<VoloNugetPackagesVersionUpdater> Logger { get; set; }
public VoloNugetPackagesVersionUpdater(NuGetService nuGetService)
public VoloNugetPackagesVersionUpdater(NuGetService nuGetService, MyGetPackageListFinder myGetPackageListFinder)
{
_nuGetService = nuGetService;
_myGetPackageListFinder = myGetPackageListFinder;
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.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<string> UpdateVoloPackagesAsync(string content, bool includePreviews)
private async Task<string> UpdateVoloPackagesAsync(string content, bool includePreviews = false, bool switchToStable = false)
{
string packageId = null;
@ -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 (includePreviews || (currentVersion.Contains("-preview") && !switchToStable))
{
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 && (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();
}
else
{
Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, packageVersion);
}
}
}

Loading…
Cancel
Save