From 489e855bc057342c40a8b3ea7a25aa73e1962a44 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 2 Oct 2020 11:28:53 +0300 Subject: [PATCH] Cli add-module improvements & blazor support resolves https://github.com/abpframework/abp/issues/5454 resolves https://github.com/abpframework/abp/issues/5680 --- .../ProjectModification/NuGetPackageTarget.cs | 5 +- .../Cli/ProjectModification/ProjectFinder.cs | 6 +- .../SolutionFileModifier.cs | 61 +++++++++++++++- .../SolutionModuleAdder.cs | 69 +++++++++++++++++-- 4 files changed, 127 insertions(+), 14 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageTarget.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageTarget.cs index 890053049f..10274f3528 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageTarget.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageTarget.cs @@ -12,6 +12,7 @@ Web = 7, EntityFrameworkCore = 8, MongoDB = 9, - SignalR = 10 + SignalR = 10, + Blazor = 11 } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs index d4b3a62b94..0c02f8cb87 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs @@ -45,6 +45,8 @@ namespace Volo.Abp.Cli.ProjectModification return FindProjectEndsWith(projectFiles, assemblyNames, ".SignalR") ?? FindProjectEndsWith(projectFiles, assemblyNames, ".Web") ?? FindProjectEndsWith(projectFiles, assemblyNames, ".HttpApi.Host"); + case NuGetPackageTarget.Blazor: + return FindProjectEndsWith(projectFiles, assemblyNames, ".Blazor"); default: return null; } @@ -103,8 +105,8 @@ namespace Volo.Abp.Cli.ProjectModification private static string FindProjectEndsWith( string[] projectFiles, - string[] assemblyNames, - string postfix, + string[] assemblyNames, + string postfix, string excludePostfix = null) { for (var i = 0; i < assemblyNames.Length; i++) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs index 4eabeaa846..a24b31e5f1 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs @@ -10,6 +10,61 @@ namespace Volo.Abp.Cli.ProjectModification { public class SolutionFileModifier : ITransientDependency { + public async Task RemoveProjectFromSolutionFileAsync(string solutionFile, string projectName) + { + var solutionFileContent = File.ReadAllText(solutionFile); + solutionFileContent.NormalizeLineEndings(); + var lines = solutionFileContent.Split(new[] {Environment.NewLine, "\n"}, StringSplitOptions.None); + File.WriteAllText(solutionFile, RemoveProject(lines.ToList(), projectName).JoinAsString(Environment.NewLine)); + } + + private List RemoveProject(List solutionFileLines, string projectName) + { + var projectKey = FindProjectKey(solutionFileLines, projectName); + + if (projectKey == null) + { + return solutionFileLines; + } + + var newSolutionFileLines = new List(); + var firstOccurence = true; + + for (var i = 0; i < solutionFileLines.Count; ++i) + { + if (solutionFileLines[i].Contains(projectKey)) + { + if (firstOccurence) + { + firstOccurence = false; + ++i; //Skip "EndProject" line too. + } + + continue; + } + + newSolutionFileLines.Add(solutionFileLines[i]); + } + + return newSolutionFileLines; + } + + private string FindProjectKey(List solutionFileLines, string projectName) + { + var projectNameWithQuotes = $"\"{projectName}\""; + foreach (var solutionFileLine in solutionFileLines) + { + if (solutionFileLine.Contains(projectNameWithQuotes)) + { + var curlyBracketStartIndex = solutionFileLine.LastIndexOf("{", StringComparison.OrdinalIgnoreCase); + var curlyBracketEndIndex = solutionFileLine.LastIndexOf("}", StringComparison.OrdinalIgnoreCase); + return solutionFileLine.Substring(curlyBracketStartIndex + 1, curlyBracketEndIndex - curlyBracketStartIndex - 1); + } + } + + return null; + } + public async Task AddModuleToSolutionFileAsync(ModuleWithMastersInfo module, string solutionFile) { await AddModule(module, solutionFile); @@ -19,7 +74,7 @@ namespace Volo.Abp.Cli.ProjectModification { var srcModuleFolderId = await AddNewFolderAndGetIdOrGetExistingId(solutionFile, module.Name, await AddNewFolderAndGetIdOrGetExistingId(solutionFile, "modules")); var testModuleFolderId = await AddNewFolderAndGetIdOrGetExistingId(solutionFile, module.Name + ".Tests", await AddNewFolderAndGetIdOrGetExistingId(solutionFile, "test")); - + var file = File.ReadAllText(solutionFile); var lines = file.Split(Environment.NewLine).ToList(); @@ -52,7 +107,7 @@ namespace Volo.Abp.Cli.ProjectModification + Environment.NewLine + "EndProject"; lines.InsertAfter(l => l.Trim().Equals("EndProject"), newProjectLine); - + var newPostSolutionLine = " {" + projectGuid + "}.Debug|Any CPU.ActiveCfg = Debug|Any CPU" + Environment.NewLine + " {" + projectGuid + "}.Debug|Any CPU.Build.0 = Debug|Any CPU" + Environment.NewLine + @@ -60,7 +115,7 @@ namespace Volo.Abp.Cli.ProjectModification " {" + projectGuid + "}.Release|Any CPU.Build.0 = Release|Any CPU"; lines.InsertAfter(l=>l.Contains("GlobalSection") && l.Contains("ProjectConfigurationPlatforms"), newPostSolutionLine); - + var newPreSolutionLine = " {"+ projectGuid + "} = {"+ parentFolderId + "}"; 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 4cbeb2ba26..cc563f97cf 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 @@ -76,7 +76,8 @@ namespace Volo.Abp.Cli.ProjectModification var module = await FindModuleInfoAsync(moduleName); - Logger.LogInformation($"Installing module '{module.Name}' to the solution '{Path.GetFileNameWithoutExtension(solutionFile)}'"); + Logger.LogInformation( + $"Installing module '{module.Name}' to the solution '{Path.GetFileNameWithoutExtension(solutionFile)}'"); var projectFiles = ProjectFinder.GetProjectFiles(solutionFile); @@ -86,6 +87,7 @@ namespace Volo.Abp.Cli.ProjectModification { var modulesFolderInSolution = Path.Combine(Path.GetDirectoryName(solutionFile), "modules"); await DownloadSourceCodesToSolutionFolder(module, modulesFolderInSolution, version); + await RemoveUnnecessaryProjectsAsync(Path.GetDirectoryName(solutionFile), module, projectFiles); if (addSourceCodeToSolutionFile) { @@ -103,6 +105,53 @@ namespace Volo.Abp.Cli.ProjectModification ModifyDbContext(projectFiles, module, startupProject, skipDbMigrations); } + private async Task RemoveUnnecessaryProjectsAsync(string solutionDirectory, ModuleWithMastersInfo module, string[] projectFiles) + { + var moduleDirectory = Path.Combine(solutionDirectory, "modules", module.Name); + var moduleSolutionFile = Directory.GetFiles(moduleDirectory, "*.sln", SearchOption.TopDirectoryOnly).First(); + var isProjectTiered = await IsProjectTiered(projectFiles); + + if (!projectFiles.Any(p => p.EndsWith(".Blazor.csproj"))) + { + await RemoveProjectByTarget(module, moduleSolutionFile, NuGetPackageTarget.Blazor,isProjectTiered); + } + + if (!projectFiles.Any(p => p.EndsWith(".Web.csproj"))) + { + await RemoveProjectByTarget(module, moduleSolutionFile, NuGetPackageTarget.Web, isProjectTiered); + } + + if (!projectFiles.Any(p => p.EndsWith(".MongoDB.csproj"))) + { + await RemoveProjectByTarget(module, moduleSolutionFile, NuGetPackageTarget.MongoDB, isProjectTiered); + } + + if (!projectFiles.Any(p => p.EndsWith(".EntityFrameworkCore.csproj"))) + { + await RemoveProjectByTarget(module, moduleSolutionFile, NuGetPackageTarget.EntityFrameworkCore, isProjectTiered); + } + } + + private async Task RemoveProjectByTarget(ModuleWithMastersInfo module, string moduleSolutionFile, NuGetPackageTarget target, bool isTieredProject) + { + var packages = module.NugetPackages.Where(n => + (isTieredProject && n.TieredTarget != NuGetPackageTarget.Undefined + ? n.TieredTarget + : n.Target) == target + ).ToList(); + + foreach (var package in packages) + { + await SolutionFileModifier.RemoveProjectFromSolutionFileAsync(moduleSolutionFile, package.Name); + + var projectPath = Path.Combine(Path.GetDirectoryName(moduleSolutionFile), "src", package.Name); + if (Directory.Exists(projectPath)) + { + Directory.Delete(projectPath, true); + } + } + } + private async Task AddAngularPackages(string solutionFilePath, ModuleWithMastersInfo module) { var angularPath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(solutionFilePath)), "angular"); @@ -112,7 +161,8 @@ namespace Volo.Abp.Cli.ProjectModification return; } - var angularPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Angular)).ToList(); + var angularPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Angular)) + .ToList(); if (!angularPackages.IsNullOrEmpty()) { @@ -150,7 +200,8 @@ namespace Volo.Abp.Cli.ProjectModification } } - private async Task DownloadSourceCodesToSolutionFolder(ModuleWithMastersInfo module, string modulesFolderInSolution, string version = null) + private async Task DownloadSourceCodesToSolutionFolder(ModuleWithMastersInfo module, + string modulesFolderInSolution, string version = null) { var targetModuleFolder = Path.Combine(modulesFolderInSolution, module.Name); @@ -216,7 +267,8 @@ namespace Volo.Abp.Cli.ProjectModification await ProjectNugetPackageAdder.AddAsync(targetProjectFile, nugetPackage); } - var mvcNpmPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Mvc)).ToList(); + var mvcNpmPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Mvc)) + .ToList(); if (!mvcNpmPackages.IsNullOrEmpty()) { @@ -240,7 +292,8 @@ namespace Volo.Abp.Cli.ProjectModification } } - protected void ModifyDbContext(string[] projectFiles, ModuleInfo module, string startupProject, bool skipDbMigrations = false) + protected void ModifyDbContext(string[] projectFiles, ModuleInfo module, string startupProject, + bool skipDbMigrations = false) { if (string.IsNullOrWhiteSpace(module.EfCoreConfigureMethodName)) { @@ -275,11 +328,13 @@ namespace Volo.Abp.Cli.ProjectModification if (dbContextFile == null) { - Logger.LogDebug($"{dbMigrationsProject} project doesn't have a class that is derived from \"AbpDbContext\"."); + Logger.LogDebug( + $"{dbMigrationsProject} project doesn't have a class that is derived from \"AbpDbContext\"."); return; } - var addedNewBuilder = DbContextFileBuilderConfigureAdder.Add(dbContextFile, module.EfCoreConfigureMethodName); + var addedNewBuilder = + DbContextFileBuilderConfigureAdder.Add(dbContextFile, module.EfCoreConfigureMethodName); if (!skipDbMigrations) {