|  |  |  | @ -1,12 +1,13 @@ | 
			
		
	
		
			
				
					|  |  |  |  | using System; | 
			
		
	
		
			
				
					|  |  |  |  | using JetBrains.Annotations; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.Extensions.Logging; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.Extensions.Logging.Abstractions; | 
			
		
	
		
			
				
					|  |  |  |  | using System; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Collections.Generic; | 
			
		
	
		
			
				
					|  |  |  |  | using System.IO; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Linq; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Net; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Net.Http; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Threading.Tasks; | 
			
		
	
		
			
				
					|  |  |  |  | using JetBrains.Annotations; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.Extensions.Logging; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.Extensions.Logging.Abstractions; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.DependencyInjection; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.Json; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -18,13 +19,16 @@ namespace Volo.Abp.Cli.ProjectModification | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         protected IJsonSerializer JsonSerializer { get; } | 
			
		
	
		
			
				
					|  |  |  |  |         protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; } | 
			
		
	
		
			
				
					|  |  |  |  |         protected ProjectNpmPackageAdder ProjectNpmPackageAdder { get; } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public SolutionModuleAdder( | 
			
		
	
		
			
				
					|  |  |  |  |             IJsonSerializer jsonSerializer, | 
			
		
	
		
			
				
					|  |  |  |  |             ProjectNugetPackageAdder projectNugetPackageAdder) | 
			
		
	
		
			
				
					|  |  |  |  |             ProjectNugetPackageAdder projectNugetPackageAdder, | 
			
		
	
		
			
				
					|  |  |  |  |             ProjectNpmPackageAdder projectNpmPackageAdder) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             JsonSerializer = jsonSerializer; | 
			
		
	
		
			
				
					|  |  |  |  |             ProjectNugetPackageAdder = projectNugetPackageAdder; | 
			
		
	
		
			
				
					|  |  |  |  |             ProjectNpmPackageAdder = projectNpmPackageAdder; | 
			
		
	
		
			
				
					|  |  |  |  |             Logger = NullLogger<SolutionModuleAdder>.Instance; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -36,87 +40,41 @@ namespace Volo.Abp.Cli.ProjectModification | 
			
		
	
		
			
				
					|  |  |  |  |             Check.NotNull(moduleName, nameof(moduleName)); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             var module = await FindModuleInfoAsync(moduleName); | 
			
		
	
		
			
				
					|  |  |  |  |             var projectFiles = GetProjectFiles(solutionFile); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.LogInformation($"Installing module '{module.Name}' to the solution '{Path.GetFileNameWithoutExtension(solutionFile)}'"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             var projectFiles = ProjectFinder.GetProjectFiles(solutionFile); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             foreach (var nugetPackage in module.NugetPackages) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 var targetProjectFile = FindTargetProjectFile(projectFiles, nugetPackage.Target); | 
			
		
	
		
			
				
					|  |  |  |  |                 var targetProjectFile = ProjectFinder.FindNuGetTargetProjectFile(projectFiles, nugetPackage.Target); | 
			
		
	
		
			
				
					|  |  |  |  |                 if (targetProjectFile == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 { | 
			
		
	
		
			
				
					|  |  |  |  |                     Logger.LogDebug($"Target project is not available for NuGet package '{nugetPackage.Name}'"); | 
			
		
	
		
			
				
					|  |  |  |  |                     continue; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 await ProjectNugetPackageAdder.AddAsync(targetProjectFile, nugetPackage); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         private string FindTargetProjectFile(string[] projectFiles, NuGetPackageTarget target) | 
			
		
	
		
			
				
					|  |  |  |  |             if (!module.NpmPackages.IsNullOrEmpty()) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |             if (!projectFiles.Any()) | 
			
		
	
		
			
				
					|  |  |  |  |                 var targetProjects = ProjectFinder.FindNpmTargetProjectFile(projectFiles); | 
			
		
	
		
			
				
					|  |  |  |  |                 if (targetProjects.Any()) | 
			
		
	
		
			
				
					|  |  |  |  |                 { | 
			
		
	
		
			
				
					|  |  |  |  |                 return null; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             var assemblyNames = projectFiles | 
			
		
	
		
			
				
					|  |  |  |  |                 .Select( | 
			
		
	
		
			
				
					|  |  |  |  |                     filePath => filePath | 
			
		
	
		
			
				
					|  |  |  |  |                         .Replace("\\", "/") | 
			
		
	
		
			
				
					|  |  |  |  |                         .Substring(filePath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1) | 
			
		
	
		
			
				
					|  |  |  |  |                         .RemovePostFix(StringComparison.OrdinalIgnoreCase, ".csproj") | 
			
		
	
		
			
				
					|  |  |  |  |                 ).ToArray(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             switch (target) | 
			
		
	
		
			
				
					|  |  |  |  |                     foreach (var targetProject in targetProjects) | 
			
		
	
		
			
				
					|  |  |  |  |                     { | 
			
		
	
		
			
				
					|  |  |  |  |                         foreach (var npmPackage in module.NpmPackages.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Mvc))) | 
			
		
	
		
			
				
					|  |  |  |  |                         { | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.Web: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.EntityFrameworkCore: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".EntityFrameworkCore") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.MongoDB: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".MongoDB") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.Application: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".Application") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.ApplicationContracts: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".Application.Contracts"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.Domain: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".Domain") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Application") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.DomainShared: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".Domain.Shared"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.HttpApi: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".HttpApi") ?? | 
			
		
	
		
			
				
					|  |  |  |  |                            FindProjectEndsWith(assemblyNames, ".Web"); | 
			
		
	
		
			
				
					|  |  |  |  |                 case NuGetPackageTarget.HttpApiClient: | 
			
		
	
		
			
				
					|  |  |  |  |                     return FindProjectEndsWith(assemblyNames, ".HttpApi.Client"); | 
			
		
	
		
			
				
					|  |  |  |  |                 default: | 
			
		
	
		
			
				
					|  |  |  |  |                     throw new ApplicationException($"{nameof(NuGetPackageTarget)} has not implemented: {target}"); | 
			
		
	
		
			
				
					|  |  |  |  |                             await ProjectNpmPackageAdder.AddAsync(Path.GetDirectoryName(targetProject), npmPackage); | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         private static string FindProjectEndsWith(string[] projectAssemblyNames, string postfix) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             return projectAssemblyNames.FirstOrDefault(p => p.EndsWith(postfix, StringComparison.OrdinalIgnoreCase)); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         protected virtual string[] GetProjectFiles(string solutionFile) | 
			
		
	
		
			
				
					|  |  |  |  |                 else | 
			
		
	
		
			
				
					|  |  |  |  |                 { | 
			
		
	
		
			
				
					|  |  |  |  |             var baseProjectFolder = GetBaseProjectFolder(solutionFile); | 
			
		
	
		
			
				
					|  |  |  |  |             return Directory.GetFiles(baseProjectFolder, "*.csproj", SearchOption.AllDirectories); | 
			
		
	
		
			
				
					|  |  |  |  |                     Logger.LogDebug("Target project is not available for NPM packages."); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         protected virtual string GetBaseProjectFolder(string solutionFile) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             var baseFolder = Path.GetDirectoryName(solutionFile); | 
			
		
	
		
			
				
					|  |  |  |  |             var srcFolder = Path.Combine(baseFolder, "src"); | 
			
		
	
		
			
				
					|  |  |  |  |             if (Directory.Exists(srcFolder)) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 baseFolder = srcFolder; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             return baseFolder; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  |         protected virtual async Task<ModuleInfo> FindModuleInfoAsync(string moduleName) | 
			
		
	
	
		
			
				
					|  |  |  | 
 |