From 058af963f09428f6fece2cc8fab4e051affa8e44 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 22 Jun 2025 09:22:17 +0800 Subject: [PATCH] Support to install the MVC npm package. --- .../Abp/Cli/Commands/AddPackageCommand.cs | 16 +++---- .../INpmPackageInfoProvider.cs | 5 ++- .../ProjectBuilding/NpmPackageInfoProvider.cs | 4 +- .../ProjectNpmPackageAdder.cs | 43 +++++++++++++------ .../SolutionModuleAdder.cs | 2 +- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs index f2197fa596..32d9f49799 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Cli.Commands; public class AddPackageCommand : IConsoleCommand, ITransientDependency { public const string Name = "add-package"; - + public ILogger Logger { get; set; } protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; } @@ -40,12 +40,12 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency ); } - var isAngularPackage = false; + var isNpmPackage = false; var isNugetPackage = true; if (commandLineArgs.Target.StartsWith("@")) { - isAngularPackage = true; + isNpmPackage = true; isNugetPackage = false; } @@ -66,16 +66,15 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency addSourceCodeToSolutionFile ); } - else if (isAngularPackage) + else if (isNpmPackage) { - await ProjectNpmPackageAdder.AddAngularPackageAsync( + await ProjectNpmPackageAdder.AddNpmPackageAsync( GetAngularDirectory(commandLineArgs), commandLineArgs.Target, version, withSourceCode ); } - } public string GetUsageInfo() @@ -84,7 +83,7 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency sb.AppendLine(""); sb.AppendLine("'add-package' command is used to add an ABP package to a project."); - sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file or angular.json."); + sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file or packages.json."); sb.AppendLine(""); sb.AppendLine("Usage:"); sb.AppendLine(""); @@ -94,7 +93,7 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency sb.AppendLine(""); sb.AppendLine(" -p|--project Specifies the project file explicitly. (Only available for NuGet packages)"); sb.AppendLine(" -s|--solution Specifies the solution file explicitly. (Only available for NuGet packages)"); - sb.AppendLine(" --with-source-code Downloads the source code of the NPM/NuGet package and make other projects depends on it."); + sb.AppendLine(" --with-source-code Downloads the source code of the Angular NPM/NuGet package and make other projects depends on it."); sb.AppendLine(" --add-to-solution-file Adds the downloaded project to the .sln file, when source code is downloaded. (Only available for NuGet packages)"); sb.AppendLine(" -ad|--angular-directory Specifies the Angular project directory explicitly. (Only available for Angular packages)"); sb.AppendLine(" -v|--version Specifies the version of the package. Default is your project's ABP version or latest ABP version."); @@ -103,6 +102,7 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency sb.AppendLine(""); sb.AppendLine(" abp add-package Volo.Abp.FluentValidation Adds the NuGet package to the current project."); sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the NuGet package to the given project."); + sb.AppendLine(" abp add-package @abp/signalr Adds the NPM package to the given corresponding project."); sb.AppendLine(" abp add-package @abp/ng.theme.basic Adds the NPM package to the given corresponding project."); sb.AppendLine(""); sb.AppendLine("See the documentation for more info: https://abp.io/docs/latest/cli"); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs index cfa6e2347c..018d821ede 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.Cli.ProjectModification; namespace Volo.Abp.Cli.ProjectBuilding; @@ -6,4 +7,6 @@ namespace Volo.Abp.Cli.ProjectBuilding; public interface INpmPackageInfoProvider { Task GetAsync(string name); + + Task> GetPackageListAsync(); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs index d95588ee57..27fb3f88a7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs @@ -32,7 +32,7 @@ public class NpmPackageInfoProvider : INpmPackageInfoProvider, ITransientDepende public async Task GetAsync(string name) { - var packageList = await GetPackageListInternalAsync(); + var packageList = await GetPackageListAsync(); var package = packageList.FirstOrDefault(m => m.Name == name); @@ -44,7 +44,7 @@ public class NpmPackageInfoProvider : INpmPackageInfoProvider, ITransientDepende return package; } - private async Task> GetPackageListInternalAsync() + public async Task> GetPackageListAsync() { var client = _cliHttpClientFactory.CreateClient(); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs index 07705808ae..9b7b17d57e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs @@ -24,16 +24,20 @@ public class ProjectNpmPackageAdder : ITransientDependency public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } public IInstallLibsService InstallLibsService { get; } public ICmdHelper CmdHelper { get; } - private readonly CliHttpClientFactory _cliHttpClientFactory; + public CliHttpClientFactory CliHttpClientFactory { get; } + public INpmPackageInfoProvider NpmPackageInfoProvider { get; } + public ILogger Logger { get; set; } - public ProjectNpmPackageAdder(CliHttpClientFactory cliHttpClientFactory, + public ProjectNpmPackageAdder( IJsonSerializer jsonSerializer, SourceCodeDownloadService sourceCodeDownloadService, AngularSourceCodeAdder angularSourceCodeAdder, IRemoteServiceExceptionHandler remoteServiceExceptionHandler, IInstallLibsService installLibsService, - ICmdHelper cmdHelper) + ICmdHelper cmdHelper, + CliHttpClientFactory cliHttpClientFactory, + INpmPackageInfoProvider npmPackageInfoProvider) { JsonSerializer = jsonSerializer; SourceCodeDownloadService = sourceCodeDownloadService; @@ -41,14 +45,16 @@ public class ProjectNpmPackageAdder : ITransientDependency RemoteServiceExceptionHandler = remoteServiceExceptionHandler; InstallLibsService = installLibsService; CmdHelper = cmdHelper; - _cliHttpClientFactory = cliHttpClientFactory; + CliHttpClientFactory = cliHttpClientFactory; + NpmPackageInfoProvider = npmPackageInfoProvider; + Logger = NullLogger.Instance; } - public async Task AddAngularPackageAsync(string directory, string npmPackageName, string version = null, + public async Task AddNpmPackageAsync(string directory, string npmPackageName, string version = null, bool withSourceCode = false) { - await AddAngularPackageAsync( + await AddNpmPackageAsync( directory, await FindNpmPackageInfoAsync(npmPackageName), version, @@ -56,7 +62,7 @@ public class ProjectNpmPackageAdder : ITransientDependency ); } - public async Task AddAngularPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, + public async Task AddNpmPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, bool withSourceCode = false) { var packageJsonFilePath = Path.Combine(directory, "package.json"); @@ -83,16 +89,27 @@ public class ProjectNpmPackageAdder : ITransientDependency Logger.LogInformation($"'{npmPackage.Name}' is already installed."); } - if (withSourceCode) + if (withSourceCode && await DownloadAngularSourceCode(directory, npmPackage, version)) { - await DownloadAngularSourceCode(directory, npmPackage, version); await AngularSourceCodeAdder.AddAsync(directory, npmPackage); } } - protected virtual async Task DownloadAngularSourceCode(string angularDirectory, NpmPackageInfo package, + protected virtual async Task DownloadAngularSourceCode(string angularDirectory, NpmPackageInfo package, string version = null) { + var downloadablePackages = await NpmPackageInfoProvider.GetPackageListAsync(); + if (!downloadablePackages.Exists(p => p.Name == package.Name)) + { + Logger.LogError($"'{package.Name}' is not downloadable!"); + Logger.LogInformation("The downloadable packages are: "); + foreach (var downloadablePackage in downloadablePackages) + { + Logger.LogInformation($"> {downloadablePackage.Name}"); + } + return false; + } + var targetFolder = Path.Combine(angularDirectory, "projects", package.Name.RemovePreFix("@").Replace("/", "-")); @@ -106,6 +123,8 @@ public class ProjectNpmPackageAdder : ITransientDependency targetFolder, version ); + + return true; } public async Task AddMvcPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, @@ -210,9 +229,9 @@ public class ProjectNpmPackageAdder : ITransientDependency private async Task FindNpmPackageInfoAsync(string packageName) { var url = $"{CliUrls.WwwAbpIo}api/app/npmPackage/byName/?name=" + packageName; - var client = _cliHttpClientFactory.CreateClient(); + var client = CliHttpClientFactory.CreateClient(); - using (var response = await client.GetAsync(url, _cliHttpClientFactory.GetCancellationToken())) + using (var response = await client.GetAsync(url, CliHttpClientFactory.GetCancellationToken())) { if (!response.IsSuccessStatusCode) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index 9873a09b58..1c6a2abd3f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -513,7 +513,7 @@ public class SolutionModuleAdder : ITransientDependency foreach (var npmPackage in angularPackages) { - await ProjectNpmPackageAdder.AddAngularPackageAsync(angularPath, npmPackage); + await ProjectNpmPackageAdder.AddNpmPackageAsync(angularPath, npmPackage); } } }