From d7985119d0680aa6f32ebf6eb894f18c212eec6a Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Dec 2020 23:11:39 +0800 Subject: [PATCH 1/2] Update command allow to specify version --- .../Volo/Abp/Cli/Commands/UpdateCommand.cs | 22 +++-- .../Volo/Abp/Cli/NuGet/NuGetService.cs | 71 +++++++------- .../ProjectModification/NpmPackagesUpdater.cs | 57 ++++++++--- .../VoloNugetPackagesVersionUpdater.cs | 94 +++++++++++++------ 4 files changed, 161 insertions(+), 83 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 5fd30115e2..3173744bd0 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 @@ -34,24 +34,25 @@ namespace Volo.Abp.Cli.Commands var directory = commandLineArgs.Options.GetOrNull(Options.SolutionPath.Short, Options.SolutionPath.Long) ?? Directory.GetCurrentDirectory(); + var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long); if (updateNuget || !updateNpm) { - await UpdateNugetPackages(commandLineArgs, directory); + await UpdateNugetPackages(commandLineArgs, directory, version); } if (updateNpm || !updateNuget) { - await UpdateNpmPackages(directory); + await UpdateNpmPackages(directory, version); } } - private async Task UpdateNpmPackages(string directory) + private async Task UpdateNpmPackages(string directory, string version) { - await _npmPackagesUpdater.Update(directory); + await _npmPackagesUpdater.Update(directory, version: version); } - private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs, string directory) + private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs, string directory, string version) { var solution = commandLineArgs.Options.GetOrNull(Options.SolutionName.Short, Options.SolutionName.Long); @@ -66,7 +67,7 @@ namespace Volo.Abp.Cli.Commands { var solutionName = Path.GetFileName(solution).RemovePostFix(".sln"); - await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll); + await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll, version: version); Logger.LogInformation($"Volo packages are updated in {solutionName} solution."); return; @@ -78,7 +79,7 @@ namespace Volo.Abp.Cli.Commands { var projectName = Path.GetFileName(project).RemovePostFix(".csproj"); - await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, checkAll: checkAll); + await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, checkAll: checkAll, version: version); Logger.LogInformation($"Volo packages are updated in {projectName} project."); return; @@ -107,6 +108,7 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine("-sp|--solution-path (Specify the solution path)"); sb.AppendLine("-sn|--solution-name (Specify the solution name)"); sb.AppendLine("--check-all (Check the new version of each package separately)"); + sb.AppendLine("-v|--version (default: latest version)"); sb.AppendLine(""); sb.AppendLine("Some examples:"); sb.AppendLine(""); @@ -148,6 +150,12 @@ namespace Volo.Abp.Cli.Commands { public const string Long = "check-all"; } + + public static class Version + { + public const string Short = "v"; + public const string Long = "version"; + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs index 1ecfc9e34d..a7243dbccd 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs @@ -40,13 +40,43 @@ namespace Volo.Abp.Cli.NuGet } public async Task GetLatestVersionOrNullAsync(string packageId, bool includeNightly = false, bool includeReleaseCandidates = false) + { + var versionList = await GetPackageVersionListAsync(packageId, includeNightly, includeReleaseCandidates); + + List versions; + + if (!includeNightly && !includeReleaseCandidates) + { + versions = versionList + .Select(SemanticVersion.Parse) + .OrderByDescending(v=> v, new VersionComparer()).ToList(); + + versions = versions.Where(x => !x.IsPrerelease).ToList(); + } + else if (!includeNightly && includeReleaseCandidates) + { + versions = versionList + .Where(v=> !v.Contains("-preview")) + .Select(SemanticVersion.Parse) + .OrderByDescending(v=> v, new VersionComparer()).ToList(); + } + else + { + versions = versionList + .Select(SemanticVersion.Parse) + .OrderByDescending(v=> v, new VersionComparer()).ToList(); + } + + return versions.Any() ? versions.Max() : null; + + } + + public async Task> GetPackageVersionListAsync(string packageId, bool includeNightly = false, + bool includeReleaseCandidates = false) { if (AuthService.IsLoggedIn()) { - if (_proPackageList == null) - { - _proPackageList = await GetProPackageListAsync(); - } + _proPackageList ??= await GetProPackageListAsync(); } string url; @@ -75,37 +105,8 @@ namespace Volo.Abp.Cli.NuGet var responseContent = await responseMessage.Content.ReadAsStringAsync(); - List versions; - - if (!includeNightly && !includeReleaseCandidates) - { - versions = JsonSerializer - .Deserialize(responseContent) - .Versions - .Select(SemanticVersion.Parse) - .OrderByDescending(v=> v, new VersionComparer()).ToList(); - - versions = versions.Where(x => !x.IsPrerelease).ToList(); - } - else if (!includeNightly && includeReleaseCandidates) - { - versions = JsonSerializer - .Deserialize(responseContent) - .Versions - .Where(v=> !v.Contains("-preview")) - .Select(SemanticVersion.Parse) - .OrderByDescending(v=> v, new VersionComparer()).ToList(); - } - else - { - versions = JsonSerializer - .Deserialize(responseContent) - .Versions - .Select(SemanticVersion.Parse) - .OrderByDescending(v=> v, new VersionComparer()).ToList(); - } - - return versions.Any() ? versions.Max() : null; + return JsonSerializer + .Deserialize(responseContent).Versions; } } 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 c71e9591c0..f2bbe873d8 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 @@ -43,7 +43,7 @@ namespace Volo.Abp.Cli.ProjectModification Logger = NullLogger.Instance; } - public async Task Update(string rootDirectory, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false) + public async Task Update(string rootDirectory, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, string version = null) { var fileList = _packageJsonFileFinder.Find(rootDirectory); @@ -58,7 +58,7 @@ namespace Volo.Abp.Cli.ProjectModification async Task UpdateAsync(string file) { - var updated = await UpdatePackagesInFile(file, includePreviews,includeReleaseCandidates, switchToStable); + var updated = await UpdatePackagesInFile(file, includePreviews,includeReleaseCandidates, switchToStable, version); packagesUpdated.TryAdd(file, updated); } @@ -181,7 +181,8 @@ namespace Volo.Abp.Cli.ProjectModification string filePath, bool includePreviews = false, bool includeReleaseCandidates = false, - bool switchToStable = false) + bool switchToStable = false, + string specifiedVersion = null) { var packagesUpdated = false; var fileContent = File.ReadAllText(filePath); @@ -195,7 +196,7 @@ namespace Volo.Abp.Cli.ProjectModification foreach (var abpPackage in abpPackages) { - var updated = await TryUpdatingPackage(filePath, abpPackage, includePreviews, includeReleaseCandidates, switchToStable); + var updated = await TryUpdatingPackage(filePath, abpPackage, includePreviews, includeReleaseCandidates, switchToStable, specifiedVersion); if (updated) { @@ -215,27 +216,45 @@ namespace Volo.Abp.Cli.ProjectModification JProperty package, bool includePreviews = false, bool includeReleaseCandidates = false, - bool switchToStable = false) + bool switchToStable = false, + string specifiedVersion = null) { var currentVersion = (string) package.Value; var version = ""; - if ((includePreviews || (!switchToStable && currentVersion.Contains("-preview"))) && !includeReleaseCandidates) + if (!specifiedVersion.IsNullOrWhiteSpace()) { - version = "preview"; + if (!SpecifiedVersionExists(specifiedVersion, package)) + { + return false; + } + + if (SemanticVersion.Parse(specifiedVersion) <= SemanticVersion.Parse(currentVersion.RemovePreFix("~", "^"))) + { + return false; + } + version = specifiedVersion.EnsureStartsWith('^'); } else { - if (!switchToStable && IsPrerelease(currentVersion)) + if ((includePreviews || (!switchToStable && currentVersion.Contains("-preview"))) && !includeReleaseCandidates) { - version = await GetLatestVersion(package, true); + version = "preview"; } else { - version = await GetLatestVersion(package, includeReleaseCandidates); + if (!switchToStable && IsPrerelease(currentVersion)) + { + version = await GetLatestVersion(package, true); + } + else + { + version = await GetLatestVersion(package, includeReleaseCandidates); + } } } + if (string.IsNullOrEmpty(version) || version == currentVersion) { return false; @@ -267,9 +286,7 @@ namespace Volo.Abp.Cli.ProjectModification return _fileVersionStorage[package.Name]; } - var versionListAsJson = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} versions"); - var versionList = JsonConvert.DeserializeObject(versionListAsJson) - .OrderByDescending(SemanticVersion.Parse, new VersionComparer()).ToList(); + var versionList = GetPackageVersionList(package); var newVersion = includeReleaseCandidates ? versionList.First() @@ -327,5 +344,19 @@ namespace Volo.Abp.Cli.ProjectModification Logger.LogInformation($"Running npm install on {fileDirectory}"); CmdHelper.RunCmd($"cd {fileDirectory} && npm install"); } + + protected virtual List GetPackageVersionList(JProperty package) + { + var versionListAsJson = CmdHelper.RunCmdAndGetOutput($"npm show {package.Name} versions"); + return JsonConvert.DeserializeObject(versionListAsJson) + .OrderByDescending(SemanticVersion.Parse, new VersionComparer()).ToList(); + } + + protected virtual bool SpecifiedVersionExists(string version, JProperty package) + { + var versionList = GetPackageVersionList(package); + + return versionList.Any(v => v.Equals(version, StringComparison.OrdinalIgnoreCase)); + } } } 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 275bf23c76..c499dd0ee0 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 @@ -25,11 +25,11 @@ namespace Volo.Abp.Cli.ProjectModification Logger = NullLogger.Instance; } - public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool includeReleaseCandidates = 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, string version = null) { var projectPaths = ProjectFinder.GetProjectFiles(solutionPath); - if (checkAll) + if (checkAll && version.IsNullOrWhiteSpace()) { Task.WaitAll(projectPaths.Select(projectPath => UpdateInternalAsync(projectPath, includePreviews, includeReleaseCandidates, switchToStable)).ToArray()); } @@ -48,7 +48,8 @@ namespace Volo.Abp.Cli.ProjectModification switchToStable, latestVersionFromNuget, latestReleaseCandidateVersionFromNuget, - latestVersionFromMyGet); + latestVersionFromMyGet, + version); File.WriteAllText(filePath, updatedContent); } @@ -57,9 +58,9 @@ namespace Volo.Abp.Cli.ProjectModification } } - public async Task UpdateProjectAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = 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, string version = null) { - if (checkAll) + if (checkAll && version.IsNullOrWhiteSpace()) { await UpdateInternalAsync(projectPath, includeNightlyPreviews, includeReleaseCandidates, switchToStable); } @@ -77,7 +78,8 @@ namespace Volo.Abp.Cli.ProjectModification switchToStable, latestVersionFromNuget, latestReleaseCandidateVersionFromNuget, - latestVersionFromMyGet); + latestVersionFromMyGet, + version); File.WriteAllText(projectPath, updatedContent); } @@ -91,13 +93,26 @@ namespace Volo.Abp.Cli.ProjectModification File.WriteAllText(projectPath, updatedContent); } + protected virtual async Task SpecifiedVersionExists(string version, string packageId) + { + var versionList = await _nuGetService.GetPackageVersionListAsync(packageId); + + if (versionList.All(v => !v.Equals(version, StringComparison.OrdinalIgnoreCase))) + { + versionList = await _nuGetService.GetPackageVersionListAsync(packageId, true); + } + + return versionList.Any(v => v.Equals(version, StringComparison.OrdinalIgnoreCase)); + } + private async Task UpdateVoloPackagesAsync(string content, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, SemanticVersion latestNugetVersion = null, SemanticVersion latestNugetReleaseCandidateVersion = null, - string latestMyGetVersion = null) + string latestMyGetVersion = null, + string specifiedVersion = null) { string packageId = null; @@ -129,40 +144,63 @@ namespace Volo.Abp.Cli.ProjectModification Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, currentSemanticVersion); - if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates) + if (!specifiedVersion.IsNullOrWhiteSpace()) { - var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId); - - if (currentVersion != latestVersion) + if (await SpecifiedVersionExists(specifiedVersion, packageId)) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, latestVersion); - versionAttribute.Value = latestVersion; + var specifiedSemanticVersion = SemanticVersion.Parse(specifiedVersion); + if (specifiedSemanticVersion > currentSemanticVersion) + { + Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, specifiedVersion); + versionAttribute.Value = specifiedVersion; + } + else + { + Logger.LogWarning("Unable to update package \"{0}\" version v{1} to v{2}.", packageId, currentVersion, specifiedVersion); + } } else { - Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, currentVersion); + Logger.LogWarning("Package \"{0}\" specified version v{1} does not exist.", packageId, specifiedVersion); } } else { - 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 && (currentSemanticVersion < latestVersion || (currentSemanticVersion.IsPrerelease && switchToStable))) + if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentSemanticVersion.ToString(), latestVersion.ToString()); - versionAttribute.Value = latestVersion.ToString(); + var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId); + + 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.LogInformation("Package: \"{0}-v{1}\" is up to date.", packageId, currentSemanticVersion); + 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 && (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(); + } + else + { + Logger.LogInformation("Package: \"{0}-v{1}\" is up to date.", packageId, currentSemanticVersion); + } } } } From e5729e24f792f7acab7496460d7b134ed332c6f6 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 7 Dec 2020 23:15:43 +0800 Subject: [PATCH 2/2] Update CLI.md --- docs/en/CLI.md | 1 + docs/zh-Hans/CLI.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/CLI.md b/docs/en/CLI.md index d51dd91b5d..c5eb38bbbe 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -129,6 +129,7 @@ abp update [options] * `--solution-path` or `-sp`: Specify the solution path. Use the current directory by default * `--solution-name` or `-sn`: Specify the solution name. Search `*.sln` files in the directory by default. * `--check-all`: Check the new version of each package separately. Default is `false`. +* `--version` or `-v`: Specifies the version to use for update. If not specified, latest version is used. ### add-package diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md index 3390ce99b3..4c63dcd818 100644 --- a/docs/zh-Hans/CLI.md +++ b/docs/zh-Hans/CLI.md @@ -126,6 +126,7 @@ abp update [options] * `--solution-path` 或 `-sp`: 指定解决方案路径/目录. 默认使用当前目录 * `--solution-name` 或 `-sn`: 指定解决方案名称. 默认在目录中搜索`*.sln`文件. * `--check-all`: 分别检查每个包的新版本. 默认是 `false`. +* `--version` or `-v`: 指定用于升级的版本. 如果没有指定,则使用最新版本. ### add-package