From da07de833048b73a7a83d38686b723c3e2597e6e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 24 Feb 2021 17:18:53 +0300 Subject: [PATCH] ABP CLI support to create services for the microservice solution resolves https://github.com/volosoft/volo/issues/5514 --- .../Volo/Abp/Cli/Commands/NewCommand.cs | 57 ++++++++++++++--- .../Steps/ProjectReferenceReplaceStep.cs | 30 +++++---- .../Steps/RemoveProjectFromSolutionStep.cs | 4 +- .../Building/Steps/SolutionRenameStep.cs | 28 ++++++--- .../TemplateProjectBuildPipelineBuilder.cs | 3 +- .../Abp/Cli/ProjectBuilding/SolutionName.cs | 7 ++- .../ProjectBuilding/TemplateInfoProvider.cs | 4 +- .../MicroserviceServiceProTemplate.cs | 16 +++++ .../MicroserviceServiceTemplateBase.cs | 62 +++++++++++++++++++ .../Microservice/MicroserviceTemplateBase.cs | 26 ++++++-- 10 files changed, 198 insertions(+), 39 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceProTemplate.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index c82c434916..051c76031d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -147,19 +147,34 @@ namespace Volo.Abp.Cli.Commands } var createSolutionFolder = GetCreateSolutionFolderPreference(commandLineArgs); - if (!createSolutionFolder) - { - Logger.LogInformation("Create Solution Folder: no"); - } var outputFolder = commandLineArgs.Options.GetOrNull(Options.OutputFolder.Short, Options.OutputFolder.Long); var outputFolderRoot = outputFolder != null ? Path.GetFullPath(outputFolder) : Directory.GetCurrentDirectory(); - outputFolder = createSolutionFolder ? - Path.Combine(outputFolderRoot, SolutionName.Parse(projectName).FullName) : - outputFolderRoot; + SolutionName solutionName; + if (MicroserviceServiceTemplateBase.IsMicroserviceServiceTemplate(template)) + { + var microserviceSolutionName = FindMicroserviceSolutionName(outputFolderRoot); + + if (microserviceSolutionName == null) + { + throw new CliUsageException("This command should be run inside a folder that contains a microservice solution!"); + } + + solutionName = SolutionName.Parse(microserviceSolutionName, projectName); + outputFolder = MicroserviceServiceTemplateBase.CalculateTargetFolder(outputFolderRoot, projectName); + uiFramework = uiFramework == UiFramework.NotSpecified ? FindMicroserviceSolutionUiFramework(outputFolderRoot) : uiFramework; + } + else + { + solutionName = SolutionName.Parse(projectName); + + outputFolder = createSolutionFolder ? + Path.Combine(outputFolderRoot, SolutionName.Parse(projectName).FullName) : + outputFolderRoot; + } Volo.Abp.IO.DirectoryHelper.CreateIfNotExists(outputFolder); @@ -176,7 +191,7 @@ namespace Volo.Abp.Cli.Commands var result = await TemplateProjectBuilder.BuildAsync( new ProjectBuildArgs( - SolutionName.Parse(projectName), + solutionName, template, version, databaseProvider, @@ -245,6 +260,32 @@ namespace Volo.Abp.Cli.Commands } } + private string FindMicroserviceSolutionName(string outputFolderRoot) + { + var slnFile = Directory.GetFiles(outputFolderRoot, "*.sln").FirstOrDefault(); + + if (slnFile == null) + { + return null; + } + + return Path.GetFileName(slnFile).RemovePostFix(".sln"); + } + + private UiFramework FindMicroserviceSolutionUiFramework(string outputFolderRoot) + { + if (Directory.Exists(Path.Combine(outputFolderRoot, "applications", "blazor"))) + { + return UiFramework.Blazor; + } + if (Directory.Exists(Path.Combine(outputFolderRoot, "applications", "web"))) + { + return UiFramework.Mvc; + } + + return UiFramework.None; + } + private void OpenThanksPage(UiFramework uiFramework, DatabaseProvider databaseProvider, bool tiered, bool commercial) { uiFramework = uiFramework == UiFramework.NotSpecified || uiFramework == UiFramework.None ? UiFramework.Mvc : uiFramework; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs index 698c7f1d8d..dafdc28dc4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text.RegularExpressions; using System.Xml; using Volo.Abp.Cli.ProjectBuilding.Files; +using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; using Volo.Abp.Cli.Utils; namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps @@ -25,7 +26,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var localVoloRepoPath = context.BuildArgs.VoloGitHubLocalRepositoryPath; new ProjectReferenceReplacer.LocalProjectPathReferenceReplacer( - context.Files, + context, context.Module?.Namespace ?? "MyCompanyName.MyProjectName", localAbpRepoPath, localVoloRepoPath @@ -41,7 +42,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps } new ProjectReferenceReplacer.NugetReferenceReplacer( - context.Files, + context, context.Module?.Namespace ?? "MyCompanyName.MyProjectName", nugetPackageVersion ).Run(); @@ -70,13 +71,15 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private abstract class ProjectReferenceReplacer { private readonly List _entries; + private readonly bool _isMicroserviceServiceTemplate; private readonly string _projectName; protected ProjectReferenceReplacer( - List entries, + ProjectBuildContext context, string projectName) { - _entries = entries; + _entries = context.Files; + _isMicroserviceServiceTemplate = MicroserviceServiceTemplateBase.IsMicroserviceServiceTemplate(context.Template?.Name); _projectName = projectName; } @@ -113,14 +116,15 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var oldNodeIncludeValue = oldNode.Attributes["Include"].Value; // ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method - if (oldNodeIncludeValue.Contains(_projectName) && _entries.Any(e=>e.Name.EndsWith(GetProjectNameWithExtensionFromProjectReference(oldNodeIncludeValue)))) + if (oldNodeIncludeValue.Contains(_projectName)) { - continue; + if (_isMicroserviceServiceTemplate || _entries.Any(e=>e.Name.EndsWith(GetProjectNameWithExtensionFromProjectReference(oldNodeIncludeValue)))) + { + continue; + } } - XmlNode newNode = null; - - newNode = GetNewReferenceNode(doc, oldNodeIncludeValue); + XmlNode newNode = GetNewReferenceNode(doc, oldNodeIncludeValue); oldNode.ParentNode.ReplaceChild(newNode, oldNode); } @@ -145,8 +149,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { private readonly string _nugetPackageVersion; - public NugetReferenceReplacer(List entries, string projectName, string nugetPackageVersion) - : base(entries, projectName) + public NugetReferenceReplacer(ProjectBuildContext context, string projectName, string nugetPackageVersion) + : base(context, projectName) { _nugetPackageVersion = nugetPackageVersion; } @@ -183,8 +187,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private readonly string _gitHubAbpLocalRepositoryPath; private readonly string _gitHubVoloLocalRepositoryPath; - public LocalProjectPathReferenceReplacer(List entries, string projectName, string gitHubAbpLocalRepositoryPath, string gitHubVoloLocalRepositoryPath) - : base(entries, projectName) + public LocalProjectPathReferenceReplacer(ProjectBuildContext context, string projectName, string gitHubAbpLocalRepositoryPath, string gitHubVoloLocalRepositoryPath) + : base(context, projectName) { _gitHubAbpLocalRepositoryPath = gitHubAbpLocalRepositoryPath; _gitHubVoloLocalRepositoryPath = gitHubVoloLocalRepositoryPath; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 942dd91067..b8c1f24b46 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -85,11 +85,11 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private void SetSolutionAndProjectPathsIfNull(ProjectBuildContext context) { - if (_solutionFilePath == null) { _solutionFilePath = context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.sln")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name; + context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name ?? + context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.sln")?.Name; } if (_projectFolderPath == null) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs index ce2c8c3b2a..27199f6ce4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/SolutionRenameStep.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Volo.Abp.Cli.ProjectBuilding.Files; +using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { @@ -8,13 +9,26 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { public override void Execute(ProjectBuildContext context) { - new SolutionRenamer( - context.Files, - "MyCompanyName", - "MyProjectName", - context.BuildArgs.SolutionName.CompanyName, - context.BuildArgs.SolutionName.ProjectName - ).Run(); + if (MicroserviceServiceTemplateBase.IsMicroserviceServiceTemplate(context.BuildArgs.TemplateName)) + { + new SolutionRenamer( + context.Files, + "MyCompanyName.MyProjectName", + "MicroserviceName", + context.BuildArgs.SolutionName.CompanyName, + context.BuildArgs.SolutionName.ProjectName + ).Run(); + } + else + { + new SolutionRenamer( + context.Files, + "MyCompanyName", + "MyProjectName", + context.BuildArgs.SolutionName.CompanyName, + context.BuildArgs.SolutionName.ProjectName + ).Run(); + } } private class SolutionRenamer diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs index 8b7cfeb440..3e77f0844e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs @@ -33,7 +33,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building } if ((context.BuildArgs.UiFramework == UiFramework.Mvc || context.BuildArgs.UiFramework == UiFramework.Blazor) - && context.BuildArgs.MobileApp == MobileApp.None && context.Template.Name != MicroserviceProTemplate.TemplateName) + && context.BuildArgs.MobileApp == MobileApp.None && context.Template.Name != MicroserviceProTemplate.TemplateName + && context.Template.Name != MicroserviceServiceProTemplate.TemplateName) { pipeline.Steps.Add(new RemoveRootFolderStep()); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SolutionName.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SolutionName.cs index ba93774fbe..ba55f7aa4c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SolutionName.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SolutionName.cs @@ -17,6 +17,11 @@ namespace Volo.Abp.Cli.ProjectBuilding ProjectName = projectName; } + public static SolutionName Parse(string fullName, string microserviceName) + { + return new SolutionName(fullName + "." + microserviceName, fullName, microserviceName); + } + public static SolutionName Parse(string fullName) { if (fullName.Length < 1) @@ -47,4 +52,4 @@ namespace Volo.Abp.Cli.ProjectBuilding return new SolutionName(fullName, companyName, projectName); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs index 1a4bf3c05a..05e12e7922 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateInfoProvider.cs @@ -28,7 +28,7 @@ namespace Volo.Abp.Cli.ProjectBuilding public TemplateInfoProvider(ICancellationTokenProvider cancellationTokenProvider, IRemoteServiceExceptionHandler remoteServiceExceptionHandler, - AuthService authService, + AuthService authService, CliHttpClientFactory cliHttpClientFactory) { CancellationTokenProvider = cancellationTokenProvider; @@ -56,6 +56,8 @@ namespace Volo.Abp.Cli.ProjectBuilding return new AppProTemplate(); case MicroserviceProTemplate.TemplateName: return new MicroserviceProTemplate(); + case MicroserviceServiceProTemplate.TemplateName: + return new MicroserviceServiceProTemplate(); case ModuleTemplate.TemplateName: return new ModuleTemplate(); case ModuleProTemplate.TemplateName: diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceProTemplate.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceProTemplate.cs new file mode 100644 index 0000000000..7b7b104033 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceProTemplate.cs @@ -0,0 +1,16 @@ +namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice +{ + public class MicroserviceServiceProTemplate : MicroserviceServiceTemplateBase + { + /// + /// "microservice-service-pro". + /// + public const string TemplateName = "microservice-service-pro"; + + public MicroserviceServiceProTemplate() + : base(TemplateName) + { + DocumentUrl = null; // todo: set this + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs new file mode 100644 index 0000000000..de589336b0 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceServiceTemplateBase.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using JetBrains.Annotations; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectBuilding.Building.Steps; + +namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice +{ + public abstract class MicroserviceServiceTemplateBase : TemplateInfo + { + protected MicroserviceServiceTemplateBase([NotNull] string name) + : base(name) + { + } + + public static bool IsMicroserviceServiceTemplate(string templateName) + { + return templateName == MicroserviceServiceProTemplate.TemplateName; + } + + public static string CalculateTargetFolder(string mainSolutionFolder, string serviceName) + { + serviceName = serviceName.ToCamelCase().RemovePostFix("Service"); + + return Path.Combine(mainSolutionFolder, "microservices", serviceName); + } + + public override IEnumerable GetCustomSteps(ProjectBuildContext context) + { + var steps = new List(); + + DeleteUnrelatedUiProject(context, steps); + RandomizeStringEncryption(context, steps); + + return steps; + } + + private static void DeleteUnrelatedUiProject(ProjectBuildContext context, List steps) + { + switch (context.BuildArgs.UiFramework) + { + case UiFramework.Blazor: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Web")); + break; + case UiFramework.Mvc: + case UiFramework.NotSpecified: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Blazor")); + break; + default: + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Blazor")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Web")); + break; + } + } + + private static void RandomizeStringEncryption(ProjectBuildContext context, List steps) + { + steps.Add(new RandomizeStringEncryptionStep()); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs index 52ff3c9c91..0a56f5272a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Microservice/MicroserviceTemplateBase.cs @@ -33,27 +33,41 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice switch (context.BuildArgs.UiFramework) { case UiFramework.None: - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, + "/applications/web/src/MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, + "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveFolderStep("/applications/blazor")); steps.Add(new RemoveFolderStep("/angular")); break; case UiFramework.Angular: - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, + "/applications/web/src/MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveFolderStep("/applications/web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, + "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveFolderStep("/applications/blazor")); break; case UiFramework.Blazor: - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web",null, + "/applications/web/src/MyCompanyName.MyProjectName.Web")); + steps.Add(new RemoveFolderStep("/applications/web")); steps.Add(new RemoveFolderStep("/angular")); break; case UiFramework.Mvc: case UiFramework.NotSpecified: - steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor",null, + "/applications/blazor/src/MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveFolderStep("/applications/blazor")); steps.Add(new RemoveFolderStep("/angular")); break; } + + steps.Add(new RemoveFolderStep("/microservices/template")); } private static void RandomizeStringEncryption(ProjectBuildContext context, List steps)