From 7aa82af0bed10ce84aff5d664fc7d0b6db9aeb28 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 21 Jun 2022 17:49:22 +0800 Subject: [PATCH 1/5] Upgrade to Elsa 2.8.2 --- src/AbpHelper.Core/AbpHelper.Core.csproj | 2 +- src/AbpHelper.Core/AbpHelperCoreModule.cs | 7 +- .../Commands/CommandWithOption.cs | 59 ++-- .../Commands/Ef/Migrations/Add/AddCommand.cs | 24 +- .../Ef/Migrations/Add/AddCommandOption.cs | 2 +- .../Ef/Migrations/Remove/RemoveCommand.cs | 28 +- .../Migrations/Remove/RemoveCommandOption.cs | 2 +- .../Generate/Controller/ControllerCommand.cs | 113 ++++---- .../Commands/Generate/Crud/CrudCommand.cs | 92 +++--- .../Localization/LocalizationCommand.cs | 80 +++--- .../Generate/Methods/MethodsCommand.cs | 62 ++--- .../Generate/Service/ServiceCommand.cs | 41 +-- .../Commands/Module/Add/AddCommand.cs | 262 +++++++++++------- .../Commands/Module/Add/AddCommandOption.cs | 2 +- .../Commands/Module/ModuleCommand.cs | 3 +- .../Commands/Module/Remove/RemoveCommand.cs | 218 +++++++++------ .../Extensions/ServiceCollectionExtensions.cs | 22 +- src/AbpHelper.Core/Models/TypeInfo.cs | 6 +- .../Steps/Abp/BuildDtoInfoStep.cs | 85 ++++-- .../Steps/Abp/EntityParserStep.cs | 63 +++-- ...LocalizationJsonModificationCreatorStep.cs | 43 ++- .../CSharp/AppServiceClassStep.cs | 25 +- .../CSharp/AppServiceInterfaceStep.cs | 26 +- .../ApplicationAutoMapperProfileStep.cs | 69 ++++- .../CSharp/CSharpModificationCreatorStep.cs | 33 +-- .../CSharp/ControllerStep.cs | 71 +++-- .../CSharp/DbContextClassStep.cs | 48 +++- .../CSharp/DbContextInterfaceStep.cs | 53 +++- .../DbContextModelCreatingExtensionsStep.cs | 54 +++- .../CSharp/DependsOnStep.cs | 88 ++++-- .../CSharp/EntityConstructorsStep.cs | 23 +- .../CSharp/EntityFrameworkCoreModuleStep.cs | 47 +++- .../CSharp/MenuContributorStep.cs | 62 ++++- .../CSharp/MenuNameStep.cs | 21 +- .../CSharp/MigrationsContextStep.cs | 81 ++++-- .../PermissionDefinitionProviderStep.cs | 54 +++- .../CSharp/PermissionsStep.cs | 20 +- .../CSharp/WebAutoMapperProfileStep.cs | 27 +- .../CodeGenerationStepBase.cs | 27 ++ .../CodeModificationStepBase.cs | 24 ++ .../Typescript/AppRoutingModuleStep.cs | 39 ++- .../Typescript/ModuleStep.cs | 39 ++- .../Typescript/RoutingModuleStep.cs | 21 +- .../TypeScriptModificationCreatorStep.cs | 34 +-- .../Steps/Abp/ParseStep/BaseParserStep.cs | 70 +++-- .../Steps/Abp/ParseStep/ClassParserStep.cs | 17 +- .../Abp/ParseStep/InterfaceParserStep.cs | 20 +- .../Steps/Abp/ProjectInfoProviderStep.cs | 63 +++-- .../Steps/Abp/SetModelVariableStep.cs | 33 ++- .../Steps/Common/DirectoryFinderStep.cs | 52 ++-- src/AbpHelper.Core/Steps/Common/EmptyStep.cs | 11 +- .../Steps/Common/FileFinderStep.cs | 77 +++-- .../Steps/Common/FileGenerationStep.cs | 40 ++- .../Steps/Common/FileModifierStep.cs | 84 ++++-- .../Steps/Common/GroupGenerationStep.cs | 76 +++-- .../Steps/Common/MultiFilesFinderStep.cs | 49 ++-- .../Steps/Common/RunCommandStep.cs | 75 ++--- .../Steps/Common/TextGenerationStep.cs | 64 +++-- src/AbpHelper.Core/Steps/StepWithOption.cs | 53 ++-- .../{{EntityInfo.Name}}/Index.cshtml | 3 + .../Common/ConfigureFindDbContextWorkflow.cs | 61 ++-- .../ConfigureHasDbMigrationsWorkflow.cs | 45 ++- .../ConfigureMigrationProjectsWorkflow.cs | 207 ++++++++------ .../CustomRepositoryGenerationWorkflow.cs | 22 +- .../Crud/EFCoreConfigurationWorkflow.cs | 72 +++-- .../EntityConstructorsGenerationWorkflow.cs | 2 +- .../Crud/EntityUsingGenerationWorkflow.cs | 11 +- .../Crud/LocalizationGenerationWorkflow.cs | 41 ++- .../MigrationAndUpdateDatabaseWorkflow.cs | 33 ++- .../Crud/ServiceGenerationWorkflow.cs | 61 ++-- .../Generate/Crud/TestGenerationWorkflow.cs | 7 +- .../Crud/UiAngularGenerationWorkflow.cs | 99 ++++--- .../Crud/UiRazorPagesGenerationWorkflow.cs | 102 +++++-- .../Workflow/Generate/OverwriteWorkflow.cs | 18 +- .../Steps/EntityParserStep_Tests.cs | 6 +- .../Steps/EntityParserStep_Tests2.cs | 6 +- .../Steps/FileModifierStep_Tests.cs | 24 +- test/AbpHelper.Tests/Steps/StepTestsBase.cs | 9 +- 78 files changed, 2464 insertions(+), 1351 deletions(-) create mode 100644 src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeGenerationStepBase.cs create mode 100644 src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeModificationStepBase.cs diff --git a/src/AbpHelper.Core/AbpHelper.Core.csproj b/src/AbpHelper.Core/AbpHelper.Core.csproj index 47d73ed8..2c316755 100644 --- a/src/AbpHelper.Core/AbpHelper.Core.csproj +++ b/src/AbpHelper.Core/AbpHelper.Core.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/AbpHelper.Core/AbpHelperCoreModule.cs b/src/AbpHelper.Core/AbpHelperCoreModule.cs index b6fe6d41..5760536b 100644 --- a/src/AbpHelper.Core/AbpHelperCoreModule.cs +++ b/src/AbpHelper.Core/AbpHelperCoreModule.cs @@ -31,9 +31,10 @@ private void ConfigureVirtualFileSystem() private void ConfigureElsaActivities(ServiceConfigurationContext context) { context.Services - .AddElsa() - .AddAllActivities() - ; + .AddElsa(x => + { + x.AddAbpHelperActivities(); + }); } private void ConfigureTemplateFiles(ServiceConfigurationContext context) diff --git a/src/AbpHelper.Core/Commands/CommandWithOption.cs b/src/AbpHelper.Core/Commands/CommandWithOption.cs index 50730b63..03ff3193 100644 --- a/src/AbpHelper.Core/Commands/CommandWithOption.cs +++ b/src/AbpHelper.Core/Commands/CommandWithOption.cs @@ -6,14 +6,13 @@ using System.Reflection; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Attributes; -using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Services; using EasyAbp.AbpHelper.Core.Steps.Abp; -using Elsa.Activities; -using Elsa.Expressions; +using Elsa.Activities.Primitives; +using Elsa.Builders; using Elsa.Models; -using Elsa.Scripting.JavaScript; using Elsa.Services; +using Elsa.Services.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -22,7 +21,8 @@ namespace EasyAbp.AbpHelper.Core.Commands { public abstract class CommandWithOption : CommandBase where TOption : CommandOptionsBase { - public CommandWithOption(IServiceProvider serviceProvider, string name, string? description = null) : base(serviceProvider, name, description) + public CommandWithOption(IServiceProvider serviceProvider, string name, string? description = null) : base( + serviceProvider, name, description) { Logger = NullLogger>.Instance; @@ -34,6 +34,7 @@ public CommandWithOption(IServiceProvider serviceProvider, string name, string? protected virtual string OptionVariableName => CommandConsts.OptionVariableName; protected virtual string BaseDirectoryVariableName => CommandConsts.BaseDirectoryVariableName; protected virtual string ExcludeDirectoriesVariableName => CommandConsts.ExcludeDirectoriesVariableName; + protected virtual string OverwriteVariableName => CommandConsts.OverwriteVariableName; public ILogger> Logger { get; set; } @@ -46,25 +47,25 @@ public virtual async Task RunCommand(TOption option) await RunWorkflow(builder => { var activityBuilder = builder - .StartWith( - step => - { - step.VariableName = OptionVariableName; - step.ValueExpression = new JavaScriptExpression($"({option.ToJson()})"); - }) - .Then( - step => - { - step.VariableName = BaseDirectoryVariableName; - step.ValueExpression = new LiteralExpression(option.Directory); - }) - .Then( - step => - { - step.VariableName = ExcludeDirectoriesVariableName; - step.ValueExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CommandOptionsBase.Exclude)}"); - }) - .Then() + .StartWith( + step => + { + step.Set(x => x.VariableName, OptionVariableName); + step.Set(x => x.Value, option); + }) + .Then( + step => + { + step.Set(x => x.VariableName, BaseDirectoryVariableName); + step.Set(x => x.Value, option.Directory); + }) + .Then( + step => + { + step.Set(x => x.VariableName, ExcludeDirectoriesVariableName); + step.Set(x => x.Value, option.Exclude); + }) + .Then() ; return ConfigureBuild(option, activityBuilder).Build(); @@ -93,7 +94,7 @@ protected virtual string GetBaseDirectory(string directory) return directory; } - protected async Task RunWorkflow(Func builder) + protected async Task RunWorkflow(Func builder) { var workflowBuilderFactory = ServiceProvider.GetRequiredService>(); var workflowBuilder = workflowBuilderFactory(); @@ -101,15 +102,15 @@ protected async Task RunWorkflow(Func(); - var ctx = await invoker.StartAsync(workflowDefinition); - if (ctx.Workflow.Status == WorkflowStatus.Finished) + var invoker = ServiceProvider.GetRequiredService(); + var ctx = await invoker.StartWorkflowAsync(workflowDefinition); + if (ctx.WorkflowInstance?.WorkflowStatus == WorkflowStatus.Finished) { Logger.LogInformation($"Command '{Name}' finished successfully."); } else { - Logger.LogError("Error activity: " + ctx.CurrentActivity.State); + Logger.LogError("Error activity: " + ctx.ActivityId); } } diff --git a/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommand.cs b/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommand.cs index beea9b19..413450cc 100644 --- a/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommand.cs +++ b/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommand.cs @@ -2,16 +2,16 @@ using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Common; -using Elsa.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Commands.Ef.Migrations.Add { public class AddCommand : CommandWithOption { - private const string AddCommandDescription = @"Adds a new migration. The usage is the same as `dotnet ef migrations add`, + private const string AddCommandDescription = + @"Adds a new migration. The usage is the same as `dotnet ef migrations add`, except providing the default value for the `--project` and `--startup-project` options."; public AddCommand(IServiceProvider serviceProvider) : base(serviceProvider, "add", AddCommandDescription) @@ -20,18 +20,20 @@ public AddCommand(IServiceProvider serviceProvider) : base(serviceProvider, "add protected override IActivityBuilder ConfigureBuild(AddCommandOption option, IActivityBuilder activityBuilder) { - string efOptions = option.EfOptions == null ? String.Empty : string.Join(" ", option.EfOptions); + var efOptions = option.EfOptions == null ? string.Empty : string.Join(" ", option.EfOptions); return base.ConfigureBuild(option, activityBuilder) .Then(step => { - step.VariableName = "EfOptions"; - step.ValueExpression = new LiteralExpression(efOptions); - + step.Set(x => x.VariableName, "EfOptions"); + step.Set(x => x.Value, efOptions); }) .AddConfigureMigrationProjectsWorkflow(ActivityNames.AddMigration) .Then( - step => step.Command = new JavaScriptExpression("`dotnet ef migrations add ${Option.Name} -p \"${MigrationProjectFile}\" -s \"${StartupProjectFile}\" ${EfOptions || ''}`") - ).WithName(ActivityNames.AddMigration) + step => + { + step.Set(x => x.Command, + "dotnet ef migrations add {Option.Name} -p \"{MigrationProjectFile}\" -s \"{StartupProjectFile}\" {EfOptions || ''}"); + }).WithName(ActivityNames.AddMigration) ; } } diff --git a/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommandOption.cs b/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommandOption.cs index 40622544..9958344a 100644 --- a/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommandOption.cs +++ b/src/AbpHelper.Core/Commands/Ef/Migrations/Add/AddCommandOption.cs @@ -8,6 +8,6 @@ public class AddCommandOption : MigrationsCommandOption public string Name { get; set; } = null!; [Argument("ef-options", Description = "Other options to `dotnet ef migrations add`")] - public string[] EfOptions { get; set; } = null!; + public string[]? EfOptions { get; set; } = null; } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommand.cs b/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommand.cs index 31b002df..5118a294 100644 --- a/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommand.cs +++ b/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommand.cs @@ -2,36 +2,40 @@ using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Common; -using Elsa.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; +using Elsa.Activities.Primitives; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Ef.Migrations.Remove { public class RemoveCommand : CommandWithOption { - private const string RemoveCommandDescription = @"Removes the last migration. The usage is the same as `dotnet ef migrations remove`, + private const string RemoveCommandDescription = + @"Removes the last migration. The usage is the same as `dotnet ef migrations remove`, except providing the default value for the `--project` and `--startup-project` options."; - public RemoveCommand(IServiceProvider serviceProvider) : base(serviceProvider, "remove", RemoveCommandDescription) + public RemoveCommand(IServiceProvider serviceProvider) : base(serviceProvider, "remove", + RemoveCommandDescription) { } protected override IActivityBuilder ConfigureBuild(RemoveCommandOption option, IActivityBuilder activityBuilder) { - string efOptions = option.EfOptions == null ? String.Empty : string.Join(" ", option.EfOptions); + var efOptions = option.EfOptions == null ? string.Empty : string.Join(" ", option.EfOptions); return base.ConfigureBuild(option, activityBuilder) .Then(step => { - step.VariableName = "EfOptions"; - step.ValueExpression = new LiteralExpression(efOptions); - + step.Set(x => x.VariableName, "EfOptions"); + step.Set(x => x.Value, efOptions); }) .AddConfigureMigrationProjectsWorkflow(ActivityNames.RemoveMigration) .Then( - step => step.Command = new JavaScriptExpression("`dotnet ef migrations remove -p \"${MigrationProjectFile}\" -s \"${StartupProjectFile}\" ${EfOptions || ''}`") - ).WithName(ActivityNames.RemoveMigration) + step => + { + step.Set(x => x.Command, + "dotnet ef migrations remove -p \"{MigrationProjectFile}\" -s \"{StartupProjectFile}\" {EfOptions || ''}"); + }).WithName(ActivityNames.RemoveMigration) ; } } diff --git a/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommandOption.cs b/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommandOption.cs index 7708168e..7164ba84 100644 --- a/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommandOption.cs +++ b/src/AbpHelper.Core/Commands/Ef/Migrations/Remove/RemoveCommandOption.cs @@ -5,6 +5,6 @@ namespace EasyAbp.AbpHelper.Core.Commands.Ef.Migrations.Remove public class RemoveCommandOption : MigrationsCommandOption { [Argument("ef-options", Description = "Other options to `dotnet ef migrations remove`")] - public string[] EfOptions { get; set; } = null!; + public string[]? EfOptions { get; set; } = null; } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Commands/Generate/Controller/ControllerCommand.cs b/src/AbpHelper.Core/Commands/Generate/Controller/ControllerCommand.cs index 4a48b43d..a9807c8f 100644 --- a/src/AbpHelper.Core/Commands/Generate/Controller/ControllerCommand.cs +++ b/src/AbpHelper.Core/Commands/Generate/Controller/ControllerCommand.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Abp.ParseStep; @@ -7,94 +8,104 @@ using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Generate; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Generate.Controller { public class ControllerCommand : CommandWithOption { - public ControllerCommand(IServiceProvider serviceProvider) - : base(serviceProvider, "controller", "Generate controller class and methods according to the specified service") + public ControllerCommand(IServiceProvider serviceProvider) + : base(serviceProvider, "controller", + "Generate controller class and methods according to the specified service") { } - protected override IActivityBuilder ConfigureBuild(ControllerCommandOption option, IActivityBuilder activityBuilder) + protected override IActivityBuilder ConfigureBuild(ControllerCommandOption option, + IActivityBuilder activityBuilder) { string cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; return base.ConfigureBuild(option, activityBuilder) - .AddOverwriteWorkflow() - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Controller"); - }) - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(ControllerCommandOption.SkipBuild)}"), + .AddOverwriteWorkflow(option) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Controller"); + }) + .Then( + step => { step.Set(x => x.Condition, option.SkipBuild); }, ifElse => { ifElse.When(OutcomeNames.False) .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{AspNetCoreDir}}/src/${{ProjectInfo.FullName}}.Application && dotnet build`" - )) - .Then(ActivityNames.SearchServiceInterface) + step => + { + step.Set(x => x.Command, x => + { + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir); + var projectInfo = x.GetVariable("ProjectInfo")!; + return + $"cd{cdOption} {aspNetCoreDir}/src/{projectInfo.FullName}.Application && dotnet build"; + }); + }) + .ThenNamed(ActivityNames.SearchServiceInterface) ; ifElse.When(OutcomeNames.True) - .Then(ActivityNames.SearchServiceInterface) + .ThenNamed(ActivityNames.SearchServiceInterface) ; }) - .Then( - step => { step.SearchFileName = new JavaScriptExpression($"`I${{{OptionVariableName}.{nameof(ControllerCommandOption.Name)}}}AppService.cs`"); } + .Then(step => { step.Set(x => x.SearchFileName, $"I{option.Name}AppService.cs"); } ).WithName(ActivityNames.SearchServiceInterface) .Then() - .Then( - step => { step.SearchFileName = new JavaScriptExpression($"`${{{OptionVariableName}.{nameof(ControllerCommandOption.Name)}}}AppService.cs`"); } + .Then(step => { step.Set(x => x.SearchFileName, $"{option.Name}AppService.cs"); } ) .Then() .Then() - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(ControllerCommandOption.NoOverwrite)}"), + .Then( + step => { step.Set(x => x.Condition, option.NoOverwrite); }, ifElse => { ifElse.When(OutcomeNames.True) // Regenerate/Overwrite - .Then( - step => - { - step.GroupName = "Controller"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); - }) + .Then(step => + { + step.Set(x => x.GroupName, "Controller"); + step.Set(x => x.TargetDirectory, + x => x.GetVariable(VariableNames.AspNetCoreDir)); + }) ; ifElse.When(OutcomeNames.False) - .Then( - step => - { - step.SearchFileName = new JavaScriptExpression($"`${{{OptionVariableName}.{nameof(ControllerCommandOption.Name)}}}Controller.cs`"); - step.ErrorIfNotFound = new JavaScriptExpression("false"); - } - ).WithName(ActivityNames.SearchController) - .Then( - step => step.ConditionExpression = new JavaScriptExpression("FileFinderResult != null"), + .Then(step => + { + step.Set(x => x.SearchFileName, $"{option.Name}Controller.cs"); + step.Set(x => x.ErrorIfNotFound, false); + }).WithName(ActivityNames.SearchController) + .Then( + step => { step.Set(x => x.Condition, x => !x.GetInput().IsNullOrWhiteSpace()); }, found => { found.When(OutcomeNames.False) - .Then( - step => - { - step.GroupName = "Controller"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); - }) + .Then(step => + { + step.Set(x => x.GroupName, "Controller"); + step.Set(x => x.TargetDirectory, + x => x.GetVariable(VariableNames.AspNetCoreDir)); + }) ; found.When(OutcomeNames.True) .Then(step => { - step.OutputVariableName = new LiteralExpression("ControllerInfo"); + step.Set(x => x.OutputVariableName, "ControllerInfo"); + }) + .Then(step => + { + step.Set(x => x.InterfaceInfo, + x => x.GetVariable("InterfaceInfo")); + step.Set(x => x.ClassInfo, x => x.GetVariable("ClassInfo")); + step.Set(x => x.ControllerInfo, + x => x.GetVariable("ControllerInfo")); }) - .Then() .Then() ; } diff --git a/src/AbpHelper.Core/Commands/Generate/Crud/CrudCommand.cs b/src/AbpHelper.Core/Commands/Generate/Crud/CrudCommand.cs index 68025ec8..521e0f46 100644 --- a/src/AbpHelper.Core/Commands/Generate/Crud/CrudCommand.cs +++ b/src/AbpHelper.Core/Commands/Generate/Crud/CrudCommand.cs @@ -7,11 +7,10 @@ using EasyAbp.AbpHelper.Core.Workflow.Generate; using EasyAbp.AbpHelper.Core.Workflow.Generate.Crud; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; +using Elsa.Activities.Primitives; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Generate.Crud { @@ -30,111 +29,120 @@ protected override IActivityBuilder ConfigureBuild(CrudCommandOption option, IAc var entityFileName = option.Entity + ".cs"; return base.ConfigureBuild(option, activityBuilder) - .AddOverwriteWorkflow() - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Crud"); - }) + .AddOverwriteWorkflow(option) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Crud"); + }) .Then( - step => { step.SearchFileName = new LiteralExpression(entityFileName); }) + step => { step.Set(x => x.SearchFileName, entityFileName); }) .Then() - .Then() + .Then(step => + { + step.Set(x => x.EntityInfo, x => x.GetVariable("EntityInfo")); + step.Set(x => x.DtoSuffix, option.DtoSuffix); + step.Set(x => x.SeparateDto, option.SeparateDto); + step.Set(x => x.EntityPrefixDto, option.EntityPrefixDto); + }) .Then() - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipEntityConstructors)}"), + .Then( + step => { step.Set(x => x.Condition, option.SkipEntityConstructors); }, ifElse => { ifElse.When(OutcomeNames.False) .AddEntityConstructorsGenerationWorkflow() - .Then("EntityUsing") + .ThenNamed("EntityUsing") ; ifElse.When(OutcomeNames.True) - .Then("EntityUsing") + .ThenNamed("EntityUsing") ; }) .AddEntityUsingGenerationWorkflow("EntityUsing") .AddEfCoreConfigurationWorkflow() - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipCustomRepository)}"), + .Then( + step => { step.Set(x => x.Condition, option.SkipCustomRepository); }, ifElse => { ifElse .When(OutcomeNames.False) .AddCustomRepositoryGeneration() - .Then("ServiceGeneration") + .ThenNamed("ServiceGeneration") ; ifElse .When(OutcomeNames.True) - .Then("ServiceGeneration") + .ThenNamed("ServiceGeneration") ; } ) - .AddServiceGenerationWorkflow("ServiceGeneration") - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipLocalization)}"), + .AddServiceGenerationWorkflow("ServiceGeneration", option) + .Then( + step => { step.Set(x => x.Condition, option.SkipLocalization); }, ifElse => { ifElse.When(OutcomeNames.False) .AddLocalizationGenerationWorkflow() - .Then(ActivityNames.Ui) + .ThenNamed(ActivityNames.Ui) ; ifElse.When(OutcomeNames.True) - .Then(ActivityNames.Ui) + .ThenNamed(ActivityNames.Ui) ; }) - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipUi)}"), + .Then( + step => { step.Set(x => x.Condition, option.SkipUi); }, ifElse => { ifElse .When(OutcomeNames.False) .Then( - @switch => + step => { - @switch.Expression = new JavaScriptExpression("(ProjectInfo.UiFramework)"); - @switch.Cases = Enum.GetValues(typeof(UiFramework)).Cast().Select(u => u.ToString()).ToArray(); + step.WithCases(context => + { + var projectInfo = context.GetVariable("ProjectInfo")!; + return Enum.GetValues().Select(u => + new SwitchCase(u.ToString(), projectInfo.UiFramework == u)).ToList(); + }); }, @switch => { @switch.When(UiFramework.None.ToString("D")) - .Then(TestGeneration); + .ThenNamed(TestGeneration); @switch.When(UiFramework.RazorPages.ToString("D")) .AddUiRazorPagesGenerationWorkflow() - .Then(TestGeneration); + .ThenNamed(TestGeneration); @switch.When(UiFramework.Angular.ToString("D")) // TODO //.AddUiAngularGenerationWorkflow() - .Then(TestGeneration); + .ThenNamed(TestGeneration); } ) ; ifElse .When(OutcomeNames.True) - .Then(TestGeneration) + .ThenNamed(TestGeneration) ; } ).WithName(ActivityNames.Ui) - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipTest)}"), + .Then( + step => { step.Set(x => x.Condition, option.SkipTest); }, ifElse => { ifElse .When(OutcomeNames.False) .AddTestGenerationWorkflow() - .Then(DbMigrations) + .ThenNamed(DbMigrations) ; ifElse .When(OutcomeNames.True) - .Then(DbMigrations) + .ThenNamed(DbMigrations) ; } ).WithName(TestGeneration) - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{OptionVariableName}.{nameof(CrudCommandOption.SkipDbMigrations)}"), + .Then( + step => { step.Set(x => x.Condition, option.SkipDbMigrations); }, ifElse => { ifElse diff --git a/src/AbpHelper.Core/Commands/Generate/Localization/LocalizationCommand.cs b/src/AbpHelper.Core/Commands/Generate/Localization/LocalizationCommand.cs index 8f922dd8..05ae35b1 100644 --- a/src/AbpHelper.Core/Commands/Generate/Localization/LocalizationCommand.cs +++ b/src/AbpHelper.Core/Commands/Generate/Localization/LocalizationCommand.cs @@ -1,15 +1,16 @@ using System; using System.Collections.Generic; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Generate; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Fluid.Ast; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Generate.Localization { @@ -20,47 +21,52 @@ public LocalizationCommand(IServiceProvider serviceProvider) { } - protected override IActivityBuilder ConfigureBuild(LocalizationCommandOption option, IActivityBuilder activityBuilder) + protected override IActivityBuilder ConfigureBuild(LocalizationCommandOption option, + IActivityBuilder activityBuilder) { return base.ConfigureBuild(option, activityBuilder) - .AddOverwriteWorkflow() - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Localization"); - }) + .AddOverwriteWorkflow(option) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Localization"); + }) .Then() /* Add localization */ - .Then( - step => { step.TemplateName = "Localization"; } - ) - .Then( - step => + .Then(step => { step.Set(x => x.TemplateName, "Localization"); }) + .Then(step => + { + step.Set(x => x.SearchDirectoryName, "Localization"); + step.Set(x => x.BaseDirectory, x => { - step.SearchDirectoryName = "Localization"; - step.BaseDirectory = new JavaScriptExpression(@"`${AspNetCoreDir}/src/${ProjectInfo.FullName}.Domain.Shared`"); - } - ) - .Then( + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir); + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{aspNetCoreDir}/src/{projectInfo.FullName}.Domain.Shared"; + }); + step.Set(x => x.ExcludeDirectories, x => x.GetVariable(ExcludeDirectoriesVariableName)); + }) + .Then(step => + { + step.Set(x => x.SearchFileName, "*.json"); + step.Set(x => x.BaseDirectory, + x => x.GetVariable(DirectoryFinderStep.DefaultDirectoryParameterName)); + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); + }) + .Then( step => { - step.SearchFileName = new LiteralExpression("*.json"); - step.BaseDirectory = new JavaScriptExpression(DirectoryFinderStep.DefaultDirectoryParameterName); - } - ) - .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(MultiFileFinderStep.DefaultFileParameterName); }, + step.Set(x => x.Items, + x => x.GetVariable>(MultiFileFinderStep.DefaultFileParameterName)); + }, branch => branch.When(OutcomeNames.Iterate) - .Then( - step => - { - step.TargetFile = new JavaScriptExpression("CurrentValue"); - step.LocalizationJson = new JavaScriptExpression(TextGenerationStep.DefaultGeneratedTextParameterName); - } - ) - .Then(branch) + .Then(step => + { + step.Set(x => x.TargetFile, x => x.GetInput()); + step.Set(x => x.LocalizationJson, + x => x.GetVariable(TextGenerationStep.DefaultGeneratedTextParameterName)); + }) ); } } diff --git a/src/AbpHelper.Core/Commands/Generate/Methods/MethodsCommand.cs b/src/AbpHelper.Core/Commands/Generate/Methods/MethodsCommand.cs index 06b3a28b..c1b41afa 100644 --- a/src/AbpHelper.Core/Commands/Generate/Methods/MethodsCommand.cs +++ b/src/AbpHelper.Core/Commands/Generate/Methods/MethodsCommand.cs @@ -8,11 +8,10 @@ using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Generate; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Generate.Methods { @@ -38,48 +37,45 @@ protected override IActivityBuilder ConfigureBuild(MethodsCommandOption option, IActivityBuilder activityBuilder) { return base.ConfigureBuild(option, activityBuilder) - .AddOverwriteWorkflow() - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Methods"); - }) - .Then( - step => - { - step.SearchFileName = new JavaScriptExpression($"`I${{{OptionVariableName}.{nameof(MethodsCommandOption.ServiceName)}}}AppService.cs`"); - }) + .AddOverwriteWorkflow(option) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Methods"); + }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => $"I{option.ServiceName}AppService.cs"); + }) .Then() .Then() .Then() .Then() .Then( - x => { x.CollectionExpression = new JavaScriptExpression>($"{OptionVariableName}.{nameof(MethodsCommandOption.MethodNames)}"); }, + step => + { + step.Set(x => x.Items, option.MethodNames); + }, branch => branch.When(OutcomeNames.Iterate) - .Then( - step => - { - step.VariableName = "Bag.Name"; - step.ValueExpression = new JavaScriptExpression("CurrentValue"); - } - ) + .Then(step => + { + step.Set(x => x.VariableName, "Bag.Name"); + step.Set(x => x.Value, x => x.GetInput()); + }) .Then() .Then( step => { - step.GroupName = "Service"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); + step.Set(x => x.GroupName, x => "Service"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); } ) - .Then(branch) ) - .Then( - step => - { - step.SearchFileName = new JavaScriptExpression($"`${{{OptionVariableName}.{nameof(MethodsCommandOption.ServiceName)}}}AppService.cs`"); - }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => $"{option.ServiceName}AppService.cs"); + }) .Then() .Then(); } diff --git a/src/AbpHelper.Core/Commands/Generate/Service/ServiceCommand.cs b/src/AbpHelper.Core/Commands/Generate/Service/ServiceCommand.cs index 4b1da57b..3e0d84a1 100644 --- a/src/AbpHelper.Core/Commands/Generate/Service/ServiceCommand.cs +++ b/src/AbpHelper.Core/Commands/Generate/Service/ServiceCommand.cs @@ -5,18 +5,19 @@ using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Generate; -using Elsa.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; using Humanizer; + namespace EasyAbp.AbpHelper.Core.Commands.Generate.Service { public class ServiceCommand : CommandWithOption { - public ServiceCommand(IServiceProvider serviceProvider) - : base(serviceProvider, "service", "Generate service interface and class files according to the specified name") + public ServiceCommand(IServiceProvider serviceProvider) + : base(serviceProvider, "service", + "Generate service interface and class files according to the specified name") { } @@ -26,27 +27,27 @@ public override Task RunCommand(ServiceCommandOption option) { option.Folder = option.Name.Pluralize(); } + option.Folder = option.Folder.NormalizePath(); return base.RunCommand(option); } - protected override IActivityBuilder ConfigureBuild(ServiceCommandOption option, IActivityBuilder activityBuilder) + protected override IActivityBuilder ConfigureBuild(ServiceCommandOption option, + IActivityBuilder activityBuilder) { return base.ConfigureBuild(option, activityBuilder) - .AddOverwriteWorkflow() - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Service"); - }) + .AddOverwriteWorkflow(option) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Service"); + }) .Then() - .Then( - step => - { - step.GroupName = "Service"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); - }); + .Then(step => + { + step.Set(x => x.GroupName, "Service"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); + }); } } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Commands/Module/Add/AddCommand.cs b/src/AbpHelper.Core/Commands/Module/Add/AddCommand.cs index a18d09e8..baa72191 100644 --- a/src/AbpHelper.Core/Commands/Module/Add/AddCommand.cs +++ b/src/AbpHelper.Core/Commands/Module/Add/AddCommand.cs @@ -3,18 +3,18 @@ using System.CommandLine; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Common; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; -using JetBrains.Annotations; +using Elsa.Builders; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Module.Add { @@ -22,18 +22,19 @@ public class AddCommand : CommandWithOption { private readonly IDictionary _packageProjectMap = new Dictionary { - {ModuleConsts.Shared, "Domain.Shared"}, - {ModuleConsts.Domain, "Domain"}, - {ModuleConsts.EntityFrameworkCore, "EntityFrameworkCore"}, - {ModuleConsts.MongoDB, "MongoDB"}, - {ModuleConsts.Contracts, "Application.Contracts"}, - {ModuleConsts.Application, "Application"}, - {ModuleConsts.HttpApi, "HttpApi"}, - {ModuleConsts.Client, "HttpApi.Client"}, - {ModuleConsts.Web, "Web"}, + { ModuleConsts.Shared, "Domain.Shared" }, + { ModuleConsts.Domain, "Domain" }, + { ModuleConsts.EntityFrameworkCore, "EntityFrameworkCore" }, + { ModuleConsts.MongoDB, "MongoDB" }, + { ModuleConsts.Contracts, "Application.Contracts" }, + { ModuleConsts.Application, "Application" }, + { ModuleConsts.HttpApi, "HttpApi" }, + { ModuleConsts.Client, "HttpApi.Client" }, + { ModuleConsts.Web, "Web" }, }; - public AddCommand([NotNull] IServiceProvider serviceProvider) : base(serviceProvider, "add", "Add ABP module according to the specified packages") + public AddCommand(IServiceProvider serviceProvider) : base(serviceProvider, "add", + "Add ABP module according to the specified packages") { AddValidator(result => { @@ -49,127 +50,185 @@ public AddCommand([NotNull] IServiceProvider serviceProvider) : base(serviceProv protected override IActivityBuilder ConfigureBuild(AddCommandOption option, IActivityBuilder activityBuilder) { var moduleIdToCustomsMapping = typeof(ModuleCommandOption).GetProperties() - .Where(prop => prop.PropertyType == typeof(bool) && (bool) prop.GetValue(option)!) + .Where(prop => prop.PropertyType == typeof(bool) && (bool)prop.GetValue(option)!) .Select(prop => _packageProjectMap[prop.Name.ToKebabCase()]) - .ToDictionary(x => x, x => new List(new[] {$"{x}:{x}"})); - + .ToDictionary(x => x, x => new List(new[] { $"{x}:{x}" })); + if (!option.Custom.IsNullOrEmpty()) { foreach (var customPart in option.Custom.Split(',')) { var moduleId = customPart.Substring(0, customPart.IndexOf(':')); - + if (!moduleIdToCustomsMapping.ContainsKey(moduleId)) { moduleIdToCustomsMapping.Add(moduleId, new List()); } - + moduleIdToCustomsMapping[moduleId].Add(customPart); } } - string cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; + var cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; return base.ConfigureBuild(option, activityBuilder) - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Module"); - }) - .Then( - step => - { - step.VariableName = VariableNames.ProjectNames; - step.ValueExpression = new JavaScriptExpression( - $"[{string.Join(",", moduleIdToCustomsMapping.SelectMany(x => x.Value).Select(x => $"\"{x}\"").JoinAsString(","))}]"); - } - ) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Module"); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.ProjectNames); + step.Set(x => x.Value, moduleIdToCustomsMapping.ToDictionary(x => x.Value)); + }) .Then() .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(VariableNames.ProjectNames); }, + step => + { + step.Set(x => x.Items, x => x.GetVariable>(VariableNames.ProjectNames)); + }, branch => branch.When(OutcomeNames.Iterate) - .Then( - step => - { - step.VariableName = VariableNames.CurrentModuleName; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':')[0]"); - } - ) - .Then( - step => - { - step.VariableName = VariableNames.TargetAppProjectName; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':')[1]"); - } - ) - .Then( - step => + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.CurrentModuleName); + step.Set(x => x.Value, x => x.GetInput()!.Split(':')[0]); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.CurrentModuleName); + step.Set(x => x.Value, + x => x.GetInput()!.Split(':')[1]); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.SubmoduleUsingTextPostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.SubmoduleUsingTextPostfix; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':').length > 2 ? '.' + CurrentValue.split(':')[2] : ''"); - } - ) - .Then( - step => + var s = x.GetInput()!.Split(':'); + return s.Length > 2 ? $".{s[2]}" : ""; + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.PackageName); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.PackageName; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.CurrentModuleName} != '' ? {CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleName)} + '.' + {VariableNames.CurrentModuleName} : {CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleName)}"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return currentModuleName.IsNullOrWhiteSpace() + ? option.ModuleName + : $"{option.ModuleName}.{currentModuleName}"; + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.ModuleClassNamePostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.ModuleClassNamePostfix; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.CurrentModuleName}.replace(/\\./g, '')"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return Regex.Replace(currentModuleName, "/\\./g", ""); + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.AppProjectClassNamePostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.AppProjectClassNamePostfix; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.TargetAppProjectName}.replace(/\\./g, '')"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return Regex.Replace(currentModuleName, "/\\./g", ""); + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.DependsOnModuleClassName); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.DependsOnModuleClassName; - step.ValueExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleGroupNameWithoutCompanyName)} + {VariableNames.ModuleClassNamePostfix} + 'Module'"); - } - ) - .Then( - step => step.ConditionExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(AddCommandOption.Version)} != null"), + var moduleClassNamePostfix = + x.GetVariable(VariableNames.ModuleClassNamePostfix); + return + $"{option.ModuleGroupNameWithoutCompanyName}{moduleClassNamePostfix}Module"; + }); + }) + .Then( + step => step.Set(x => x.Condition, !option.Version.IsNullOrWhiteSpace()), ifElse => { ifElse .When(OutcomeNames.True) // with version specified - .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{AspNetCoreDir}}/src/${{ProjectInfo.FullName}}.${{TargetAppProjectName}} && dotnet add package ${{PackageName}} -v ${{Option.Version}}`" - )) - .Then(ActivityNames.AddDependsOn) + .Then(step => + { + step.Set(x => x.Command, x => + { + var aspNetCoreDir = + x.GetVariable(VariableNames.AspNetCoreDir)!; + var targetAppProjectName = + x.GetVariable(VariableNames.TargetAppProjectName)!; + var packageName = + x.GetVariable(VariableNames.PackageName)!; + var projectInfo = x.GetVariable("ProjectInfo")!; + + return + @$"cd{cdOption} {aspNetCoreDir}/src/{projectInfo.FullName}.{targetAppProjectName} && dotnet add package {packageName} -v {option.Version}"; + }); + }) + .ThenNamed(ActivityNames.AddDependsOn) ; ifElse .When(OutcomeNames.False) // no version - .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{AspNetCoreDir}}/src/${{ProjectInfo.FullName}}.${{TargetAppProjectName}} && dotnet add package ${{PackageName}}`" - )) - .Then(ActivityNames.AddDependsOn) + .Then(step => + { + step.Set(x => x.Command, x => + { + var aspNetCoreDir = + x.GetVariable(VariableNames.AspNetCoreDir)!; + var targetAppProjectName = + x.GetVariable(VariableNames.TargetAppProjectName)!; + var packageName = + x.GetVariable(VariableNames.PackageName)!; + var projectInfo = x.GetVariable("ProjectInfo")!; + + return + $"cd{cdOption} {aspNetCoreDir}/src/{projectInfo.FullName}.{targetAppProjectName} && dotnet add package {packageName}"; + }); + }) + .ThenNamed(ActivityNames.AddDependsOn) ; } ) .Then().WithName(ActivityNames.AddDependsOn) - .Then( - step => { step.SearchFileName = new JavaScriptExpression($"`${{ProjectInfo.Name}}${{{VariableNames.AppProjectClassNamePostfix}}}Module.cs`"); }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var appProjectClassNamePostfix = + x.GetVariable(VariableNames.AppProjectClassNamePostfix)!; + var projectInfo = x.GetVariable("ProjectInfo")!; + + return + $"{projectInfo.Name}{appProjectClassNamePostfix}Module.cs"; + }); + }) .Then(step => { - step.Action = new LiteralExpression(((int)DependsOnStep.ActionType.Add).ToString()); + step.Set(x => x.Action, DependsOnStep.ActionType.Add); + step.Set(x => x.ModuleClassNamePostfix, + x => x.GetVariable(VariableNames.ModuleClassNamePostfix)); + step.Set(x => x.DependsOnModuleClassName, + x => x.GetVariable(VariableNames.DependsOnModuleClassName)); + step.Set(x => x.SubmoduleUsingTextPostfix, + x => x.GetVariable(VariableNames.SubmoduleUsingTextPostfix)); }) .Then() - .Then( - step => step.ConditionExpression = new JavaScriptExpression("TargetAppProjectName == 'EntityFrameworkCore'"), + .Then( + step => + { + step.Set(x => x.Condition, x => + { + var targetAppProjectName = + x.GetVariable(VariableNames.TargetAppProjectName)!; + return targetAppProjectName == "EntityFrameworkCore"; + }); + }, ifElse => { // For "EntityFrameCore" package, we generate a "builder.ConfigureXXX();" in the migrations context class */ @@ -179,19 +238,18 @@ protected override IActivityBuilder ConfigureBuild(AddCommandOption option, IAct .AddConfigureFindDbContextWorkflow("AddAction") .Then(step => { - step.Action = new LiteralExpression(((int)MigrationsContextStep.ActionType.Add).ToString()); + step.Set(x => x.Action, MigrationsContextStep.ActionType.Add); }).WithName("AddAction") .Then() - .Then(ActivityNames.NextProject) + .ThenNamed(ActivityNames.NextProject) ; ifElse .When(OutcomeNames.False) - .Then(ActivityNames.NextProject) + .ThenNamed(ActivityNames.NextProject) ; } ) .Then().WithName(ActivityNames.NextProject) - .Then(branch) ) ; } diff --git a/src/AbpHelper.Core/Commands/Module/Add/AddCommandOption.cs b/src/AbpHelper.Core/Commands/Module/Add/AddCommandOption.cs index 4f68bb5a..397d140b 100644 --- a/src/AbpHelper.Core/Commands/Module/Add/AddCommandOption.cs +++ b/src/AbpHelper.Core/Commands/Module/Add/AddCommandOption.cs @@ -5,6 +5,6 @@ namespace EasyAbp.AbpHelper.Core.Commands.Module.Add public class AddCommandOption : ModuleCommandOption { [Option('v', "version", Description = "Specify the version of the package(s) to add")] - public string Version { get; set; } = null!; + public string? Version { get; set; } } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Commands/Module/ModuleCommand.cs b/src/AbpHelper.Core/Commands/Module/ModuleCommand.cs index 6cc62e71..5e619adc 100644 --- a/src/AbpHelper.Core/Commands/Module/ModuleCommand.cs +++ b/src/AbpHelper.Core/Commands/Module/ModuleCommand.cs @@ -1,13 +1,12 @@ using System; using EasyAbp.AbpHelper.Core.Commands.Module.Add; using EasyAbp.AbpHelper.Core.Commands.Module.Remove; -using JetBrains.Annotations; namespace EasyAbp.AbpHelper.Core.Commands.Module { public class ModuleCommand : CommandBase { - public ModuleCommand([NotNull] IServiceProvider serviceProvider) + public ModuleCommand(IServiceProvider serviceProvider) : base(serviceProvider, "module", "Help quickly install/update/uninstall ABP modules. See 'abphelper module --help' for details") { AddCommand(); diff --git a/src/AbpHelper.Core/Commands/Module/Remove/RemoveCommand.cs b/src/AbpHelper.Core/Commands/Module/Remove/RemoveCommand.cs index eba30193..0e078151 100644 --- a/src/AbpHelper.Core/Commands/Module/Remove/RemoveCommand.cs +++ b/src/AbpHelper.Core/Commands/Module/Remove/RemoveCommand.cs @@ -3,18 +3,19 @@ using System.CommandLine; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow; using EasyAbp.AbpHelper.Core.Workflow.Common; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; using JetBrains.Annotations; +using IActivityBuilder = Elsa.Builders.IActivityBuilder; namespace EasyAbp.AbpHelper.Core.Commands.Module.Remove { @@ -22,18 +23,19 @@ public class RemoveCommand : CommandWithOption { private readonly IDictionary _packageProjectMap = new Dictionary { - {ModuleConsts.Shared, "Domain.Shared"}, - {ModuleConsts.Domain, "Domain"}, - {ModuleConsts.EntityFrameworkCore, "EntityFrameworkCore"}, - {ModuleConsts.MongoDB, "MongoDB"}, - {ModuleConsts.Contracts, "Application.Contracts"}, - {ModuleConsts.Application, "Application"}, - {ModuleConsts.HttpApi, "HttpApi"}, - {ModuleConsts.Client, "HttpApi.Client"}, - {ModuleConsts.Web, "Web"}, + { ModuleConsts.Shared, "Domain.Shared" }, + { ModuleConsts.Domain, "Domain" }, + { ModuleConsts.EntityFrameworkCore, "EntityFrameworkCore" }, + { ModuleConsts.MongoDB, "MongoDB" }, + { ModuleConsts.Contracts, "Application.Contracts" }, + { ModuleConsts.Application, "Application" }, + { ModuleConsts.HttpApi, "HttpApi" }, + { ModuleConsts.Client, "HttpApi.Client" }, + { ModuleConsts.Web, "Web" }, }; - public RemoveCommand([NotNull] IServiceProvider serviceProvider) : base(serviceProvider, "remove", "Remove ABP module according to the specified packages") + public RemoveCommand([NotNull] IServiceProvider serviceProvider) : base(serviceProvider, "remove", + "Remove ABP module according to the specified packages") { AddValidator(result => { @@ -49,10 +51,10 @@ public RemoveCommand([NotNull] IServiceProvider serviceProvider) : base(serviceP protected override IActivityBuilder ConfigureBuild(RemoveCommandOption option, IActivityBuilder activityBuilder) { var moduleNameToAppProjectNameMapping = typeof(ModuleCommandOption).GetProperties() - .Where(prop => prop.PropertyType == typeof(bool) && (bool) prop.GetValue(option)!) + .Where(prop => prop.PropertyType == typeof(bool) && (bool)prop.GetValue(option)!) .Select(prop => _packageProjectMap[prop.Name.ToKebabCase()]) .ToDictionary(x => x, x => x); - + if (!option.Custom.IsNullOrEmpty()) { foreach (var customPart in option.Custom.Split(',')) @@ -61,86 +63,114 @@ protected override IActivityBuilder ConfigureBuild(RemoveCommandOption option, I moduleNameToAppProjectNameMapping.Add(s[0], s[1]); } } - - string cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; + + var cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; return base.ConfigureBuild(option, activityBuilder) - .Then( - step => - { - step.VariableName = VariableNames.TemplateDirectory; - step.ValueExpression = new LiteralExpression("/Templates/Module"); - }) - .Then( - step => - { - step.VariableName = VariableNames.ProjectNames; - step.ValueExpression = new JavaScriptExpression($"[{string.Join(",", moduleNameToAppProjectNameMapping.Select(n => $"\"{n.Key}:{n.Value}\""))}]"); - } - ) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TemplateDirectory); + step.Set(x => x.Value, "/Templates/Module"); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.ProjectNames); + step.Set(x => x.Value, moduleNameToAppProjectNameMapping); + }) .Then() .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(VariableNames.ProjectNames); }, + step => + { + step.Set(x => x.Items, x => x.GetVariable>(VariableNames.ProjectNames)); + }, branch => branch.When(OutcomeNames.Iterate) - .Then( - step => - { - step.VariableName = VariableNames.CurrentModuleName; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':')[0]"); - } - ) - .Then( - step => + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.CurrentModuleName); + step.Set(x => x.Value, x => x.GetInput()!.Split(':')[0]); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.TargetAppProjectName); + step.Set(x => x.Value, x => x.GetInput()!.Split(':')[1]); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.SubmoduleUsingTextPostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.TargetAppProjectName; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':')[1]"); - } - ) - .Then( - step => + var s = x.GetInput()!.Split(':'); + return s.Length > 2 ? $".{s[2]}" : ""; + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.PackageName); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.SubmoduleUsingTextPostfix; - step.ValueExpression = new JavaScriptExpression("CurrentValue.split(':').length > 2 ? '.' + CurrentValue.split(':')[2] : ''"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return currentModuleName.IsNullOrWhiteSpace() + ? option.ModuleName + : $"{option.ModuleName}.{currentModuleName}"; + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.ModuleClassNamePostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.PackageName; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.CurrentModuleName} != '' ? {CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleName)} + '.' + {VariableNames.CurrentModuleName} : {CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleName)}"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return Regex.Replace(currentModuleName, "/\\./g", ""); + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.AppProjectClassNamePostfix); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.ModuleClassNamePostfix; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.CurrentModuleName}.replace(/\\./g, '')"); - } - ) - .Then( - step => + var currentModuleName = x.GetVariable(VariableNames.CurrentModuleName)!; + return Regex.Replace(currentModuleName, "/\\./g", ""); + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, VariableNames.DependsOnModuleClassName); + step.Set(x => x.Value, x => { - step.VariableName = VariableNames.AppProjectClassNamePostfix; - step.ValueExpression = new JavaScriptExpression($"{VariableNames.TargetAppProjectName}.replace(/\\./g, '')"); - } - ) - .Then( - step => + var moduleClassNamePostfix = + x.GetVariable(VariableNames.ModuleClassNamePostfix); + return + $"{option.ModuleGroupNameWithoutCompanyName}{moduleClassNamePostfix}Module"; + }); + }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => { - step.VariableName = VariableNames.DependsOnModuleClassName; - step.ValueExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(ModuleCommandOption.ModuleGroupNameWithoutCompanyName)} + {VariableNames.ModuleClassNamePostfix} + 'Module'"); - } - ) - .Then( - step => { step.SearchFileName = new JavaScriptExpression($"`${{ProjectInfo.Name}}${{{VariableNames.AppProjectClassNamePostfix}}}Module.cs`"); }) + var projectInfo = x.GetVariable("ProjectInfo")!; + var postfix = x.GetVariable(VariableNames.AppProjectClassNamePostfix); + return $"{projectInfo.Name}{postfix}Module.cs"; + }); + }) .Then(step => { - step.Action = new LiteralExpression(((int)DependsOnStep.ActionType.Remove).ToString()); - }) + step.Set(x => x.Action, DependsOnStep.ActionType.Remove); + step.Set(x => x.ModuleClassNamePostfix, + x => x.GetVariable(VariableNames.ModuleClassNamePostfix)); + step.Set(x => x.DependsOnModuleClassName, + x => x.GetVariable(VariableNames.DependsOnModuleClassName)); + step.Set(x => x.SubmoduleUsingTextPostfix, + x => x.GetVariable(VariableNames.SubmoduleUsingTextPostfix)); + }) .Then() - .Then( - step => step.ConditionExpression = new JavaScriptExpression("TargetAppProjectName == 'EntityFrameworkCore'"), + .Then( + step => step.Set(x => x.Condition, + x => + { + return x.GetVariable(VariableNames.TargetAppProjectName) == + "EntityFrameworkCore"; + }), ifElse => { // For "EntityFrameCore" package, we generate a "builder.ConfigureXXX();" in the migrations context class */ @@ -150,23 +180,31 @@ protected override IActivityBuilder ConfigureBuild(RemoveCommandOption option, I .AddConfigureFindDbContextWorkflow("RemoveAction") .Then(step => { - step.Action = new LiteralExpression(((int)MigrationsContextStep.ActionType.Remove).ToString()); + step.Set(x => x.Action, MigrationsContextStep.ActionType.Remove); }).WithName("RemoveAction") .Then() - .Then(ActivityNames.RemoveDependsOn) + .ThenNamed(ActivityNames.RemoveDependsOn) ; ifElse .When(OutcomeNames.False) - .Then(ActivityNames.RemoveDependsOn) + .ThenNamed(ActivityNames.RemoveDependsOn) ; } ) .Then().WithName(ActivityNames.RemoveDependsOn) - .Then( - step => step.Command = new JavaScriptExpression( - $@"`cd{cdOption} ${{AspNetCoreDir}}/src/${{ProjectInfo.FullName}}.${{TargetAppProjectName}} && dotnet remove package ${{PackageName}}`" - )) - .Then(branch) + .Then(step => + { + step.Set(x => x.Command, x => + { + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir); + var projectInfo = x.GetVariable("ProjectInfo")!; + var targetAppProjectName = + x.GetVariable(VariableNames.TargetAppProjectName)!; + var packageName = x.GetVariable(VariableNames.PackageName)!; + return + $"cd{cdOption} {aspNetCoreDir}/src/{projectInfo.FullName}.{targetAppProjectName} && dotnet remove package {packageName}"; + }); + }) ) ; } diff --git a/src/AbpHelper.Core/Extensions/ServiceCollectionExtensions.cs b/src/AbpHelper.Core/Extensions/ServiceCollectionExtensions.cs index b83d7ab3..2dce601d 100644 --- a/src/AbpHelper.Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/AbpHelper.Core/Extensions/ServiceCollectionExtensions.cs @@ -1,23 +1,23 @@ -using System; -using System.Linq; +using System.Linq; using System.Reflection; -using Elsa.Services.Models; +using Elsa.Options; +using Elsa.Services; using Microsoft.Extensions.DependencyInjection; namespace EasyAbp.AbpHelper.Core.Extensions { public static class ServiceCollectionExtensions { - public static IServiceCollection AddAllActivities(this IServiceCollection services) + public static ElsaOptionsBuilder AddAbpHelperActivities(this ElsaOptionsBuilder services) { var activityTypes = Assembly.GetExecutingAssembly().GetTypes() - .Where(t => !t.IsAbstract) - .Where(t => t.IsAssignableTo(typeof(IActivity))) - ; - foreach (var activity in activityTypes) - services.AddTransient(activity) - .AddTransient(sp => (IActivity) sp.GetRequiredService(activity)) - ; + .Where(t => !t.IsAbstract) + .Where(t => t.IsAssignableTo(typeof(IActivity))); + + foreach (var activityType in activityTypes) + { + services.AddActivity(activityType); + } return services; } diff --git a/src/AbpHelper.Core/Models/TypeInfo.cs b/src/AbpHelper.Core/Models/TypeInfo.cs index b7096e8d..37207858 100644 --- a/src/AbpHelper.Core/Models/TypeInfo.cs +++ b/src/AbpHelper.Core/Models/TypeInfo.cs @@ -9,15 +9,15 @@ namespace EasyAbp.AbpHelper.Core.Models /// public class TypeInfo { - public List Usings { get; } = new List(); + public List Usings { get; } = new(); public string Namespace { get; } public string NamespaceLastPart => Namespace.Split('.').Last(); public string Name { get; } public string NamePluralized => Name.Pluralize(); public string RelativeDirectory { get; } public string RelativeNamespace => RelativeDirectory.Replace('/', '.'); - public List Methods { get; } = new List(); - public List Attributes { get; } = new List(); + public List Methods { get; } = new(); + public List Attributes { get; } = new(); public TypeInfo(string @namespace, string name, string relativeDirectory) { diff --git a/src/AbpHelper.Core/Steps/Abp/BuildDtoInfoStep.cs b/src/AbpHelper.Core/Steps/Abp/BuildDtoInfoStep.cs index 00ac28aa..6e17b3cc 100644 --- a/src/AbpHelper.Core/Steps/Abp/BuildDtoInfoStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/BuildDtoInfoStep.cs @@ -1,24 +1,74 @@ using System; -using EasyAbp.AbpHelper.Core.Commands.Generate.Crud; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Models; -using Elsa.Results; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; using Microsoft.Extensions.Logging; namespace EasyAbp.AbpHelper.Core.Steps.Abp { + [Activity( + Category = "BuildDtoInfoStep", + Description = "BuildDtoInfoStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class BuildDtoInfoStep : Step { - protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext context) + [ActivityInput( + Hint = "EntityInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public EntityInfo EntityInfo { - var entityInfo = context.GetVariable("EntityInfo"); - var option = context.GetVariable("Option") as CrudCommandOption; + get => GetState()!; + set => SetState(value); + } + + [ActivityInput( + Hint = "SeparateDto", + UIHint = ActivityInputUIHints.Checkbox, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public bool SeparateDto + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "EntityPrefixDto", + UIHint = ActivityInputUIHints.Checkbox, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public bool EntityPrefixDto + { + get => GetState(); + set => SetState(value); + } + [ActivityInput( + Hint = "DtoSuffix", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string? DtoSuffix + { + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { try { - string[] actionNames = { string.Empty, string.Empty, string.Empty}; + string[] actionNames = { string.Empty, string.Empty, string.Empty }; - if (option != null && option.SeparateDto) + if (SeparateDto) { actionNames[1] = "Create"; actionNames[2] = "Update"; @@ -29,21 +79,20 @@ protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext co actionNames[2] = actionNames[1]; } - string[] typeNames = new string[actionNames.Length]; + var typeNames = new string[actionNames.Length]; - var useEntityPrefix = option != null && option.EntityPrefixDto; - var dtoSubfix = option?.DtoSuffix ?? "Dto"; + var dtoSubfix = DtoSuffix ?? "Dto"; - for (int i = 0; i < typeNames.Length; i++) + for (var i = 0; i < typeNames.Length; i++) { - typeNames[i] = useEntityPrefix - ? $"{entityInfo.Name}{actionNames[i]}{dtoSubfix}" - : $"{actionNames[i]}{entityInfo.Name}{dtoSubfix}"; + typeNames[i] = EntityPrefixDto + ? $"{EntityInfo.Name}{actionNames[i]}{dtoSubfix}" + : $"{actionNames[i]}{EntityInfo.Name}{dtoSubfix}"; } - - DtoInfo dtoInfo = new DtoInfo(typeNames[0], typeNames[1], typeNames[2]); - - context.SetLastResult(dtoInfo); + + var dtoInfo = new DtoInfo(typeNames[0], typeNames[1], typeNames[2]); + + context.Output = dtoInfo; context.SetVariable("DtoInfo", dtoInfo); LogOutput(() => dtoInfo); diff --git a/src/AbpHelper.Core/Steps/Abp/EntityParserStep.cs b/src/AbpHelper.Core/Steps/Abp/EntityParserStep.cs index ebc4b118..cd830733 100644 --- a/src/AbpHelper.Core/Steps/Abp/EntityParserStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/EntityParserStep.cs @@ -2,14 +2,15 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Common; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -17,26 +18,49 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp { + [Activity( + Category = "EntityParserStep", + Description = "EntityParserStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class EntityParserStep : Step { - public WorkflowExpression EntityFile + [ActivityInput( + Hint = "EntityFile", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityFile { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); + get => GetState(); set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + [ActivityInput( + Hint = "ProjectInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ProjectInfo? ProjectInfo { - var entityFile = await context.EvaluateAsync(EntityFile, cancellationToken); - LogInput(() => entityFile); - var projectInfo = context.GetVariable("ProjectInfo"); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityFile ??= context.GetVariable(FileFinderStep.DefaultFileParameterName)!; + ProjectInfo ??= context.GetVariable("ProjectInfo")!; + + LogInput(() => EntityFile); + LogInput(() => ProjectInfo); - var sourceText = await File.ReadAllTextAsync(entityFile, cancellationToken); + var sourceText = await File.ReadAllTextAsync(EntityFile, context.CancellationToken); try { - var tree = CSharpSyntaxTree.ParseText(sourceText, cancellationToken: cancellationToken); - var root = tree.GetCompilationUnitRoot(cancellationToken: cancellationToken); + var tree = CSharpSyntaxTree.ParseText(sourceText, cancellationToken: context.CancellationToken); + var root = tree.GetCompilationUnitRoot(cancellationToken: context.CancellationToken); if (root.ContainsDiagnostics) { // source contains syntax error @@ -55,7 +79,7 @@ protected override async Task OnExecuteAsync(WorkflowEx var @namespace = namespaceSyntax?.Name.ToString(); var relativeDirectory = @namespace - .RemovePreFix(projectInfo.FullName + ".") + .RemovePreFix(ProjectInfo.FullName + ".") .Replace('.', '/'); var classDeclarationSyntax = root @@ -77,11 +101,13 @@ protected override async Task OnExecuteAsync(WorkflowEx if (genericNameSyntax == null) { // No generic parameter -> Entity with Composite Keys - baseType = baseList.Descendants().Single(node => !node.ToFullString().StartsWith("I")).Type.ToString(); + baseType = baseList.Descendants() + .Single(node => !node.ToFullString().StartsWith("I")).Type.ToString(); primaryKey = null; // Get composite keys - var getKeysMethod = root.Descendants().Single(m => m.Identifier.ToString() == "GetKeys"); + var getKeysMethod = root.Descendants() + .Single(m => m.Identifier.ToString() == "GetKeys"); keyNames = getKeysMethod .Descendants() .First() @@ -92,14 +118,15 @@ protected override async Task OnExecuteAsync(WorkflowEx { // Normal entity baseType = genericNameSyntax.Identifier.ToString(); - primaryKey = genericNameSyntax.Descendants().Single().Arguments[0].ToString(); + primaryKey = genericNameSyntax.Descendants().Single().Arguments[0] + .ToString(); } var properties = root.Descendants() .Select(prop => new PropertyInfo(prop.Type.ToString(), prop.Identifier.ToString())) .ToList() ; - var entityInfo = new EntityInfo(@namespace, className, baseType, primaryKey, relativeDirectory); + var entityInfo = new EntityInfo(@namespace!, className, baseType, primaryKey, relativeDirectory); entityInfo.Properties.AddRange(properties); if (keyNames != null) { @@ -108,7 +135,7 @@ protected override async Task OnExecuteAsync(WorkflowEx keyNames.Select(k => properties.Single(prop => prop.Name == k))); } - context.SetLastResult(entityInfo); + context.Output = entityInfo; context.SetVariable("EntityInfo", entityInfo); LogOutput(() => entityInfo); diff --git a/src/AbpHelper.Core/Steps/Abp/LocalizationJsonModificationCreatorStep.cs b/src/AbpHelper.Core/Steps/Abp/LocalizationJsonModificationCreatorStep.cs index b1b7e61d..b571b9e1 100644 --- a/src/AbpHelper.Core/Steps/Abp/LocalizationJsonModificationCreatorStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/LocalizationJsonModificationCreatorStep.cs @@ -1,37 +1,50 @@ using System.IO; -using System.Threading; using System.Threading.Tasks; -using EasyAbp.AbpHelper.Core.Steps.Common; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Newtonsoft.Json.Linq; namespace EasyAbp.AbpHelper.Core.Steps.Abp { + [Activity( + Category = "LocalizationJsonModificationCreatorStep", + Description = "LocalizationJsonModificationCreatorStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class LocalizationJsonModificationCreatorStep : Step { - public WorkflowExpression TargetFile + [ActivityInput( + Hint = "TargetFile", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string TargetFile { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); + get => GetState()!; set => SetState(value); } - public WorkflowExpression LocalizationJson + [ActivityInput( + Hint = "LocalizationJson", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string LocalizationJson { - get => GetState>(); + get => GetState()!; set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var targetFile = await context.EvaluateAsync(TargetFile, cancellationToken); - LogInput(() => targetFile); - var localizations = await context.EvaluateAsync(LocalizationJson, cancellationToken); - var jNew = JObject.Parse(localizations); + LogInput(() => TargetFile); + var jNew = JObject.Parse(LocalizationJson); - var jsonText = await File.ReadAllTextAsync(targetFile); + var jsonText = await File.ReadAllTextAsync(TargetFile); var jDoc = JObject.Parse(jsonText); var jTexts = jDoc["texts"] ?? jDoc["Texts"]!; @@ -39,7 +52,7 @@ protected override async Task OnExecuteAsync(WorkflowEx if (jTexts[kv.Key] == null) // Prevent inserting duplicate localization jTexts[kv.Key] = kv.Value; - await File.WriteAllTextAsync(targetFile, jDoc.ToString()); + await File.WriteAllTextAsync(TargetFile, jDoc.ToString()); return Done(); } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceClassStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceClassStep.cs index 1fc816f3..f2235b75 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceClassStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceClassStep.cs @@ -3,23 +3,30 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "AppServiceClassStep", + Description = "AppServiceClassStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class AppServiceClassStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string usingTaskContents = TextGenerator.GenerateByTemplateName(templateDir, "AppService_UsingTask", model); - string usingDtoContents = TextGenerator.GenerateByTemplateName(templateDir, "AppService_UsingDto", model); - string classContents = TextGenerator.GenerateByTemplateName(templateDir, "AppServiceClass", model); + var model = context.GetVariable("Model")!; + var usingTaskContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppService_UsingTask", model); + var usingDtoContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppService_UsingDto", model); + var classContents = TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppServiceClass", model); return new List> { @@ -40,7 +47,7 @@ protected override IList> CreateModificati }; } - public AppServiceClassStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public AppServiceClassStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceInterfaceStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceInterfaceStep.cs index 107e9161..f5744126 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceInterfaceStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/AppServiceInterfaceStep.cs @@ -3,23 +3,31 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "AppServiceInterfaceStep", + Description = "AppServiceInterfaceStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class AppServiceInterfaceStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string usingTaskContents = TextGenerator.GenerateByTemplateName(templateDir, "AppService_UsingTask", model); - string usingDtoContents = TextGenerator.GenerateByTemplateName(templateDir, "AppService_UsingDto", model); - string interfaceContents = TextGenerator.GenerateByTemplateName(templateDir, "AppServiceInterface", model); + var model = context.GetVariable("Model")!; + var usingTaskContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppService_UsingTask", model); + var usingDtoContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppService_UsingDto", model); + var interfaceContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppServiceInterface", model); return new List> { @@ -40,7 +48,7 @@ protected override IList> CreateModificati }; } - public AppServiceInterfaceStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public AppServiceInterfaceStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ApplicationAutoMapperProfileStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ApplicationAutoMapperProfileStep.cs index 021165a2..2b06e5cb 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ApplicationAutoMapperProfileStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ApplicationAutoMapperProfileStep.cs @@ -1,47 +1,86 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "ApplicationAutoMapperProfileStep", + Description = "ApplicationAutoMapperProfileStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class ApplicationAutoMapperProfileStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "EntityUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityUsingText { - var model = context.GetVariable("Model"); - string entityUsingText = context.GetVariable("EntityUsingText"); - string entityDtoUsingText = context.GetVariable("EntityDtoUsingText"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string contents = TextGenerator.GenerateByTemplateName(templateDir, "ApplicationAutoMapperProfile_CreateMap", model); - + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "EntityDtoUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityDtoUsingText + { + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityUsingText ??= context.GetVariable("EntityUsingText")!; + EntityDtoUsingText ??= context.GetVariable("EntityDtoUsingText")!; + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var contents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "ApplicationAutoMapperProfile_CreateMap", + context.GetVariable("Model")!); + return new List> { new InsertionBuilder( root => root.Descendants().Last().GetEndLine(), - entityUsingText, - modifyCondition: root => root.DescendantsNotContain(entityUsingText) + EntityUsingText, + modifyCondition: root => root.DescendantsNotContain(EntityUsingText) ), new InsertionBuilder( root => root.Descendants().Last().GetEndLine(), - entityDtoUsingText, - modifyCondition: root => root.DescendantsNotContain(entityDtoUsingText) + EntityDtoUsingText, + modifyCondition: root => root.DescendantsNotContain(EntityDtoUsingText) ), new InsertionBuilder( root => root.Descendants().Single().GetEndLine(), contents, - modifyCondition: root => root.Descendants().Single().NotContains(contents) + modifyCondition: root => + root.Descendants().Single().NotContains(contents) ) }; } - public ApplicationAutoMapperProfileStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public ApplicationAutoMapperProfileStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/CSharpModificationCreatorStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/CSharpModificationCreatorStep.cs index f5b5d301..089536d9 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/CSharpModificationCreatorStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/CSharpModificationCreatorStep.cs @@ -1,41 +1,33 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; +using EasyAbp.AbpHelper.Core.Workflow; +using Elsa.ActivityResults; using Elsa.Services.Models; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { - public abstract class CSharpModificationCreatorStep : Step + public abstract class CSharpModificationCreatorStep : CodeModificationStepBase { - protected TextGenerator TextGenerator; - - protected CSharpModificationCreatorStep(TextGenerator textGenerator) + protected CSharpModificationCreatorStep(TextGenerator textGenerator) : base(textGenerator) { - TextGenerator = textGenerator; } - public WorkflowExpression SourceFile + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); - set => SetState(value); - } + TemplateDirectory ??= context.GetVariable(VariableNames.TemplateDirectory)!; + SourceFile ??= context.GetVariable(FileFinderStep.DefaultFileParameterName)!; - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) - { - var file = await context.EvaluateAsync(SourceFile, cancellationToken); - LogInput(() => file); + LogInput(() => TemplateDirectory); + LogInput(() => SourceFile); - var sourceText = await File.ReadAllTextAsync(file, cancellationToken); + var sourceText = await File.ReadAllTextAsync(SourceFile!, context.CancellationToken); var tree = CSharpSyntaxTree.ParseText(sourceText); var root = tree.GetCompilationUnitRoot(); @@ -46,13 +38,14 @@ protected override async Task OnExecuteAsync(WorkflowEx .ToList() ; - context.SetLastResult(modifications); + context.Output = modifications; context.SetVariable("Modifications", modifications); LogOutput(() => modifications, $"Modifications count: {modifications.Count}"); return Done(); } - protected abstract IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit); + protected abstract IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit); } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ControllerStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ControllerStep.cs index 9dba83c0..16de7c23 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ControllerStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/ControllerStep.cs @@ -3,7 +3,10 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; @@ -11,36 +14,70 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "ControllerStep", + Description = "ControllerStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class ControllerStep : CSharpModificationCreatorStep { - public ControllerStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + [ActivityInput( + Hint = "InterfaceInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public TypeInfo InterfaceInfo + { + get => GetState()!; + set => SetState(value); + } + + [ActivityInput( + Hint = "ClassInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public TypeInfo ClassInfo + { + get => GetState()!; + set => SetState(value); + } + + [ActivityInput( + Hint = "ControllerInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public TypeInfo ControllerInfo { + get => GetState()!; + set => SetState(value); } - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + public ControllerStep([NotNull] TextGenerator textGenerator) : base(textGenerator) { - var serviceInterfaceInfo = context.GetVariable("InterfaceInfo"); - var serviceClassInfo = context.GetVariable("ClassInfo"); - var controllerInfo = context.GetVariable("ControllerInfo"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); + } + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { // Generate added methods var modifications = new List>(); - var addedMethods = serviceClassInfo.Methods - .Except(controllerInfo.Methods) // Except the existing controller methods - .Intersect(serviceInterfaceInfo.Methods) // Only methods defined in the interface need to generate - // Why not just use the `serviceInterfaceInfo.Methods`? Because we need use attributes info - // which only defined in the service class + var addedMethods = ClassInfo.Methods + .Except(ControllerInfo.Methods) // Except the existing controller methods + .Intersect(InterfaceInfo.Methods) // Only methods defined in the interface need to generate + // Why not just use the `serviceInterfaceInfo.Methods`? Because we need use attributes info + // which only defined in the service class ; foreach (var method in addedMethods) { - var model = new {method}; - string methodText = TextGenerator.GenerateByTemplateName(templateDir, "ControllerMethod", model); + var model = new { method }; + string methodText = TextGenerator.GenerateByTemplateName(TemplateDirectory, "ControllerMethod", model); modifications.Add( new InsertionBuilder( - root => root.Descendants().First().GetEndLine(), - methodText - )); + root => root.Descendants().First().GetEndLine(), + methodText + )); } return modifications; diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextClassStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextClassStep.cs index 00b46c8a..b7624b78 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextClassStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextClassStep.cs @@ -1,9 +1,14 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; @@ -11,27 +16,52 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "DbContextClassStep", + Description = "DbContextClassStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class DbContextClassStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "EntityUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityUsingText { - var model = context.GetVariable("Model"); - string entityUsingText = context.GetVariable("EntityUsingText"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string dbContextPropertyText = TextGenerator.GenerateByTemplateName(templateDir, "DbContextClass_Property", model); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityUsingText ??= context.GetVariable("EntityUsingText")!; + + LogInput(() => EntityUsingText); + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var dbContextPropertyText = + TextGenerator.GenerateByTemplateName(TemplateDirectory!, "DbContextClass_Property", context.GetVariable("Model")!); return new List> { new InsertionBuilder( root => root.Descendants().Last().GetEndLine(), - entityUsingText, + EntityUsingText!, InsertPosition.After, - root => root.DescendantsNotContain(entityUsingText) + root => root.DescendantsNotContain(EntityUsingText!) ), new InsertionBuilder( root => root.Descendants().Single().Identifier.GetStartLine() - 1, dbContextPropertyText, - modifyCondition: root => root.DescendantsNotContain(dbContextPropertyText) + modifyCondition: root => + root.DescendantsNotContain(dbContextPropertyText) ) }; } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextInterfaceStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextInterfaceStep.cs index 21d8d9d7..381130c5 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextInterfaceStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextInterfaceStep.cs @@ -1,25 +1,53 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "DbContextInterfaceStep", + Description = "DbContextInterfaceStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class DbContextInterfaceStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "EntityUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityUsingText { - var model = context.GetVariable("Model"); - string entityUsingText = context.GetVariable("EntityUsingText"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string dbContextUsingText = TextGenerator.GenerateByTemplateName(templateDir, "DbContextInterface_Using", model); - string dbContextPropertyText = TextGenerator.GenerateByTemplateName(templateDir, "DbContextInterface_Property", model); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityUsingText ??= context.GetVariable("EntityUsingText")!; + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var model = context.GetVariable("Model")!; + var dbContextUsingText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "DbContextInterface_Using", model); + var dbContextPropertyText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "DbContextInterface_Property", model); return new List> { @@ -31,19 +59,20 @@ protected override IList> CreateModificati ), new InsertionBuilder( root => root.Descendants().Last().GetEndLine(), - entityUsingText, + EntityUsingText, InsertPosition.After, - root => root.DescendantsNotContain(entityUsingText) + root => root.DescendantsNotContain(EntityUsingText) ), new InsertionBuilder( root => root.Descendants().Single().GetEndLine(), dbContextPropertyText, - modifyCondition: root => root.DescendantsNotContain(dbContextPropertyText) + modifyCondition: root => + root.DescendantsNotContain(dbContextPropertyText) ) }; } - public DbContextInterfaceStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public DbContextInterfaceStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextModelCreatingExtensionsStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextModelCreatingExtensionsStep.cs index 39adcee2..d0d134ed 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextModelCreatingExtensionsStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DbContextModelCreatingExtensionsStep.cs @@ -1,32 +1,61 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "DbContextModelCreatingExtensionsStep", + Description = "DbContextModelCreatingExtensionsStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class DbContextModelCreatingExtensionsStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "EntityUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityUsingText { - var model = context.GetVariable("Model"); - var entityUsingText = context.GetVariable("EntityUsingText"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - var modelingUsingText = TextGenerator.GenerateByTemplateName(templateDir, "DbContextModelCreatingExtensions_Using", model); - var entityConfigText = TextGenerator.GenerateByTemplateName(templateDir, "DbContextModelCreatingExtensions_EntityConfig", model); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityUsingText ??= context.GetVariable("EntityUsingText")!; + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var model = context.GetVariable("Model")!; + var modelingUsingText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "DbContextModelCreatingExtensions_Using", + model); + var entityConfigText = TextGenerator.GenerateByTemplateName(TemplateDirectory, + "DbContextModelCreatingExtensions_EntityConfig", model); return new List> { new InsertionBuilder( root => 1, - entityUsingText, - modifyCondition: root => root.DescendantsNotContain(entityUsingText) + EntityUsingText, + modifyCondition: root => root.DescendantsNotContain(EntityUsingText) ), new InsertionBuilder( root => root.Descendants().Last().GetEndLine(), @@ -36,12 +65,13 @@ protected override IList> CreateModificati new InsertionBuilder( root => root.Descendants().First().GetEndLine(), entityConfigText, - modifyCondition: root => root.Descendants().First().NotContains(entityConfigText) + modifyCondition: root => + root.Descendants().First().NotContains(entityConfigText) ) }; } - public DbContextModelCreatingExtensionsStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public DbContextModelCreatingExtensionsStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DependsOnStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DependsOnStep.cs index f7608267..59f8d627 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DependsOnStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/DependsOnStep.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; using Elsa.Services.Models; using JetBrains.Annotations; @@ -14,37 +15,80 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "DependsOnStep", + Description = "DependsOnStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class DependsOnStep : CSharpModificationCreatorStep { public enum ActionType { - Add, Remove + Add, + Remove } - public WorkflowExpression Action + + [ActivityInput( + Hint = "Action", + UIHint = ActivityInputUIHints.Dropdown, + Options = new[] { ActionType.Add, ActionType.Remove }, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ActionType Action + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "ModuleClassNamePostfix", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string ModuleClassNamePostfix + { + get => GetState()!; + set => SetState(value); + } + + [ActivityInput( + Hint = "SubmoduleUsingTextPostfix", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string SubmoduleUsingTextPostfix { - get => GetState>(); + get => GetState()!; set => SetState(value); } - + + [ActivityInput( + Hint = "DependsOnModuleClassName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string DependsOnModuleClassName + { + get => GetState()!; + set => SetState(value); + } + public DependsOnStep([NotNull] TextGenerator textGenerator) : base(textGenerator) { } - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var action = context.EvaluateAsync(Action, CancellationToken.None).GetAwaiter().GetResult(); - var moduleClassNamePostfix = context.GetVariable(VariableNames.ModuleClassNamePostfix); - var submoduleUsingTextPostfix = context.GetVariable(VariableNames.SubmoduleUsingTextPostfix); - var dependsOnClassName = context.GetVariable(VariableNames.DependsOnModuleClassName); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - var model = context.GetVariable("Model"); - model.Bag.ModuleClassNamePostfix = moduleClassNamePostfix; - model.Bag.DependsOnModuleClassName = dependsOnClassName; - model.Bag.SubmoduleUsingTextPostfix = submoduleUsingTextPostfix; - string usingText = TextGenerator.GenerateByTemplateName(templateDir, "ModuleClass_Using", model); - string dependsOnText = TextGenerator.GenerateByTemplateName(templateDir, "ModuleClass_DependsOn", model); + var model = context.GetVariable("Model")! as dynamic; + model.Bag.ModuleClassNamePostfix = ModuleClassNamePostfix; + model.Bag.DependsOnModuleClassName = DependsOnModuleClassName; + model.Bag.SubmoduleUsingTextPostfix = SubmoduleUsingTextPostfix; + string usingText = TextGenerator.GenerateByTemplateName(TemplateDirectory, "ModuleClass_Using", model); + string dependsOnText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "ModuleClass_DependsOn", model); - if (action == ActionType.Add) + if (Action == ActionType.Add) { // Add "[DependsOn(...)]" return new List> @@ -65,8 +109,10 @@ protected override IList> CreateModificati else { // Delete "[DependsOn(...)]" - Func usingLine = node => node.Descendants().Single(n => n.Contains(usingText)).GetStartLine(); - Func dependsLine = node => node.Descendants().Single(n => n.Contains(dependsOnText)).GetStartLine(); + Func usingLine = node => + node.Descendants().Single(n => n.Contains(usingText)).GetStartLine(); + Func dependsLine = node => + node.Descendants().Single(n => n.Contains(dependsOnText)).GetStartLine(); return new List> { new DeletionBuilder( diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityConstructorsStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityConstructorsStep.cs index cb69ff6d..d16ab772 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityConstructorsStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityConstructorsStep.cs @@ -3,22 +3,29 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "EntityConstructorsStep", + Description = "EntityConstructorsStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class EntityConstructorsStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string protectedCtorText = TextGenerator.GenerateByTemplateName(templateDir, "Entity_ProtectedConstructor", model); - string publicCtorText = TextGenerator.GenerateByTemplateName(templateDir, "Entity_PublicConstructor", model); + var model = context.GetVariable("Model")!; + var protectedCtorText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Entity_ProtectedConstructor", model); + var publicCtorText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Entity_PublicConstructor", model); return new List> { @@ -37,7 +44,7 @@ protected override IList> CreateModificati }; } - public EntityConstructorsStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public EntityConstructorsStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityFrameworkCoreModuleStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityFrameworkCoreModuleStep.cs index 2741caec..3102e0d8 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityFrameworkCoreModuleStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/EntityFrameworkCoreModuleStep.cs @@ -1,24 +1,51 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "EntityFrameworkCoreModuleStep", + Description = "EntityFrameworkCoreModuleStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class EntityFrameworkCoreModuleStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "EntityUsingText", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? EntityUsingText { - var model = context.GetVariable("Model"); - string entityUsingText = context.GetVariable("EntityUsingText"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string contents = TextGenerator.GenerateByTemplateName(templateDir, "EntityFrameworkCoreModule_AddRepository", model); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + EntityUsingText ??= context.GetVariable("EntityUsingText")!; + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var contents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "EntityFrameworkCoreModule_AddRepository", + context.GetVariable("Model")!); CSharpSyntaxNode Func(CSharpSyntaxNode root) => root .Descendants() @@ -29,8 +56,8 @@ CSharpSyntaxNode Func(CSharpSyntaxNode root) => root { new InsertionBuilder( root => 1, - entityUsingText, - modifyCondition: root => root.DescendantsNotContain(entityUsingText) + EntityUsingText, + modifyCondition: root => root.DescendantsNotContain(EntityUsingText) ), new InsertionBuilder( root => Func(root).GetEndLine(), @@ -40,7 +67,7 @@ CSharpSyntaxNode Func(CSharpSyntaxNode root) => root }; } - public EntityFrameworkCoreModuleStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public EntityFrameworkCoreModuleStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MenuContributorStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MenuContributorStep.cs index 6d480063..f94f8ba5 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MenuContributorStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MenuContributorStep.cs @@ -1,33 +1,64 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "MenuContributorStep", + Description = "MenuContributorStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class MenuContributorStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "ProjectInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ProjectInfo? ProjectInfo { - var projectInfo = context.GetVariable("ProjectInfo"); - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string addMenuItemText = TextGenerator.GenerateByTemplateName(templateDir, "MenuContributor_AddMenuItem", model); + get => GetState(); + set => SetState(value); + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + ProjectInfo ??= context.GetVariable("ProjectInfo")!; + + LogInput(() => ProjectInfo); + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var model = context.GetVariable("Model")!; + + var addMenuItemText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "MenuContributor_AddMenuItem", model); CSharpSyntaxNode MainMenu(CSharpSyntaxNode root) => root.Descendants() .First(n => n.Identifier.ToString().Contains("ConfigureMainMenu")); var builders = new List>(); - if (projectInfo.TemplateType == TemplateType.Application) + if (ProjectInfo.TemplateType == TemplateType.Application) { - string usingForAppText = TextGenerator.GenerateByTemplateName(templateDir, "MenuContributor_UsingForApp", model); + var usingForAppText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "MenuContributor_UsingForApp", model); builders.Add( new InsertionBuilder( @@ -43,11 +74,14 @@ CSharpSyntaxNode MainMenu(CSharpSyntaxNode root) => root.Descendants( root => MainMenu(root).GetStartLine(), @@ -81,7 +115,7 @@ CSharpSyntaxNode MainMenu(CSharpSyntaxNode root) => root.Descendants> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string addMenuNameText = TextGenerator.GenerateByTemplateName(templateDir, "Menus_AddMenuName", model); - + var addMenuNameText = TextGenerator.GenerateByTemplateName(TemplateDirectory!, "Menus_AddMenuName", + context.GetVariable("Model")!); + return new List> { new InsertionBuilder( diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MigrationsContextStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MigrationsContextStep.cs index 0d3b4ca9..cf3cb8c3 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MigrationsContextStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/MigrationsContextStep.cs @@ -1,51 +1,89 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "MigrationsContextStep", + Description = "MigrationsContextStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class MigrationsContextStep : CSharpModificationCreatorStep - { + { public enum ActionType { - Add, Remove + Add, + Remove } - public WorkflowExpression Action + + [ActivityInput( + Hint = "Action", + UIHint = ActivityInputUIHints.Dropdown, + Options = new[] { ActionType.Add, ActionType.Remove }, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ActionType Action + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "SubmoduleUsingTextPostfix", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? SubmoduleUsingTextPostfix { - get => GetState>(); + get => GetState(); set => SetState(value); } - public MigrationsContextStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + + public MigrationsContextStep(TextGenerator textGenerator) : base(textGenerator) { } - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var action = context.EvaluateAsync(Action, CancellationToken.None).GetAwaiter().GetResult(); - var submoduleUsingTextPostfix = context.GetVariable(VariableNames.SubmoduleUsingTextPostfix); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - var model = context.GetVariable("Model"); - model.Bag.SubmoduleUsingTextPostfix = submoduleUsingTextPostfix; - model.Bag.SubmoduleNameText = submoduleUsingTextPostfix.Replace(".", ""); - string usingText = TextGenerator.GenerateByTemplateName(templateDir, "MigrationsContext_Using", model); - string configText = TextGenerator.GenerateByTemplateName(templateDir, "MigrationsContext_ConfigureModule", model); + SubmoduleUsingTextPostfix ??= context.GetVariable(VariableNames.SubmoduleUsingTextPostfix)!; + + LogInput(() => SubmoduleUsingTextPostfix); + + return await base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var model = context.GetVariable("Model")! as dynamic; + model.Bag.SubmoduleUsingTextPostfix = SubmoduleUsingTextPostfix; + model.Bag.SubmoduleNameText = SubmoduleUsingTextPostfix.Replace(".", ""); + string usingText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "MigrationsContext_Using", model); + string configText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "MigrationsContext_ConfigureModule", model); MethodDeclarationSyntax GetModelCreatingMethod(CSharpSyntaxNode root) { - return root.Descendants().Single(m => m.Identifier.ToString() == "OnModelCreating"); + return root.Descendants() + .Single(m => m.Identifier.ToString() == "OnModelCreating"); } - if (action == ActionType.Add) + if (Action == ActionType.Add) { // Add "builder.ConfigureXXX();" return new List> @@ -65,8 +103,10 @@ MethodDeclarationSyntax GetModelCreatingMethod(CSharpSyntaxNode root) else { // Remove "builder.ConfigureXXX();" - Func usingLine = node => node.Descendants().Single(n => n.Contains(usingText)).GetStartLine(); - Func configLine = node => node.Descendants().Last(n => n.Contains(configText)).GetStartLine(); + Func usingLine = node => + node.Descendants().Single(n => n.Contains(usingText)).GetStartLine(); + Func configLine = node => + node.Descendants().Last(n => n.Contains(configText)).GetStartLine(); return new List> { new DeletionBuilder( @@ -80,7 +120,6 @@ MethodDeclarationSyntax GetModelCreatingMethod(CSharpSyntaxNode root) modifyCondition: root => root.DescendantsContain(configText) ), }; - } } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionDefinitionProviderStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionDefinitionProviderStep.cs index e4a242e8..8804a197 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionDefinitionProviderStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionDefinitionProviderStep.cs @@ -1,29 +1,58 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "PermissionDefinitionProviderStep", + Description = "PermissionDefinitionProviderStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class PermissionDefinitionProviderStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + [ActivityInput( + Hint = "ProjectInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ProjectInfo? ProjectInfo { - var projectInfo = context.GetVariable("ProjectInfo"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string groupName = rootUnit.Descendants() + get => GetState(); + set => SetState(value); + } + + protected override ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + ProjectInfo ??= context.GetVariable("ProjectInfo")!; + + LogInput(() => ProjectInfo); + + return base.OnExecuteAsync(context); + } + + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) + { + var groupName = rootUnit.Descendants() .Single(stat => stat.ToFullString().Contains("context.AddGroup")) .Descendants().Single() .Variables[0].Identifier.Text; - var model = context.GetVariable("Model"); + var model = context.GetVariable("Model")! as dynamic; model.Bag.GroupName = groupName; - string permissionDefinitionsText = TextGenerator.GenerateByTemplateName(templateDir, "Permissions_Definitions", model); + string permissionDefinitionsText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Permissions_Definitions", model); var builders = new List>(); @@ -34,13 +63,14 @@ protected override IList> CreateModificati root => root.DescendantsNotContain(permissionDefinitionsText) )); - if (projectInfo.TemplateType == TemplateType.Application) + if (ProjectInfo.TemplateType == TemplateType.Application) { // Noting special to do } - else if (projectInfo.TemplateType == TemplateType.Module) + else if (ProjectInfo.TemplateType == TemplateType.Module) { - string addGroupText = TextGenerator.GenerateByTemplateName(templateDir, "Permissions_AddGroup", model); + string addGroupText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Permissions_AddGroup", model); // Uncomment the add group statement builders.Add(new ReplacementBuilder( @@ -54,7 +84,7 @@ protected override IList> CreateModificati return builders; } - public PermissionDefinitionProviderStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public PermissionDefinitionProviderStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionsStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionsStep.cs index b6bde96a..7eb75b06 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionsStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/PermissionsStep.cs @@ -3,21 +3,27 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "PermissionsStep", + Description = "PermissionsStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class PermissionsStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string permissionNamesText = TextGenerator.GenerateByTemplateName(templateDir, "Permissions_Names", model); + var permissionNamesText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Permissions_Names", + context.GetVariable("Model")!); return new List> { @@ -30,7 +36,7 @@ protected override IList> CreateModificati }; } - public PermissionsStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public PermissionsStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/WebAutoMapperProfileStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/WebAutoMapperProfileStep.cs index 0740258c..f32f935c 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/WebAutoMapperProfileStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CSharp/WebAutoMapperProfileStep.cs @@ -3,24 +3,30 @@ using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp { + [Activity( + Category = "WebAutoMapperProfileStep", + Description = "WebAutoMapperProfileStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class WebAutoMapperProfileStep : CSharpModificationCreatorStep { - protected override IList> CreateModifications(WorkflowExecutionContext context, CompilationUnitSyntax rootUnit) + protected override IList> CreateModifications( + ActivityExecutionContext context, CompilationUnitSyntax rootUnit) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); + var model = context.GetVariable("Model")!; + var usingText = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "WebAutoMapperProfile_Using", model); + var contents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "WebAutoMapperProfile_CreateMap", model); - string usingText = TextGenerator.GenerateByTemplateName(templateDir, "WebAutoMapperProfile_Using", model); - - string contents = TextGenerator.GenerateByTemplateName(templateDir, "WebAutoMapperProfile_CreateMap", model); return new List> { new InsertionBuilder( @@ -31,12 +37,13 @@ protected override IList> CreateModificati new InsertionBuilder( root => root.Descendants().Single().GetEndLine(), contents, - modifyCondition: root => root.Descendants().Single().NotContains(contents) + modifyCondition: root => + root.Descendants().Single().NotContains(contents) ) }; } - public WebAutoMapperProfileStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public WebAutoMapperProfileStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeGenerationStepBase.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeGenerationStepBase.cs new file mode 100644 index 00000000..54a87d34 --- /dev/null +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeGenerationStepBase.cs @@ -0,0 +1,27 @@ +using EasyAbp.AbpHelper.Core.Generator; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; + +namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps; + +public abstract class CodeGenerationStepBase : Step +{ + protected readonly TextGenerator TextGenerator; + + protected CodeGenerationStepBase(TextGenerator textGenerator) + { + TextGenerator = textGenerator; + } + + [ActivityInput( + Hint = "TemplateDirectory", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? TemplateDirectory + { + get => GetState(); + set => SetState(value); + } +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeModificationStepBase.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeModificationStepBase.cs new file mode 100644 index 00000000..890ff67f --- /dev/null +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/CodeModificationStepBase.cs @@ -0,0 +1,24 @@ +using EasyAbp.AbpHelper.Core.Generator; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; + +namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps; + +public abstract class CodeModificationStepBase : CodeGenerationStepBase +{ + [ActivityInput( + Hint = "SourceFile", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? SourceFile + { + get => GetState(); + set => SetState(value); + } + + protected CodeModificationStepBase(TextGenerator textGenerator) : base(textGenerator) + { + } +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/AppRoutingModuleStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/AppRoutingModuleStep.cs index 447bf205..abb116ed 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/AppRoutingModuleStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/AppRoutingModuleStep.cs @@ -2,24 +2,43 @@ using System.Linq; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.Typescript { + [Activity( + Category = "AppRoutingModuleStep", + Description = "AppRoutingModuleStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class AppRoutingModuleStep : TypeScriptModificationCreatorStep { + [ActivityInput( + Hint = "EntityInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public EntityInfo EntityInfo + { + get => GetState()!; + set => SetState(value); + } + protected override IList>> CreateModifications( - WorkflowExecutionContext context) + ActivityExecutionContext context) { - var model = context.GetVariable("Model"); - var entityInfo = context.GetVariable("EntityInfo"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string importContents = TextGenerator.GenerateByTemplateName(templateDir, "AppRoutingModule_ImportApplicationLayoutComponent", model); - string routeContents = TextGenerator.GenerateByTemplateName(templateDir, "AppRoutingModule_Routing", model); + var model = context.GetVariable("Model")!; + var importContents = TextGenerator.GenerateByTemplateName(TemplateDirectory, + "AppRoutingModule_ImportApplicationLayoutComponent", model); + var routeContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "AppRoutingModule_Routing", model); - int LineExpression(IEnumerable lines) => lines.Last(l => l.IsMath($"{entityInfo.NamespaceLastPart.ToLower()}")).LineNumber; + int LineExpression(IEnumerable lines) => + lines.Last(l => l.IsMath($"{EntityInfo.NamespaceLastPart.ToLower()}")).LineNumber; return new List>> { @@ -37,7 +56,7 @@ protected override IList>> CreateModif }; } - public AppRoutingModuleStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public AppRoutingModuleStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/ModuleStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/ModuleStep.cs index 0f58ef51..24189ebd 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/ModuleStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/ModuleStep.cs @@ -2,24 +2,43 @@ using System.Linq; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; -using JetBrains.Annotations; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.Typescript { + [Activity( + Category = "ModuleStep", + Description = "ModuleStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class ModuleStep : TypeScriptModificationCreatorStep { + [ActivityInput( + Hint = "EntityInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public EntityInfo EntityInfo + { + get => GetState()!; + set => SetState(value); + } + protected override IList>> CreateModifications( - WorkflowExecutionContext context) + ActivityExecutionContext context) { - var model = context.GetVariable("Model"); - var entityInfo = context.GetVariable("EntityInfo"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string importContents = TextGenerator.GenerateByTemplateName(templateDir, "Module_ImportSharedModule", model); - string sharedModuleContents = TextGenerator.GenerateByTemplateName(templateDir, "Module_SharedModule", model); + var model = context.GetVariable("Model")!; + var importContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Module_ImportSharedModule", model); + var sharedModuleContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "Module_SharedModule", model); - int LineExpression(IEnumerable lines) => lines.Last(l => l.IsMath($"{entityInfo.NamespaceLastPart}RoutingModule")).LineNumber; + int LineExpression(IEnumerable lines) => + lines.Last(l => l.IsMath($"{EntityInfo.NamespaceLastPart}RoutingModule")).LineNumber; return new List>> { @@ -38,7 +57,7 @@ protected override IList>> CreateModif }; } - public ModuleStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public ModuleStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/RoutingModuleStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/RoutingModuleStep.cs index 7031dac8..3d876425 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/RoutingModuleStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/RoutingModuleStep.cs @@ -2,21 +2,26 @@ using System.Linq; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; -using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.Attributes; using Elsa.Services.Models; -using JetBrains.Annotations; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.Typescript { + [Activity( + Category = "RoutingModuleStep", + Description = "RoutingModuleStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class RoutingModuleStep : TypeScriptModificationCreatorStep { protected override IList>> CreateModifications( - WorkflowExecutionContext context) + ActivityExecutionContext context) { - var model = context.GetVariable("Model"); - string templateDir = context.GetVariable(VariableNames.TemplateDirectory); - string importContents = TextGenerator.GenerateByTemplateName(templateDir, "RoutingModule_ImportList", model); - string moduleContents = TextGenerator.GenerateByTemplateName(templateDir, "RoutingModule_Routes", model); + var model = context.GetVariable("Model")!; + var importContents = + TextGenerator.GenerateByTemplateName(TemplateDirectory, "RoutingModule_ImportList", model); + var moduleContents = TextGenerator.GenerateByTemplateName(TemplateDirectory, "RoutingModule_Routes", model); int LineExpression(IEnumerable lines) => lines.Last(l => l.IsMath($"const routes")).LineNumber; @@ -36,7 +41,7 @@ protected override IList>> CreateModif }; } - public RoutingModuleStep([NotNull] TextGenerator textGenerator) : base(textGenerator) + public RoutingModuleStep(TextGenerator textGenerator) : base(textGenerator) { } } diff --git a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/TypeScriptModificationCreatorStep.cs b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/TypeScriptModificationCreatorStep.cs index 3518a60f..7abc1682 100644 --- a/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/TypeScriptModificationCreatorStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ModificationCreatorSteps/Typescript/TypeScriptModificationCreatorStep.cs @@ -1,40 +1,31 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; +using EasyAbp.AbpHelper.Core.Workflow; +using Elsa.ActivityResults; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.Typescript { - public abstract class TypeScriptModificationCreatorStep : Step + public abstract class TypeScriptModificationCreatorStep : CodeModificationStepBase { - protected TextGenerator TextGenerator; - - protected TypeScriptModificationCreatorStep(TextGenerator textGenerator) + protected TypeScriptModificationCreatorStep(TextGenerator textGenerator) : base(textGenerator) { - TextGenerator = textGenerator; } - public WorkflowExpression SourceFile + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); - set => SetState(value); - } + TemplateDirectory ??= context.GetVariable(VariableNames.TemplateDirectory)!; + SourceFile ??= context.GetVariable(FileFinderStep.DefaultFileParameterName)!; - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, - CancellationToken cancellationToken) - { - var file = await context.EvaluateAsync(SourceFile, cancellationToken); - LogInput(() => file); + LogInput(() => TemplateDirectory); + LogInput(() => SourceFile); - var lines = (await File.ReadAllLinesAsync(file, cancellationToken)) + var lines = (await File.ReadAllLinesAsync(SourceFile, context.CancellationToken)) .Select((l, s) => new LineNode(l, s + 1)) ; @@ -46,13 +37,14 @@ protected override async Task OnExecuteAsync(WorkflowEx .ToList() ; - context.SetLastResult(modifications); + context.Output = modifications; context.SetVariable("Modifications", modifications); LogOutput(() => modifications, $"Modifications count: {modifications.Count}"); return Done(); } - protected abstract IList>> CreateModifications(WorkflowExecutionContext context); + protected abstract IList>> CreateModifications( + ActivityExecutionContext context); } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Abp/ParseStep/BaseParserStep.cs b/src/AbpHelper.Core/Steps/Abp/ParseStep/BaseParserStep.cs index 5c995402..5729b6a2 100644 --- a/src/AbpHelper.Core/Steps/Abp/ParseStep/BaseParserStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ParseStep/BaseParserStep.cs @@ -3,14 +3,14 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Common; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -22,24 +22,43 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp.ParseStep { public abstract class BaseParserStep : Step where TType : TypeDeclarationSyntax { - public WorkflowExpression File + [ActivityInput( + Hint = "ProjectInfo", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public ProjectInfo? ProjectInfo { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); + get => GetState(); set => SetState(value); } - public abstract WorkflowExpression OutputVariableName { get; set; } + [ActivityInput( + Hint = "File", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string? File + { + get => GetState(); + set => SetState(value); + } - protected abstract IEnumerable GetMethodInfos(TType typeDeclarationSyntax, INamedTypeSymbol typeSymbol); + public abstract string? OutputVariableName { get; set; } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected abstract IEnumerable GetMethodInfos(TType typeDeclarationSyntax, + INamedTypeSymbol typeSymbol); + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var file = await context.EvaluateAsync(File, cancellationToken); - LogInput(() => file); - string outputVariableName = await context.EvaluateAsync(OutputVariableName, cancellationToken); - LogInput(() => outputVariableName); - var projectInfo = context.GetVariable("ProjectInfo"); - var sourceText = await System.IO.File.ReadAllTextAsync(file, cancellationToken); + File ??= context.GetVariable(FileFinderStep.DefaultFileParameterName)!; + ProjectInfo ??= context.GetVariable("ProjectInfo")!; + + LogInput(() => File); + LogInput(() => ProjectInfo); + LogInput(() => OutputVariableName); + + var sourceText = await System.IO.File.ReadAllTextAsync(File, context.CancellationToken); try { @@ -54,15 +73,15 @@ protected override async Task OnExecuteAsync(WorkflowEx } // Scan "{ProjectInfo.FullName}.*.dll" and "Volo.*.dll", add them to the compilation later - var dlls = Directory.EnumerateFiles(projectInfo.BaseDirectory, "*.dll", SearchOption.AllDirectories) + var dlls = Directory.EnumerateFiles(ProjectInfo.BaseDirectory, "*.dll", SearchOption.AllDirectories) .Where(dll => { string fileName = Path.GetFileName(dll); - return fileName.StartsWith("Volo.") || fileName.StartsWith(projectInfo.FullName); + return fileName.StartsWith("Volo.") || fileName.StartsWith(ProjectInfo.FullName); }) ; // Create compilation of the TType - var compilation = CSharpCompilation.Create(outputVariableName) + var compilation = CSharpCompilation.Create(OutputVariableName) .AddReferences( MetadataReference.CreateFromFile(typeof(object).Assembly.Location) ) @@ -78,11 +97,12 @@ protected override async Task OnExecuteAsync(WorkflowEx .SingleOrDefault(); var usings = root.Descendants().Select(@using => @using.Name.ToString()); - var @namespace = namespaceSyntax?.Name.ToString(); - var relativeDirectory = @namespace.RemovePreFix(projectInfo.FullName + ".").Replace('.', '/'); + var @namespace = namespaceSyntax?.Name.ToString()!; + var relativeDirectory = @namespace.RemovePreFix(ProjectInfo.FullName + ".").Replace('.', '/'); var typeDeclarationSyntax = root.Descendants().Single(); var typeName = typeDeclarationSyntax.Identifier.ToString(); - var attributes = typeDeclarationSyntax.Descendants().Select(attr => attr.ToString()); + var attributes = typeDeclarationSyntax.Descendants() + .Select(attr => attr.ToString()); var model = compilation.GetSemanticModel(tree); var typeSymbol = model.GetDeclaredSymbol(typeDeclarationSyntax)!; var methods = GetMethodInfos(typeDeclarationSyntax, typeSymbol); @@ -92,15 +112,19 @@ protected override async Task OnExecuteAsync(WorkflowEx typeInfo.Attributes.AddRange(attributes); typeInfo.Methods.AddRange(methods); - context.SetLastResult(typeInfo); - context.SetVariable(outputVariableName, typeInfo); + context.Output = typeInfo; + if (OutputVariableName is not null) + { + context.SetVariable(OutputVariableName, typeInfo); + } + LogOutput(() => typeInfo); return Done(); } catch (Exception e) { - Logger.LogError(e, $"Parsing {outputVariableName} failed."); + Logger.LogError(e, $"Parsing {OutputVariableName ?? "???"} failed."); if (e is ParseException pe) foreach (var error in pe.Errors) Logger.LogError(error); diff --git a/src/AbpHelper.Core/Steps/Abp/ParseStep/ClassParserStep.cs b/src/AbpHelper.Core/Steps/Abp/ParseStep/ClassParserStep.cs index c8b8c028..d140d834 100644 --- a/src/AbpHelper.Core/Steps/Abp/ParseStep/ClassParserStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ParseStep/ClassParserStep.cs @@ -2,17 +2,30 @@ using System.Linq; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Models; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ParseStep { + [Activity( + Category = "ClassParserStep", + Description = "ClassParserStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class ClassParserStep : BaseParserStep { - public override WorkflowExpression OutputVariableName + [ActivityInput( + Hint = "OutputVariableName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public override string? OutputVariableName { - get => GetState(() => new LiteralExpression("ClassInfo")); + get => GetState(() => "ClassInfo")!; set => SetState(value); } diff --git a/src/AbpHelper.Core/Steps/Abp/ParseStep/InterfaceParserStep.cs b/src/AbpHelper.Core/Steps/Abp/ParseStep/InterfaceParserStep.cs index 67736d58..ced6801e 100644 --- a/src/AbpHelper.Core/Steps/Abp/ParseStep/InterfaceParserStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ParseStep/InterfaceParserStep.cs @@ -1,21 +1,35 @@ using System.Collections.Generic; using System.Linq; using EasyAbp.AbpHelper.Core.Models; +using Elsa; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace EasyAbp.AbpHelper.Core.Steps.Abp.ParseStep { + [Activity( + Category = "InterfaceParserStep", + Description = "InterfaceParserStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class InterfaceParserStep : BaseParserStep { - public override WorkflowExpression OutputVariableName + [ActivityInput( + Hint = "OutputVariableName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public override string OutputVariableName { - get => GetState(() => new LiteralExpression("InterfaceInfo")); + get => GetState(() => "InterfaceInfo"); set => SetState(value); } - protected override IEnumerable GetMethodInfos(InterfaceDeclarationSyntax typeDeclarationSyntax, INamedTypeSymbol typeSymbol) + protected override IEnumerable GetMethodInfos(InterfaceDeclarationSyntax typeDeclarationSyntax, + INamedTypeSymbol typeSymbol) { return typeSymbol .AllInterfaces diff --git a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs index 1b605f6c..9f257267 100644 --- a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs @@ -1,92 +1,105 @@ using System; using System.IO; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Workflow; -using Elsa.Results; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Abp { + [Activity( + Category = "ProjectInfoProviderStep", + Description = "ProjectInfoProviderStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class ProjectInfoProviderStep : StepWithOption { - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var baseDirectory = await context.EvaluateAsync(BaseDirectory, cancellationToken); - LogInput(() => baseDirectory); - var excludeDirectories = await context.EvaluateAsync(ExcludeDirectories, cancellationToken); - LogInput(() => excludeDirectories, string.Join("; ", excludeDirectories)); + BaseDirectory ??= context.GetVariable(BaseDirectoryVariableName)!; + + LogInput(() => ExcludeDirectories, string.Join("; ", ExcludeDirectories)); + LogInput(() => BaseDirectory); + LogInput(() => Overwrite); TemplateType templateType; - if (FileExistsInDirectory(baseDirectory, "*.Host.Shared.csproj", excludeDirectories)) + if (FileExistsInDirectory(BaseDirectory, "*.Host.Shared.csproj", ExcludeDirectories)) { templateType = TemplateType.Module; - } else if (FileExistsInDirectory(baseDirectory, "*.DbMigrator.csproj", excludeDirectories)) + } + else if (FileExistsInDirectory(BaseDirectory, "*.DbMigrator.csproj", ExcludeDirectories)) { templateType = TemplateType.Application; } else { - throw new NotSupportedException($"Unknown ABP project structure. Directory: {baseDirectory}"); + throw new NotSupportedException($"Unknown ABP project structure. Directory: {BaseDirectory}"); } // Assume the domain project must be existed for an ABP project - var domainCsprojFile = SearchFileInDirectory(baseDirectory, "*.Domain.csproj", excludeDirectories); - if (domainCsprojFile == null) throw new NotSupportedException($"Cannot find the domain project file. Make sure it is a valid ABP project. Directory: {baseDirectory}"); + var domainCsprojFile = SearchFileInDirectory(BaseDirectory, "*.Domain.csproj", ExcludeDirectories); + if (domainCsprojFile == null) + throw new NotSupportedException( + $"Cannot find the domain project file. Make sure it is a valid ABP project. Directory: {BaseDirectory}"); var fileName = Path.GetFileName(domainCsprojFile); var fullName = fileName.RemovePostFix(".Domain.csproj"); UiFramework uiFramework; - if (FileExistsInDirectory(baseDirectory, "*.cshtml", excludeDirectories)) + if (FileExistsInDirectory(BaseDirectory, "*.cshtml", ExcludeDirectories)) { uiFramework = UiFramework.RazorPages; } - else if (FileExistsInDirectory(baseDirectory, "app.module.ts", excludeDirectories)) + else if (FileExistsInDirectory(BaseDirectory, "app.module.ts", ExcludeDirectories)) { uiFramework = UiFramework.Angular; } else { uiFramework = UiFramework.None; - } - string aspNetCoreDir = Path.Combine(baseDirectory, "aspnet-core"); + var aspNetCoreDir = Path.Combine(BaseDirectory, "aspnet-core"); if (Directory.Exists(aspNetCoreDir)) { context.SetVariable(VariableNames.AspNetCoreDir, aspNetCoreDir); } else { - context.SetVariable(VariableNames.AspNetCoreDir, baseDirectory); + context.SetVariable(VariableNames.AspNetCoreDir, BaseDirectory); } + EnsureSlnFileExists(context, fullName); var tiered = false; if (templateType == TemplateType.Application) { - tiered = FileExistsInDirectory(baseDirectory, "*.IdentityServer.csproj", excludeDirectories); + tiered = FileExistsInDirectory(BaseDirectory, "*.IdentityServer.csproj", ExcludeDirectories); } - var projectInfo = new ProjectInfo(baseDirectory, fullName, templateType, uiFramework, tiered); + var projectInfo = new ProjectInfo(BaseDirectory, fullName, templateType, uiFramework, tiered); - context.SetLastResult(projectInfo); + context.Output = projectInfo; context.SetVariable("ProjectInfo", projectInfo); LogOutput(() => projectInfo); return Done(); } - private void EnsureSlnFileExists(WorkflowExecutionContext context, string projectName) + private void EnsureSlnFileExists(ActivityExecutionContext context, string projectName) { - string aspNetCoreDir = context.GetVariable(VariableNames.AspNetCoreDir); - string slnFile = Path.Combine(aspNetCoreDir, $"{projectName}.sln"); + var aspNetCoreDir = context.GetVariable(VariableNames.AspNetCoreDir)!; + var slnFile = Path.Combine(aspNetCoreDir, $"{projectName}.sln"); if (!File.Exists(slnFile)) { - throw new FileNotFoundException($"The solution file '{projectName}.sln' is not found in '{aspNetCoreDir}'. Make sure you specific the right folder."); + throw new FileNotFoundException( + $"The solution file '{projectName}.sln' is not found in '{aspNetCoreDir}'. Make sure you specific the right folder."); } } } -} +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs b/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs index a6730463..39a94301 100644 --- a/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs @@ -2,30 +2,37 @@ using System.Collections.Generic; using System.Dynamic; using System.Linq; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Models; -using Elsa.Results; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Abp { + [Activity( + Category = "SetModelVariableStep", + Description = "SetModelVariableStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class SetModelVariableStep : Step { - protected override Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var projectInfo = context.GetVariable("ProjectInfo"); - var option = context.GetVariable("Option"); - var entityInfo = context.GetVariable("EntityInfo"); - var interfaceInfo = context.GetVariable("InterfaceInfo"); - var classInfo = context.GetVariable("ClassInfo"); - var dtoInfo = context.GetVariable("DtoInfo"); - var variables = context.GetVariables().Where(v => v.Key.StartsWith("Bag.")); + var projectInfo = context.GetVariable("ProjectInfo"); + var option = context.GetVariable("Option"); + var entityInfo = context.GetVariable("EntityInfo"); + var interfaceInfo = context.GetVariable("InterfaceInfo"); + var classInfo = context.GetVariable("ClassInfo"); + var dtoInfo = context.GetVariable("DtoInfo"); + var variables = context.WorkflowExecutionContext.GetMergedVariables().Data + .Where(v => v.Key.StartsWith("Bag.")); var bag = new ExpandoObject(); foreach (var variable in variables) { - ((IDictionary) bag)[variable.Key.RemovePreFix("Bag.")] = variable.Value.Value; + ((IDictionary) bag)[variable.Key.RemovePreFix("Bag.")] = variable.Value; } context.SetVariable("Model", new @@ -37,9 +44,9 @@ protected override Task OnExecuteAsync(WorkflowExecutio ClassInfo = classInfo, Bag = bag, DtoInfo = dtoInfo, - });; + }); - return Task.FromResult(Done()); + return new ValueTask(Done()); } } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Common/DirectoryFinderStep.cs b/src/AbpHelper.Core/Steps/Common/DirectoryFinderStep.cs index 26044749..454d7d14 100644 --- a/src/AbpHelper.Core/Steps/Common/DirectoryFinderStep.cs +++ b/src/AbpHelper.Core/Steps/Common/DirectoryFinderStep.cs @@ -1,41 +1,59 @@ -using System.Threading; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "DirectoryFinderStep", + Description = "DirectoryFinderStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class DirectoryFinderStep : StepWithOption { public const string DefaultDirectoryParameterName = "DirectoryFinderResult"; + [ActivityInput( + Hint = "SearchDirectoryName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] public string SearchDirectoryName { - get => GetState(); + get => GetState()!; set => SetState(value); } - public WorkflowExpression ResultVariableName + [ActivityInput( + Hint = "ResultVariableName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string ResultVariableName { - get => GetState(() => new LiteralExpression(DefaultDirectoryParameterName)); + get => GetState(() => DefaultDirectoryParameterName); set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var baseDirectory = await context.EvaluateAsync(BaseDirectory, cancellationToken); - LogInput(() => baseDirectory); - var excludeDirectories = await context.EvaluateAsync(ExcludeDirectories, cancellationToken); - LogInput(() => excludeDirectories, string.Join("; ", excludeDirectories)); - LogInput(() => SearchDirectoryName); - var resultParameterName = await context.EvaluateAsync(ResultVariableName, cancellationToken); + BaseDirectory ??= context.GetVariable(BaseDirectoryVariableName)!; + LogInput(() => SearchDirectoryName); + LogInput(() => ResultVariableName); + LogInput(() => ExcludeDirectories, string.Join("; ", ExcludeDirectories)); + LogInput(() => BaseDirectory); + LogInput(() => Overwrite); - var directoryPathName = SearchDirectoryInDirectory(baseDirectory, SearchDirectoryName, excludeDirectories); - context.SetLastResult(directoryPathName); - context.SetVariable(resultParameterName, directoryPathName); - LogOutput(() => directoryPathName, $"Found directory: {directoryPathName}, stored in parameter: [{ResultVariableName}]"); + var directoryPathName = SearchDirectoryInDirectory(BaseDirectory, SearchDirectoryName, ExcludeDirectories); + context.Output = directoryPathName; + context.SetVariable(ResultVariableName, directoryPathName); + LogOutput(() => directoryPathName, + $"Found directory: {directoryPathName}, stored in parameter: [{ResultVariableName}]"); return Done(); } diff --git a/src/AbpHelper.Core/Steps/Common/EmptyStep.cs b/src/AbpHelper.Core/Steps/Common/EmptyStep.cs index 391c37fa..f533565b 100644 --- a/src/AbpHelper.Core/Steps/Common/EmptyStep.cs +++ b/src/AbpHelper.Core/Steps/Common/EmptyStep.cs @@ -1,4 +1,6 @@ -using Elsa.Results; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Common @@ -7,9 +9,14 @@ namespace EasyAbp.AbpHelper.Core.Steps.Common /// This is an empty step. /// It can be used as a label, or it can convert `IOutcomeBuilder` to `IActivityBuilder` when writing fluent steps in a workflow, /// + [Activity( + Category = "EmptyStep", + Description = "EmptyStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class EmptyStep : Step { - protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext context) + protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) { return Done(); } diff --git a/src/AbpHelper.Core/Steps/Common/FileFinderStep.cs b/src/AbpHelper.Core/Steps/Common/FileFinderStep.cs index 45151aca..4a17fbce 100644 --- a/src/AbpHelper.Core/Steps/Common/FileFinderStep.cs +++ b/src/AbpHelper.Core/Steps/Common/FileFinderStep.cs @@ -1,65 +1,88 @@ -using System.IO; +using System; +using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "FileFinderStep", + Description = "FileFinderStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class FileFinderStep : StepWithOption { public const string DefaultFileParameterName = "FileFinderResult"; - public WorkflowExpression SearchFileName + [ActivityInput( + Hint = "SearchFileName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string SearchFileName { - get => GetState>(); + get => GetState()!; set => SetState(value); } - public WorkflowExpression ResultVariableName + [ActivityInput( + Hint = "ResultVariableName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string ResultVariableName { - get => GetState(() => new LiteralExpression(DefaultFileParameterName)); + get => GetState(() => DefaultFileParameterName); set => SetState(value); } - public WorkflowExpression ErrorIfNotFound + [ActivityInput( + Hint = "ErrorIfNotFound", + UIHint = ActivityInputUIHints.Checkbox, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public bool ErrorIfNotFound { - get => GetState(() => new JavaScriptExpression("true")); + get => GetState(() => true); set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var resultVariableName = await context.EvaluateAsync(ResultVariableName, cancellationToken); - var baseDirectory = await context.EvaluateAsync(BaseDirectory, cancellationToken); - LogInput(() => baseDirectory); - var excludeDirectories = await context.EvaluateAsync(ExcludeDirectories, cancellationToken); - LogInput(() => excludeDirectories, string.Join("; ", excludeDirectories)); - var searchFileName = await context.EvaluateAsync(SearchFileName, cancellationToken); - LogInput(() => searchFileName); - var errorIfNotFound = await context.EvaluateAsync(ErrorIfNotFound, cancellationToken); - LogInput(() => errorIfNotFound); + BaseDirectory ??= context.GetVariable(BaseDirectoryVariableName)!; - var files = SearchFilesInDirectory(baseDirectory, searchFileName, excludeDirectories); + LogInput(() => SearchFileName); + LogInput(() => ResultVariableName); + LogInput(() => ErrorIfNotFound); + LogInput(() => ExcludeDirectories, string.Join("; ", ExcludeDirectories)); + LogInput(() => BaseDirectory); + LogInput(() => Overwrite); + + var files = SearchFilesInDirectory(BaseDirectory, SearchFileName, ExcludeDirectories); var filePathName = files.SingleOrDefault(); - context.SetLastResult(filePathName); - context.SetVariable(resultVariableName, filePathName); + context.Output = filePathName ?? string.Empty; + context.SetVariable(ResultVariableName, filePathName); if (filePathName == null) { - if (errorIfNotFound) throw new FileNotFoundException(searchFileName); - LogOutput(() => filePathName, $"File: '{filePathName}' not found, stored 'null' in parameter: '{ResultVariableName}'"); + if (ErrorIfNotFound) throw new FileNotFoundException(SearchFileName); + LogOutput(() => filePathName, + $"File: '{filePathName}' not found, stored 'null' in parameter: '{ResultVariableName}'"); } else { - LogOutput(() => filePathName, $"Found file: '{filePathName}', stored in parameter: '{ResultVariableName}'"); + LogOutput(() => filePathName, + $"Found file: '{filePathName}', stored in parameter: '{ResultVariableName}'"); } - return Done(); + return Done(filePathName); } } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Common/FileGenerationStep.cs b/src/AbpHelper.Core/Steps/Common/FileGenerationStep.cs index a2b619c5..0de4985f 100644 --- a/src/AbpHelper.Core/Steps/Common/FileGenerationStep.cs +++ b/src/AbpHelper.Core/Steps/Common/FileGenerationStep.cs @@ -1,44 +1,58 @@ using System.IO; -using System.Threading; using System.Threading.Tasks; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Microsoft.Extensions.Logging; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "FileGenerationStep", + Description = "FileGenerationStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class FileGenerationStep : Step { - public WorkflowExpression TargetFile + [ActivityInput( + Hint = "TargetFile", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string TargetFile { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); + get => GetState()!; set => SetState(value); } + [ActivityInput( + Hint = "Contents", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] public string Contents { - get => GetState(); + get => GetState()!; set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var targetFile = await context.EvaluateAsync(TargetFile, cancellationToken); - - LogInput(() => targetFile); + LogInput(() => TargetFile); LogInput(() => Contents, $"Contents length: {Contents.Length}"); - var dir = Path.GetDirectoryName(targetFile); + var dir = Path.GetDirectoryName(TargetFile)!; if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); Logger.LogInformation($"Directory {dir} created."); } - await File.WriteAllTextAsync(targetFile, Contents); - Logger.LogInformation($"File {targetFile} generated."); + await File.WriteAllTextAsync(TargetFile, Contents); + Logger.LogInformation($"File {TargetFile} generated."); return Done(); } diff --git a/src/AbpHelper.Core/Steps/Common/FileModifierStep.cs b/src/AbpHelper.Core/Steps/Common/FileModifierStep.cs index 225b4df7..27c53e8b 100644 --- a/src/AbpHelper.Core/Steps/Common/FileModifierStep.cs +++ b/src/AbpHelper.Core/Steps/Common/FileModifierStep.cs @@ -3,50 +3,69 @@ using System.IO; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Models; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Microsoft.Extensions.Logging; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "FileModifierStep", + Description = "FileModifierStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class FileModifierStep : Step { - public WorkflowExpression TargetFile + [ActivityInput( + Hint = "TargetFile", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string? TargetFile { - get => GetState(() => new JavaScriptExpression(FileFinderStep.DefaultFileParameterName)); + get => GetState(); set => SetState(value); } - public WorkflowExpression> Modifications + [ActivityInput( + Hint = "Modifications", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public IList? Modifications { - get => GetState(() => new JavaScriptExpression>("Modifications")); + get => GetState?>(); set => SetState(value); } - public WorkflowExpression NewLine + [ActivityInput( + Hint = "NewLine", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string NewLine { - get => GetState(() => new LiteralExpression("\r\n")); + get => GetState(() => "\r\n"); set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var targetFile = await context.EvaluateAsync(TargetFile, cancellationToken); - LogInput(() => targetFile); - - var modifications = await context.EvaluateAsync(Modifications, cancellationToken); - LogInput(() => modifications, $"Modifications count: {modifications.Count}"); - - var newLine = await context.EvaluateAsync(NewLine, cancellationToken); - - var lines = await File.ReadAllLinesAsync(targetFile); - var errors = CheckModifications(modifications, lines).ToArray(); + TargetFile ??= context.GetVariable(FileFinderStep.DefaultFileParameterName)!; + Modifications ??= context.GetVariable>("Modifications")!; + + LogInput(() => TargetFile); + LogInput(() => Modifications, $"Modifications count: {Modifications.Count}"); + + var lines = await File.ReadAllLinesAsync(TargetFile); + var errors = CheckModifications(Modifications, lines).ToArray(); if (errors.Length > 0) { foreach (var error in errors) Logger.LogError(error); @@ -60,7 +79,7 @@ protected override async Task OnExecuteAsync(WorkflowEx for (var line = 1; line <= lines.Length; line++) { var lineText = lines[line - 1]; - var lineModifications = modifications + var lineModifications = Modifications .Where(mod => mod.StartLine == line || // Positive line number mod.StartLine == line - lines.Length - 1 // Negative line number ) @@ -87,15 +106,15 @@ protected override async Task OnExecuteAsync(WorkflowEx } // We don't need these modifications anymore - foreach (var modification in lineModifications) modifications.Remove(modification); + foreach (var modification in lineModifications) Modifications.Remove(modification); newFile.AppendWithControlChar(beforeContents) - .AppendLineWithControlChar(lineText, newLine) + .AppendLineWithControlChar(lineText, NewLine) .AppendWithControlChar(afterContents); NEXT_LINE: ; } - await File.WriteAllTextAsync(targetFile, newFile.ToString()); + await File.WriteAllTextAsync(TargetFile, newFile.ToString()); return Done(); } @@ -121,16 +140,23 @@ private static IEnumerable CheckLinesInRange(IList modific // Check StartLine and EndLine are in range foreach (var modification in modifications) { - var actualStartLine = modification.StartLine >= 0 ? modification.StartLine : lines.Length + modification.StartLine; + var actualStartLine = modification.StartLine >= 0 + ? modification.StartLine + : lines.Length + modification.StartLine; - if (actualStartLine <= 0 || actualStartLine > lines.Length) yield return $"StartLine out of range: {modification}. {nameof(actualStartLine)}: {actualStartLine}"; + if (actualStartLine <= 0 || actualStartLine > lines.Length) + yield return + $"StartLine out of range: {modification}. {nameof(actualStartLine)}: {actualStartLine}"; if (modification is IRange range) { var actualEndLine = range.EndLine >= 0 ? range.EndLine : lines.Length + range.EndLine; - if (actualEndLine <= 0 || actualEndLine > lines.Length) yield return $"EndLine out of range: {modification}. {nameof(actualEndLine)}: {actualEndLine}"; + if (actualEndLine <= 0 || actualEndLine > lines.Length) + yield return $"EndLine out of range: {modification}. {nameof(actualEndLine)}: {actualEndLine}"; - if (actualStartLine > actualEndLine) yield return $"StartLine grater than EndLine: {modification}. {nameof(actualStartLine)}: {actualStartLine} {nameof(actualEndLine)}: {actualEndLine}"; + if (actualStartLine > actualEndLine) + yield return + $"StartLine grater than EndLine: {modification}. {nameof(actualStartLine)}: {actualStartLine} {nameof(actualEndLine)}: {actualEndLine}"; } } } @@ -167,6 +193,6 @@ public InvalidModificationException(IEnumerable errors) Errors.AddRange(errors); } - public List Errors { get; } = new List(); + public List Errors { get; } = new(); } } \ No newline at end of file diff --git a/src/AbpHelper.Core/Steps/Common/GroupGenerationStep.cs b/src/AbpHelper.Core/Steps/Common/GroupGenerationStep.cs index 60d764a7..90a18d84 100644 --- a/src/AbpHelper.Core/Steps/Common/GroupGenerationStep.cs +++ b/src/AbpHelper.Core/Steps/Common/GroupGenerationStep.cs @@ -1,12 +1,13 @@ using System.IO; -using System.Threading; using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Extensions; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; @@ -16,39 +17,58 @@ namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "GroupGenerationStep", + Description = "GroupGenerationStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class GroupGenerationStep : Step { private readonly TextGenerator _textGenerator; private readonly IVirtualFileProvider _virtualFileProvider; private const string SkipGenerate = "SKIP_GENERATE"; - public WorkflowExpression TemplateDirectory + [ActivityInput( + Hint = "TemplateDirectory", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? TemplateDirectory { - get => GetState>(() => new JavaScriptExpression(VariableNames.TemplateDirectory)); + get => GetState(); set => SetState(value); } + [ActivityInput( + Hint = "GroupName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] public string GroupName { - get => GetState(); + get => GetState()!; set => SetState(value); } - public WorkflowExpression TargetDirectory + [ActivityInput( + Hint = "TargetDirectory", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? TargetDirectory { - get => GetState(() => new JavaScriptExpression("BaseDirectory")); + get => GetState(); set => SetState(value); } - public WorkflowExpression Overwrite + [ActivityInput( + Hint = "Overwrite", + UIHint = ActivityInputUIHints.Checkbox, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public bool? Overwrite { - get => GetState(() => new JavaScriptExpression("Overwrite")); - set => SetState(value); - } - - public WorkflowExpression Model - { - get => GetState>(() => new JavaScriptExpression("Model")); + get => GetState(); set => SetState(value); } @@ -60,20 +80,20 @@ public GroupGenerationStep( _virtualFileProvider = virtualFileProvider; } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - string templateDir = await context.EvaluateAsync(TemplateDirectory, cancellationToken); - LogInput(() => templateDir); + TemplateDirectory ??= context.GetVariable(VariableNames.TemplateDirectory)!; + TargetDirectory ??= context.GetVariable("BaseDirectory")!; + Overwrite ??= context.GetVariable("Overwrite")!; + LogInput(() => GroupName); - var targetDirectory = await context.EvaluateAsync(TargetDirectory, cancellationToken); - LogInput(() => targetDirectory); - var overwrite = await context.EvaluateAsync(Overwrite, cancellationToken); + LogInput(() => TemplateDirectory); + LogInput(() => TargetDirectory); LogInput(() => Overwrite); - var model = await context.EvaluateAsync(Model, cancellationToken); - LogInput(() => model); - var groupDir = Path.Combine(templateDir, "Groups", GroupName).NormalizePath(); - await GenerateFile(groupDir, targetDirectory, model, overwrite); + var groupDir = Path.Combine(TemplateDirectory, "Groups", GroupName).NormalizePath(); + + await GenerateFile(groupDir, TargetDirectory, context.GetVariable("Model")!, Overwrite.Value); return Done(); } @@ -94,8 +114,8 @@ private async Task GenerateFile(string groupDirectory, string targetDirectory, o var templateText = await file.ReadAsStringAsync(); var contents = _textGenerator.GenerateByTemplateText(templateText, model, out TemplateContext context); - context.CurrentGlobal.TryGetValue(SkipGenerate, out object value); - if (value is bool skipGenerate && skipGenerate) + context.CurrentGlobal.TryGetValue(SkipGenerate, out var value); + if (value is true) { Logger.LogInformation($"Evaluated value of `{SkipGenerate}` is true, skip generating."); continue; diff --git a/src/AbpHelper.Core/Steps/Common/MultiFilesFinderStep.cs b/src/AbpHelper.Core/Steps/Common/MultiFilesFinderStep.cs index e6f81c09..a09dadb9 100644 --- a/src/AbpHelper.Core/Steps/Common/MultiFilesFinderStep.cs +++ b/src/AbpHelper.Core/Steps/Common/MultiFilesFinderStep.cs @@ -1,45 +1,62 @@ using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "MultiFileFinderStep", + Description = "MultiFileFinderStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class MultiFileFinderStep : StepWithOption { public const string DefaultFileParameterName = "MultiFilesFinderResult"; - public WorkflowExpression SearchFileName + [ActivityInput( + Hint = "SearchFileName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string SearchFileName { - get => GetState>(); + get => GetState()!; set => SetState(value); } - public WorkflowExpression ResultVariableName + [ActivityInput( + Hint = "ResultVariableName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string ResultVariableName { - get => GetState(() => new LiteralExpression(DefaultFileParameterName)); + get => GetState(() => DefaultFileParameterName); set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var baseDirectory = await context.EvaluateAsync(BaseDirectory, cancellationToken); - LogInput(() => baseDirectory); - var excludeDirectories = await context.EvaluateAsync(ExcludeDirectories, cancellationToken); - LogInput(() => excludeDirectories, string.Join("; ", excludeDirectories)); - var searchFileName = await context.EvaluateAsync(SearchFileName, cancellationToken); + BaseDirectory ??= context.GetVariable(BaseDirectoryVariableName)!; + LogInput(() => SearchFileName); - var resultParameterName = await context.EvaluateAsync(ResultVariableName, cancellationToken); + LogInput(() => ResultVariableName); + LogInput(() => ExcludeDirectories, string.Join("; ", ExcludeDirectories)); + LogInput(() => BaseDirectory); + LogInput(() => Overwrite); - var files = SearchFilesInDirectory(baseDirectory, searchFileName, excludeDirectories).ToArray(); + var files = SearchFilesInDirectory(BaseDirectory, SearchFileName, ExcludeDirectories).ToArray(); if (files.Length == 0) throw new FileNotFoundException(); - context.SetLastResult(files); - context.SetVariable(resultParameterName, files); + context.Output = files; + context.SetVariable(ResultVariableName, files); LogOutput(() => files, $"Found files count: {files.Length}, stored in parameter: '{ResultVariableName}'"); return Done(); diff --git a/src/AbpHelper.Core/Steps/Common/RunCommandStep.cs b/src/AbpHelper.Core/Steps/Common/RunCommandStep.cs index 5e536cd5..f27ea0f4 100644 --- a/src/AbpHelper.Core/Steps/Common/RunCommandStep.cs +++ b/src/AbpHelper.Core/Steps/Common/RunCommandStep.cs @@ -1,28 +1,39 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Threading; using System.Threading.Tasks; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; using Elsa.Services.Models; using Microsoft.Extensions.Logging; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "RunCommandStep", + Description = "RunCommandStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class RunCommandStep : Step { - public WorkflowExpression Command + [ActivityInput( + Hint = "Command", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string Command { - get => GetState>(); + get => GetState()!; set => SetState(value); } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var command = await context.EvaluateAsync(Command, cancellationToken); - LogInput(() => command); - var exitCode = RunCommand(command); + LogInput(() => Command); + var exitCode = RunCommand(Command); if (exitCode != 0) throw new RunningCommandFailedException(exitCode); return Done(); @@ -30,31 +41,30 @@ protected override async Task OnExecuteAsync(WorkflowEx private int RunCommand(string command) { - using (var process = new Process()) + using var process = new Process(); + + process.StartInfo = new ProcessStartInfo(GetFileName()) + { + Arguments = GetArguments(command), + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + process.OutputDataReceived += (sender, args) => { - process.StartInfo = new ProcessStartInfo(GetFileName()) - { - Arguments = GetArguments(command), - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardOutput = true, - RedirectStandardError = true - }; - process.OutputDataReceived += (sender, args) => - { - if (!args.Data.IsNullOrEmpty()) Logger.LogDebug(args.Data); - }; - process.ErrorDataReceived += (sender, args) => - { - if (!args.Data.IsNullOrEmpty()) Logger.LogError(args.Data); - }; + if (!args.Data.IsNullOrEmpty()) Logger.LogDebug(args.Data); + }; + process.ErrorDataReceived += (sender, args) => + { + if (!args.Data.IsNullOrEmpty()) Logger.LogError(args.Data); + }; - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - process.WaitForExit(); - return process.ExitCode; - } + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + return process.ExitCode; } /// @@ -64,7 +74,8 @@ private int RunCommand(string command) /// public static string GetArguments(string command) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return "-c \"" + command + "\""; + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + return "-c \"" + command + "\""; //Windows default. return "/C \"" + command + "\""; diff --git a/src/AbpHelper.Core/Steps/Common/TextGenerationStep.cs b/src/AbpHelper.Core/Steps/Common/TextGenerationStep.cs index 45358d03..1c935057 100644 --- a/src/AbpHelper.Core/Steps/Common/TextGenerationStep.cs +++ b/src/AbpHelper.Core/Steps/Common/TextGenerationStep.cs @@ -1,40 +1,55 @@ -using System.Threading; -using System.Threading.Tasks; +using System.Threading.Tasks; using EasyAbp.AbpHelper.Core.Generator; using EasyAbp.AbpHelper.Core.Workflow; +using Elsa; +using Elsa.ActivityResults; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Results; -using Elsa.Scripting.JavaScript; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Common { + [Activity( + Category = "TextGenerationStep", + Description = "TextGenerationStep", + Outcomes = new[] { OutcomeNames.Done } + )] public class TextGenerationStep : Step { private readonly TextGenerator _textGenerator; public const string DefaultGeneratedTextParameterName = "GeneratedText"; - public WorkflowExpression TemplateDirectory + [ActivityInput( + Hint = "TemplateDirectory", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string? TemplateDirectory { - get => GetState>(() => new JavaScriptExpression(VariableNames.TemplateDirectory)); - set => SetState(value); - } - - public string TemplateName - { - get => GetState(); + get => GetState(); set => SetState(value); } - public WorkflowExpression Model + [ActivityInput( + Hint = "TemplateName", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public string TemplateName { - get => GetState>(() => new JavaScriptExpression("Model")); + get => GetState()!; set => SetState(value); } - public WorkflowExpression GeneratedTextKey + [ActivityInput( + Hint = "GeneratedTextKey", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string GeneratedTextKey { - get => GetState(() => new LiteralExpression(DefaultGeneratedTextParameterName)); + get => GetState(() => DefaultGeneratedTextParameterName); set => SetState(value); } @@ -43,20 +58,19 @@ public TextGenerationStep(TextGenerator textGenerator) _textGenerator = textGenerator; } - protected override async Task OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { - string templateDir = await context.EvaluateAsync(TemplateDirectory, cancellationToken); - LogInput(() => templateDir); + TemplateDirectory ??= context.GetVariable(VariableNames.TemplateDirectory)!; + + LogInput(() => TemplateDirectory); LogInput(() => TemplateName); - var model = await context.EvaluateAsync(Model, cancellationToken); - LogInput(() => model); - var generatedTextKey = await context.EvaluateAsync(GeneratedTextKey, cancellationToken); LogInput(() => GeneratedTextKey); - var text = _textGenerator.GenerateByTemplateName(templateDir, TemplateName, model); + var text = _textGenerator.GenerateByTemplateName(TemplateDirectory, TemplateName, + context.GetVariable("Model")!); - context.SetLastResult(text); - context.SetVariable(generatedTextKey, text); + context.Output = text; + context.SetVariable(GeneratedTextKey, text); LogOutput(() => text, $"Length: {text.Length}"); return Done(); diff --git a/src/AbpHelper.Core/Steps/StepWithOption.cs b/src/AbpHelper.Core/Steps/StepWithOption.cs index 113a487e..4f3fde77 100644 --- a/src/AbpHelper.Core/Steps/StepWithOption.cs +++ b/src/AbpHelper.Core/Steps/StepWithOption.cs @@ -3,39 +3,55 @@ using System.IO; using System.Linq; using EasyAbp.AbpHelper.Core.Commands; +using Elsa.Attributes; +using Elsa.Design; using Elsa.Expressions; -using Elsa.Scripting.JavaScript; namespace EasyAbp.AbpHelper.Core.Steps { public abstract class StepWithOption : Step { - private static readonly Dictionary> ExcludeDirectorySearchCache = new Dictionary>(); + private static readonly Dictionary> ExcludeDirectorySearchCache = new(); - protected virtual string OptionVariableName => CommandConsts.OptionVariableName; - protected virtual string BaseDirectoryVariableName => CommandConsts.BaseDirectoryVariableName; protected virtual string ExcludeDirectoriesVariableName => CommandConsts.ExcludeDirectoriesVariableName; + protected virtual string BaseDirectoryVariableName => CommandConsts.BaseDirectoryVariableName; protected virtual string OverwriteVariableName => CommandConsts.OverwriteVariableName; - - public WorkflowExpression ExcludeDirectories + + [ActivityInput( + Hint = "ExcludeDirectories", + UIHint = ActivityInputUIHints.MultiLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string[] ExcludeDirectories { - get => GetState(() => new JavaScriptExpression(ExcludeDirectoriesVariableName)); + get => GetState() ?? Array.Empty(); set => SetState(value); } - public WorkflowExpression BaseDirectory + [ActivityInput( + Hint = "BaseDirectory", + UIHint = ActivityInputUIHints.SingleLine, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public string? BaseDirectory { - get => GetState(() => new JavaScriptExpression(BaseDirectoryVariableName)); + get => GetState(); set => SetState(value); } - public WorkflowExpression CommandOption + [ActivityInput( + Hint = "Overwrite", + UIHint = ActivityInputUIHints.Checkbox, + SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript } + )] + public bool Overwrite { - get => GetState(() => new JavaScriptExpression(OverwriteVariableName)); + get => GetState(); set => SetState(value); } - protected virtual bool FileExistsInDirectory(string directory, string pattern, params string[] excludedDirectories) + protected virtual bool FileExistsInDirectory(string directory, string pattern, + params string[] excludedDirectories) { return !SearchFileInDirectory(directory, pattern, excludedDirectories).IsNullOrWhiteSpace(); } @@ -69,10 +85,12 @@ protected virtual IEnumerable SearchFilesInDirectory(string directory, s GetExcludedDirectorySearchCacheKey(directory, excludedDirectories), () => GetDirectoryFullPath(directory, excludedDirectories)); - return SearchInDirectoryRecursive(directory, pattern, new HashSet(excludedDirectories), Directory.EnumerateFiles); + return SearchInDirectoryRecursive(directory, pattern, new HashSet(excludedDirectories), + Directory.EnumerateFiles); } - private IEnumerable SearchInDirectoryRecursive(string directory, string pattern, HashSet actualExcluded, Func> searchFunc) + private IEnumerable SearchInDirectoryRecursive(string directory, string pattern, + HashSet actualExcluded, Func> searchFunc) { foreach (var result in searchFunc(directory, pattern, SearchOption.TopDirectoryOnly)) { @@ -94,7 +112,8 @@ private IEnumerable SearchInDirectoryRecursive(string directory, string } } - private string? FindInDirectoryRecursive(string directory, string pattern, HashSet actualExcluded, Func> searchFunc) + private string? FindInDirectoryRecursive(string directory, string pattern, HashSet actualExcluded, + Func> searchFunc) { var result = searchFunc(directory, pattern, SearchOption.TopDirectoryOnly).FirstOrDefault(); if (!result.IsNullOrWhiteSpace()) @@ -139,8 +158,8 @@ private IReadOnlyList GetDirectoryFullPath(string directory, string[] pa } foreach (var d in Directory - .GetDirectories(directory, p, - all ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) + .GetDirectories(directory, p, + all ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { list.Add(d); } diff --git a/src/AbpHelper.Core/Templates/Crud/Groups/UiRazor/src/{{ProjectInfo.FullName}}.Web/Pages/{{Bag.PagesFolder}}/{{EntityInfo.RelativeDirectory}}/{{EntityInfo.Name}}/Index.cshtml b/src/AbpHelper.Core/Templates/Crud/Groups/UiRazor/src/{{ProjectInfo.FullName}}.Web/Pages/{{Bag.PagesFolder}}/{{EntityInfo.RelativeDirectory}}/{{EntityInfo.Name}}/Index.cshtml index 18d30d2f..3e32aef6 100644 --- a/src/AbpHelper.Core/Templates/Crud/Groups/UiRazor/src/{{ProjectInfo.FullName}}.Web/Pages/{{Bag.PagesFolder}}/{{EntityInfo.RelativeDirectory}}/{{EntityInfo.Name}}/Index.cshtml +++ b/src/AbpHelper.Core/Templates/Crud/Groups/UiRazor/src/{{ProjectInfo.FullName}}.Web/Pages/{{Bag.PagesFolder}}/{{EntityInfo.RelativeDirectory}}/{{EntityInfo.Name}}/Index.cshtml @@ -3,6 +3,9 @@ @using {{ ProjectInfo.FullName }}.Permissions {{~ end ~}} {{~ if Bag.PagesFolder; pagesNamespace = Bag.PagesFolder + "."; end ~}} +@using System.CommandLine +@using System.Net +@using EasyAbp.AbpHelper.Core.Models @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout diff --git a/src/AbpHelper.Core/Workflow/Common/ConfigureFindDbContextWorkflow.cs b/src/AbpHelper.Core/Workflow/Common/ConfigureFindDbContextWorkflow.cs index 26bf8746..5ecf534e 100644 --- a/src/AbpHelper.Core/Workflow/Common/ConfigureFindDbContextWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Common/ConfigureFindDbContextWorkflow.cs @@ -1,38 +1,49 @@ -using EasyAbp.AbpHelper.Core.Steps.Common; +using EasyAbp.AbpHelper.Core.Models; +using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Common { public static class ConfigureFindDbContextWorkflow { - public static IActivityBuilder AddConfigureFindDbContextWorkflow(this IActivityBuilder builder, string nextActivityName) + public static IActivityBuilder AddConfigureFindDbContextWorkflow(this IActivityBuilder builder, + string nextActivityName) { return builder - .AddConfigureHasDbMigrationsWorkflow("FindDbContext") - .Then( - ifElse => ifElse.ConditionExpression = new JavaScriptExpression(VariableNames.HasDbMigrations), - ifElse => - { - ifElse - .When(OutcomeNames.True) - .Then( - step => { step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}MigrationsDbContext.cs`"); } - ) - .Then(nextActivityName) + .AddConfigureHasDbMigrationsWorkflow("FindDbContext") + .Then( + ifElse => ifElse.Set(x => x.Condition, x => x.GetVariable(VariableNames.HasDbMigrations)), + ifElse => + { + ifElse + .When(OutcomeNames.True) + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}MigrationsDbContext.cs"; + }); + }) + .ThenNamed(nextActivityName) ; - ifElse - .When(OutcomeNames.False) - .Then( - step => { step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}DbContext.cs`"); } - ) - .Then(nextActivityName) + ifElse + .When(OutcomeNames.False) + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}DbContext.cs"; + }); + }) + .ThenNamed(nextActivityName) ; - } - ).WithName("FindDbContext"); + } + ).WithName("FindDbContext"); ; } } -} +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Workflow/Common/ConfigureHasDbMigrationsWorkflow.cs b/src/AbpHelper.Core/Workflow/Common/ConfigureHasDbMigrationsWorkflow.cs index f35ed345..465c8c23 100644 --- a/src/AbpHelper.Core/Workflow/Common/ConfigureHasDbMigrationsWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Common/ConfigureHasDbMigrationsWorkflow.cs @@ -1,13 +1,9 @@ -using EasyAbp.AbpHelper.Core.Commands; -using EasyAbp.AbpHelper.Core.Commands.Generate.Crud; -using EasyAbp.AbpHelper.Core.Models; +using System; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Common { @@ -15,36 +11,37 @@ public static class ConfigureHasDbMigrationsWorkflow { private const string SearchDbMigrationsResultName = nameof(SearchDbMigrationsResultName); - public static IActivityBuilder AddConfigureHasDbMigrationsWorkflow(this IActivityBuilder builder, string nextActivityName) + public static IActivityBuilder AddConfigureHasDbMigrationsWorkflow(this IActivityBuilder builder, + string nextActivityName) { return builder - .Then( - step => { - step.SearchFileName = new LiteralExpression("*.EntityFrameworkCore.DbMigrations.csproj"); - step.ErrorIfNotFound = new JavaScriptExpression("false"); + .Then(step => + { + step.Set(x => x.SearchFileName, "*.EntityFrameworkCore.DbMigrations.csproj"); + step.Set(x => x.ErrorIfNotFound, false); }) - .Then( - step => step.ConditionExpression = new JavaScriptExpression("FileFinderResult != null"), + .Then( + step => step.Set(x => x.Condition, x => !x.GetInput().IsNullOrWhiteSpace()), ifElse => { ifElse.When(OutcomeNames.True) .Then(step => { - step.VariableName = VariableNames.HasDbMigrations; - step.ValueExpression = new JavaScriptExpression("true"); + step.Set(x => x.VariableName, VariableNames.HasDbMigrations); + step.Set(x => x.Value, true); }) - .Then(nextActivityName) + .ThenNamed(nextActivityName) ; ifElse.When(OutcomeNames.False) .Then(step => { - step.VariableName = VariableNames.HasDbMigrations; - step.ValueExpression = new JavaScriptExpression("false"); + step.Set(x => x.VariableName, VariableNames.HasDbMigrations); + step.Set(x => x.Value, false); }) - .Then(nextActivityName) + .ThenNamed(nextActivityName) ; - }) - ; + }) + ; } } -} +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Workflow/Common/ConfigureMigrationProjectsWorkflow.cs b/src/AbpHelper.Core/Workflow/Common/ConfigureMigrationProjectsWorkflow.cs index a67a58af..fc63b943 100644 --- a/src/AbpHelper.Core/Workflow/Common/ConfigureMigrationProjectsWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Common/ConfigureMigrationProjectsWorkflow.cs @@ -1,13 +1,12 @@ -using EasyAbp.AbpHelper.Core.Commands; +using System; +using EasyAbp.AbpHelper.Core.Commands; using EasyAbp.AbpHelper.Core.Commands.Generate.Crud; using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Common { @@ -18,132 +17,162 @@ public static class ConfigureMigrationProjectsWorkflow private const string ModuleMigrationProjectName = nameof(ModuleMigrationProjectName); private const string AppMigrationProjectName = nameof(AppMigrationProjectName); - public static IActivityBuilder AddConfigureMigrationProjectsWorkflow(this IActivityBuilder builder, string nextActivityName) + public static IActivityBuilder AddConfigureMigrationProjectsWorkflow(this IActivityBuilder builder, + string nextActivityName) { return builder .AddConfigureHasDbMigrationsWorkflow("SearchMigrationProject") - .Then( - ifElse => ifElse.ConditionExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(CrudCommandOption.MigrationProjectName)} == null"), + .Then( + ifElse => + { + ifElse.Set(x => x.Condition, x => + { + var option = x.GetVariable(CommandConsts.OptionVariableName); + return option?.MigrationProjectName.IsNullOrWhiteSpace(); + }); + }, ifElse => { ifElse - .When(OutcomeNames.True) // No migration project name provided - .Then( - ifElse1 => ifElse1.ConditionExpression = new JavaScriptExpression(VariableNames.HasDbMigrations), - ifElse1 => + .When(OutcomeNames.True) // No migration project name provided + .Then( + ifElse1 => + { + ifElse1.Set(x => x.Condition, + x => x.GetVariable(VariableNames.HasDbMigrations)); + }, + ifElse1 => { ifElse1 .When(OutcomeNames.True) - .Then( - step => - { - step.VariableName = AppMigrationProjectName; - step.ValueExpression = new LiteralExpression("*.EntityFrameworkCore.DbMigrations.csproj"); - }) - .Then("SearchHttpApiHostProject") + .Then(step => + { + step.Set(x => x.VariableName, AppMigrationProjectName); + step.Set(x => x.Value, "*.EntityFrameworkCore.DbMigrations.csproj"); + }) + .ThenNamed("SearchHttpApiHostProject") ; ifElse1 .When(OutcomeNames.False) - .Then( - step => - { - step.VariableName = AppMigrationProjectName; - step.ValueExpression = new LiteralExpression("*.EntityFrameworkCore.csproj"); - }) - .Then("SearchHttpApiHostProject") + .Then(step => + { + step.Set(x => x.VariableName, AppMigrationProjectName); + step.Set(x => x.Value, "*.EntityFrameworkCore.csproj"); + }) + .ThenNamed("SearchHttpApiHostProject") ; } ) - .Then( - step => - { - step.VariableName = ModuleMigrationProjectName; - step.ValueExpression = new LiteralExpression("*.HttpApi.Host.csproj"); - }).WithName("SearchHttpApiHostProject") - .Then(ActivityNames.SearchFiles) + .Then(step => + { + step.Set(x => x.VariableName, ModuleMigrationProjectName); + step.Set(x => x.Value, "*.HttpApi.Host.csproj"); + }).WithName("SearchHttpApiHostProject") + .ThenNamed(ActivityNames.SearchFiles) ; ifElse .When(OutcomeNames.False) - .Then( - step => + .Then(step => + { + step.Set(x => x.VariableName, AppMigrationProjectName); + step.Set(x => x.Value, x => { - step.VariableName = AppMigrationProjectName; - step.ValueExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(CrudCommandOption.MigrationProjectName)}"); - }) - .Then( - step => + var option = + x.GetVariable(CommandConsts.OptionVariableName)!; + return option.MigrationProjectName; + }); + }) + .Then(step => + { + step.Set(x => x.VariableName, ModuleMigrationProjectName); + step.Set(x => x.Value, x => { - step.VariableName = ModuleMigrationProjectName; - step.ValueExpression = new JavaScriptExpression($"{CommandConsts.OptionVariableName}.{nameof(CrudCommandOption.MigrationProjectName)}"); - }) - .Then(ActivityNames.SearchFiles) + var option = + x.GetVariable(CommandConsts.OptionVariableName)!; + return option.MigrationProjectName; + }); + }) + .ThenNamed(ActivityNames.SearchFiles) ; } ) .WithName("SearchMigrationProject") - .Then( - ifElse => ifElse.ConditionExpression = new JavaScriptExpression - ($"ProjectInfo.TemplateType == {TemplateType.Application:D}"), + .Then( + ifElse => + { + ifElse.Set(x => x.Condition, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return projectInfo.TemplateType is TemplateType.Application; + }); + }, ifElse => { // Application ifElse .When(OutcomeNames.True) - .Then( - step => + .Then(step => + { + step.Set(x => x.SearchFileName, + x => x.GetVariable(AppMigrationProjectName)); + step.Set(x => x.ResultVariableName, MigrationProjectFile); + }) + .Then( + ie => { - step.SearchFileName = new JavaScriptExpression(AppMigrationProjectName); - step.ResultVariableName = new LiteralExpression(MigrationProjectFile); - } - ) - .Then( - ie => ie.ConditionExpression = new JavaScriptExpression - ($"ProjectInfo.UiFramework == {UiFramework.RazorPages:D}"), + ie.Set(x => x.Condition, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return projectInfo.UiFramework is UiFramework.RazorPages; + }); + }, ie => { ie.When(OutcomeNames.True) - .Then( - step => - { - step.SearchFileName = new LiteralExpression("*.Web.csproj"); - step.ResultVariableName = new LiteralExpression(StartupProjectFile); - }) - .Then(nextActivityName) + .Then(step => + { + step.Set(x => x.SearchFileName, "*.Web.csproj"); + step.Set(x => x.ResultVariableName, StartupProjectFile); + }) + .ThenNamed(nextActivityName) ; }) - .Then( - ie => ie.ConditionExpression = new JavaScriptExpression - ($"ProjectInfo.UiFramework == {UiFramework.None:D}"), + .Then( + ie => + { + ie.Set(x => x.Condition, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return projectInfo.UiFramework is UiFramework.None; + }); + }, ie => { ie.When(OutcomeNames.True) - .Then( - step => - { - step.SearchFileName = new LiteralExpression("*.DbMigrator.csproj"); - step.ResultVariableName = new LiteralExpression(StartupProjectFile); - }) - .Then(nextActivityName) + .Then(step => + { + step.Set(x => x.SearchFileName, "*.DbMigrator.csproj"); + step.Set(x => x.ResultVariableName, StartupProjectFile); + }) + .ThenNamed(nextActivityName) ; }); // Module ifElse .When(OutcomeNames.False) - .Then( - step => - { - step.SearchFileName = new JavaScriptExpression(ModuleMigrationProjectName); - step.ResultVariableName = new LiteralExpression(MigrationProjectFile); - } - ) - .Then( - step => - { - step.SearchFileName = new JavaScriptExpression(ModuleMigrationProjectName); // For module, the startup project is same with the migration project - step.ResultVariableName = new LiteralExpression(StartupProjectFile); - } - ) - .Then(nextActivityName) + .Then(step => + { + step.Set(x => x.SearchFileName, + x => x.GetVariable(ModuleMigrationProjectName)); + step.Set(x => x.ResultVariableName, MigrationProjectFile); + }) + .Then(step => + { + step.Set(x => x.SearchFileName, + x => x.GetVariable( + ModuleMigrationProjectName)); // For module, the startup project is same with the migration project + }) + .ThenNamed(nextActivityName) ; } ).WithName(ActivityNames.SearchFiles) diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/CustomRepositoryGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/CustomRepositoryGenerationWorkflow.cs index cf698dc9..d88628f0 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/CustomRepositoryGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/CustomRepositoryGenerationWorkflow.cs @@ -1,7 +1,7 @@ -using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; +using EasyAbp.AbpHelper.Core.Models; +using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -14,17 +14,23 @@ public static IActivityBuilder AddCustomRepositoryGeneration(this IOutcomeBuilde .Then( step => { - step.GroupName = "Repository"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); + step.Set(x => x.GroupName, "Repository"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); } ) /* Add repository configuration to EntityFrameworkCoreModule */ .Then( - step => step.SearchFileName = new JavaScriptExpression("`*${ProjectInfo.Name}EntityFrameworkCoreModule.cs`") - ) + step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"*{projectInfo.Name}EntityFrameworkCoreModule.cs"; + }); + }) .Then() .Then() ; } } -} +} \ No newline at end of file diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/EFCoreConfigurationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/EFCoreConfigurationWorkflow.cs index 28bce240..b8d99ca5 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/EFCoreConfigurationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/EFCoreConfigurationWorkflow.cs @@ -1,9 +1,10 @@ -using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; +using System; +using EasyAbp.AbpHelper.Core.Models; +using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -14,50 +15,77 @@ public static IActivityBuilder AddEfCoreConfigurationWorkflow(this IActivityBuil return builder /* Add entity property to DbContext class*/ .Then( - step => { step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}DbContext.cs`"); }) + step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}DbContext.cs"; + }); + }) .Then() .Then() - .IfElse( - step => step.ConditionExpression = new JavaScriptExpression("ProjectInfo.TemplateType == 1"), + .Then( + step => + { + step.Set(x => x.Condition, + x => x.GetVariable("ProjectInfo")!.TemplateType == TemplateType.Module); + }, ifElse => { // For module, we also need to modify the IDbContext interface */ ifElse .When(OutcomeNames.True) .Then( - step => { step.SearchFileName = new JavaScriptExpression("`I${ProjectInfo.Name}DbContext.cs`"); }) + step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"I{projectInfo.Name}DbContext.cs"; + }); + }) .Then() .Then() - .Then(ActivityNames.DbContextModel) + .ThenNamed(ActivityNames.DbContextModel) ; ifElse .When(OutcomeNames.False) - .Then(ActivityNames.DbContextModel) + .ThenNamed(ActivityNames.DbContextModel) ; } ) /* Add entity configuration to ModelCreating */ - .Then( - step => { - step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}DbContextModelCreatingExtensions.cs`"); - step.ErrorIfNotFound = new JavaScriptExpression("false"); - }).WithName(ActivityNames.DbContextModel) - .IfElse( - step => step.ConditionExpression = new JavaScriptExpression("FileFinderResult != null"), + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}DbContextModelCreatingExtensions.cs"; + }); + step.Set(x => x.ErrorIfNotFound, false); + }).WithName(ActivityNames.DbContextModel) + .Then( + step => { step.Set(x => x.Condition, x => !x.GetInput().IsNullOrWhiteSpace()); }, ifElse => { /* For app using abp v4.4 before version and all versions of the module, using DbContextModelCreatingExtensions by default */ ifElse .When(OutcomeNames.True) - .Then("DbContextModelCreating") + .ThenNamed("DbContextModelCreating") ; /* For app using abp v4.4 after version, using ProjectNameDbContext by default */ ifElse .When(OutcomeNames.False) - .Then( - step => step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}DbContext.cs`") - ) - .Then("DbContextModelCreating") + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}DbContext.cs"; + }); + }) + .ThenNamed("DbContextModelCreating") ; } ) diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/EntityConstructorsGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/EntityConstructorsGenerationWorkflow.cs index fde498ef..d586e8bb 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/EntityConstructorsGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/EntityConstructorsGenerationWorkflow.cs @@ -1,6 +1,6 @@ using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/EntityUsingGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/EntityUsingGenerationWorkflow.cs index d7f02416..c23687d6 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/EntityUsingGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/EntityUsingGenerationWorkflow.cs @@ -1,6 +1,5 @@ using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Expressions; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -12,15 +11,15 @@ public static IActivityBuilder AddEntityUsingGenerationWorkflow(this IActivityBu .Then( step => { - step.TemplateName = "UsingEntityNamespace"; - step.GeneratedTextKey = new LiteralExpression("EntityUsingText"); + step.Set(x => x.TemplateName, "UsingEntityNamespace"); + step.Set(x => x.GeneratedTextKey, "EntityUsingText"); } ).WithName(name) .Then( step => { - step.TemplateName = "UsingEntityDtoNamespace"; - step.GeneratedTextKey = new LiteralExpression("EntityDtoUsingText"); + step.Set(x => x.TemplateName, "UsingEntityDtoNamespace"); + step.Set(x => x.GeneratedTextKey, "EntityDtoUsingText"); } ) ; diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/LocalizationGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/LocalizationGenerationWorkflow.cs index d6e7e66d..ac650ece 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/LocalizationGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/LocalizationGenerationWorkflow.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; +using EasyAbp.AbpHelper.Core.Commands; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -16,34 +16,49 @@ public static IActivityBuilder AddLocalizationGenerationWorkflow(this IOutcomeBu return builder /* Add localization */ .Then( - step => { step.TemplateName = "Localization"; } + step => { step.Set(x => x.TemplateName, "Localization"); } ).WithName(ActivityNames.LocalizationGeneration) .Then( step => { - step.SearchDirectoryName = "Localization"; - step.BaseDirectory = new JavaScriptExpression(@"`${AspNetCoreDir}/src/${ProjectInfo.FullName}.Domain.Shared`"); + step.Set(x => x.SearchDirectoryName, "Localization"); + step.Set(x => x.BaseDirectory, x => + { + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir)!; + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{aspNetCoreDir}/src/{projectInfo.FullName}.Domain.Shared"; + }); + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); } ) .Then( step => { - step.SearchFileName = new LiteralExpression("*.json"); - step.BaseDirectory = new JavaScriptExpression(DirectoryFinderStep.DefaultDirectoryParameterName); + step.Set(x => x.SearchFileName, "*.json"); + step.Set(x => x.BaseDirectory, + x => x.GetVariable(DirectoryFinderStep.DefaultDirectoryParameterName)); + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); } ) .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(MultiFileFinderStep.DefaultFileParameterName); }, + step => + { + step.Set(x => x.Items, + x => x.GetVariable>(MultiFileFinderStep.DefaultFileParameterName)); + }, branch => branch.When(OutcomeNames.Iterate) .Then( step => { - step.TargetFile = new JavaScriptExpression("CurrentValue"); - step.LocalizationJson = new JavaScriptExpression(TextGenerationStep.DefaultGeneratedTextParameterName); + step.Set(x => x.TargetFile, x => x.GetInput()); + step.Set(x => x.LocalizationJson, + x => x.GetVariable(TextGenerationStep + .DefaultGeneratedTextParameterName)); } ) - .Then(branch) ) ; } diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/MigrationAndUpdateDatabaseWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/MigrationAndUpdateDatabaseWorkflow.cs index f7ed6daa..aeba8b66 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/MigrationAndUpdateDatabaseWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/MigrationAndUpdateDatabaseWorkflow.cs @@ -1,7 +1,7 @@ -using EasyAbp.AbpHelper.Core.Steps.Common; +using EasyAbp.AbpHelper.Core.Models; +using EasyAbp.AbpHelper.Core.Steps.Common; using EasyAbp.AbpHelper.Core.Workflow.Common; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -13,13 +13,28 @@ public static IActivityBuilder AddMigrationAndUpdateDatabaseWorkflow(this IOutco .Then() .AddConfigureMigrationProjectsWorkflow(ActivityNames.AddMigration) /* Add migration */ - .Then( - step => step.Command = new JavaScriptExpression("`dotnet ef migrations add Added${EntityInfo.Name} -p \"${MigrationProjectFile}\" -s \"${StartupProjectFile}\"`") - ).WithName(ActivityNames.AddMigration) + .Then(step => + { + step.Set(x => x.Command, x => + { + var entityInfo = x.GetVariable("EntityInfo")!; + var migrationProjectFile = x.GetVariable("MigrationProjectFile"); + var startupProjectFile = x.GetVariable("StartupProjectFile"); + return + $"dotnet ef migrations add Added{entityInfo.Name} -p \"{migrationProjectFile}\" -s \"{startupProjectFile}\""; + }); + }).WithName(ActivityNames.AddMigration) /* Update database */ - .Then( - step => step.Command = new JavaScriptExpression("`dotnet ef database update -p \"${MigrationProjectFile}\" -s \"${StartupProjectFile}\"`") - ) + .Then(step => + { + step.Set(x => x.Command, x => + { + var migrationProjectFile = x.GetVariable("MigrationProjectFile"); + var startupProjectFile = x.GetVariable("StartupProjectFile"); + return + $"dotnet ef database update -p \"{migrationProjectFile}\" -s \"{startupProjectFile}\""; + }); + }) ; } } diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/ServiceGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/ServiceGenerationWorkflow.cs index 697e573e..562cebb7 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/ServiceGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/ServiceGenerationWorkflow.cs @@ -1,51 +1,78 @@ -using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; +using EasyAbp.AbpHelper.Core.Commands.Generate.Crud; +using EasyAbp.AbpHelper.Core.Models; +using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { public static class ServiceGenerationWorkflow { - public static IActivityBuilder AddServiceGenerationWorkflow(this IActivityBuilder builder, string name) + public static IActivityBuilder AddServiceGenerationWorkflow(this IActivityBuilder builder, string name, + CrudCommandOption option) { return builder /* Generate dto, service interface and class files */ .Then( step => { - step.GroupName = "Service"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); + step.Set(x => x.GroupName, "Service"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); } ).WithName(name) /* Generate permissions */ - .IfElse( - ifElse => ifElse.ConditionExpression = new JavaScriptExpression("Option.SkipPermissions"), + .Then( + ifElse => { ifElse.Set(x => x.Condition, option.SkipPermissions); }, ifElse => { ifElse .When(OutcomeNames.True) - .Then(ActivityNames.AutoMapper) + .ThenNamed(ActivityNames.AutoMapper) ; ifElse .When(OutcomeNames.False) - .Then( - step => { step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}Permissions.cs`"); }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}Permissions.cs"; + }); + }) .Then() .Then() - .Then( - step => { step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}PermissionDefinitionProvider.cs`"); }) + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}PermissionDefinitionProvider.cs"; + }); + }) .Then() .Then() - .Then(ActivityNames.AutoMapper) + .ThenNamed(ActivityNames.AutoMapper) ; } ) /* Add mapping */ - .Then(step => step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}ApplicationAutoMapperProfile.cs`")).WithName(ActivityNames.AutoMapper) - .Then() + .Then(step => + { + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}ApplicationAutoMapperProfile.cs"; + }); + }) + .WithName(ActivityNames.AutoMapper) + .Then( + step => + { + step.Set(x => x.EntityUsingText, x => x.GetVariable("EntityUsingText")); + step.Set(x => x.EntityDtoUsingText, x => x.GetVariable("EntityDtoUsingText")); + }) .Then() ; } diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/TestGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/TestGenerationWorkflow.cs index 360c77ab..87de3f07 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/TestGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/TestGenerationWorkflow.cs @@ -1,6 +1,5 @@ using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -13,8 +12,8 @@ public static IActivityBuilder AddTestGenerationWorkflow(this IOutcomeBuilder bu .Then( step => { - step.GroupName = "Test"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); + step.Set(x => x.GroupName, "Test"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); } ) ; diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/UiAngularGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/UiAngularGenerationWorkflow.cs index 207c7898..b9c82de5 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/UiAngularGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/UiAngularGenerationWorkflow.cs @@ -1,9 +1,8 @@ using System.Runtime.InteropServices; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.Typescript; using EasyAbp.AbpHelper.Core.Steps.Common; -using Elsa.Expressions; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -14,47 +13,73 @@ public static IActivityBuilder AddUiAngularGenerationWorkflow(this IOutcomeBuild string cdOption = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? " /d" : ""; return builder /* Add angular module */ - .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{BaseDirectory}}/angular && yarn ng generate module ${{EntityInfo.NamespaceLastPart.toLowerCase()}} --route ${{EntityInfo.NamespaceLastPart.toLowerCase()}} --module app.module`" - )) + .Then(step => + { + step.Set(x => x.Command, x => + { + var baseDirectory = x.GetVariable("BaseDirectory"); + var entityInfo = x.GetVariable("EntityInfo")!; + return + $"cd{cdOption} {baseDirectory}/angular && yarn ng generate module {entityInfo.NamespaceLastPart.ToLower()} --route {entityInfo.NamespaceLastPart.ToLower()} --module app.module"; + }); + }) /* Modify app-routing.module.ts */ - .Then( - step => step.SearchFileName = new LiteralExpression("app-routing.module.ts") - ) - .Then() - .Then( - step => step.NewLine = new JavaScriptExpression(@"'\n'") - ) + .Then(step => step.Set(x => x.SearchFileName, "app-routing.module.ts")) + .Then(step => + { + step.Set(x => x.EntityInfo, x => x.GetVariable("EntityInfo")); + }) + .Then(step => step.Set(x => x.NewLine, "\n")) /* Add list component */ - .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{BaseDirectory}}/angular && yarn ng generate component ${{EntityInfo.NamespaceLastPart.toLowerCase()}}/${{EntityInfo.Name.toLowerCase()}}-list`" - )) + .Then(step => + { + step.Set(x => x.Command, x => + { + var baseDirectory = x.GetVariable("BaseDirectory"); + var entityInfo = x.GetVariable("EntityInfo")!; + return + $"cd{cdOption} {baseDirectory}/angular && yarn ng generate component {entityInfo.NamespaceLastPart.ToLower()}/{entityInfo.Name.ToLower()}-list"; + }); + }) + .Then(step => + { + step.Set(x => x.Command, x => + { + var baseDirectory = x.GetVariable("BaseDirectory"); + var entityInfo = x.GetVariable("EntityInfo")!; + return + $"cd{cdOption} {baseDirectory}/angular && yarn ng generate component {entityInfo.NamespaceLastPart.ToLower()}/{entityInfo.Name.ToLower()}-list"; + }); + }) /* Modify XXX.module.ts */ - .Then( - step => step.SearchFileName = new JavaScriptExpression("`${EntityInfo.NamespaceLastPart.toLowerCase()}.module.ts`") - ) - .Then() - .Then( - step => step.NewLine = new JavaScriptExpression(@"'\n'") - ) + .Then(step => step.Set(x => x.SearchFileName, x => + { + var entityInfo = x.GetVariable("EntityInfo")!; + return $"{entityInfo.NamespaceLastPart.ToLower()}.module.ts"; + })) + .Then(step => step.Set(x => x.EntityInfo, x => x.GetVariable("EntityInfo"))) + .Then(step => step.Set(x => x.NewLine, "\n")) /* Modify XXX-routing.module.ts */ - .Then( - step => step.SearchFileName = new JavaScriptExpression("`${EntityInfo.NamespaceLastPart.toLowerCase()}-routing.module.ts`") - ) + .Then(step => step.Set(x => x.SearchFileName, x => + { + var entityInfo = x.GetVariable("EntityInfo")!; + return $"{entityInfo.NamespaceLastPart.ToLower()}-routing.module.ts"; + })) .Then() - .Then( - step => step.NewLine = new JavaScriptExpression(@"'\n'") - ) + .Then(step => step.Set(x => x.NewLine, "\n")) /* Create state */ - .Then( - step => step.Command = new JavaScriptExpression( - @$"`cd{cdOption} ${{BaseDirectory}}/angular && yarn ng generate ngxs-schematic:state ${{EntityInfo.NamespaceLastPart.toLowerCase()}}`" - )) + .Then(step => + { + step.Set(x => x.Command, x => + { + var baseDirectory = x.GetVariable("BaseDirectory"); + var entityInfo = x.GetVariable("EntityInfo")!; + return + $"cd{cdOption} {baseDirectory}/angular && yarn ng generate ngxs-schematic:state {entityInfo.NamespaceLastPart.ToLower()}"; + }); + }) /* Generate XXX.ts */ - .Then( - step => { step.GroupName = "UiAngular"; } + .Then(step => { step.Set(x => x.GroupName, "UiAngular"); } ) ; } diff --git a/src/AbpHelper.Core/Workflow/Generate/Crud/UiRazorPagesGenerationWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/Crud/UiRazorPagesGenerationWorkflow.cs index 86ba11b6..5061544f 100644 --- a/src/AbpHelper.Core/Workflow/Generate/Crud/UiRazorPagesGenerationWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/Crud/UiRazorPagesGenerationWorkflow.cs @@ -1,12 +1,13 @@ using System.Collections.Generic; +using EasyAbp.AbpHelper.Core.Commands; +using EasyAbp.AbpHelper.Core.Models; using EasyAbp.AbpHelper.Core.Steps.Abp; using EasyAbp.AbpHelper.Core.Steps.Abp.ModificationCreatorSteps.CSharp; using EasyAbp.AbpHelper.Core.Steps.Common; using Elsa; -using Elsa.Activities; -using Elsa.Activities.ControlFlow.Activities; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.ControlFlow; +using Elsa.Activities.Primitives; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate.Crud { @@ -15,26 +16,28 @@ public static class UiRazorPagesGenerationWorkflow public static IActivityBuilder AddUiRazorPagesGenerationWorkflow(this IOutcomeBuilder builder) { return builder - .Then( - step => step.ConditionExpression = new JavaScriptExpression("ProjectInfo.TemplateType == 1"), + .Then( + step => + { + step.Set(x => x.Condition, + x => x.GetVariable("ProjectInfo")!.TemplateType == TemplateType.Module); + }, ifElse => { // For module, put generated Razor files under the "ProjectName" folder */ ifElse .When(OutcomeNames.True) - .Then( - step => - { - step.VariableName = "Bag.PagesFolder"; - step.ValueExpression = new JavaScriptExpression("ProjectInfo.Name"); - } - ) + .Then(step => + { + step.Set(x => x.VariableName, "Bag.PagesFolder"); + step.Set(x => x.Value, x => x.GetVariable("ProjectInfo")!.Name); + }) .Then() - .Then(ActivityNames.UiRazor) + .ThenNamed(ActivityNames.UiRazor) ; ifElse .When(OutcomeNames.False) - .Then(ActivityNames.UiRazor) + .ThenNamed(ActivityNames.UiRazor) ; } ) @@ -42,47 +45,86 @@ public static IActivityBuilder AddUiRazorPagesGenerationWorkflow(this IOutcomeBu .Then( step => { - step.GroupName = "UiRazor"; - step.TargetDirectory = new JavaScriptExpression(VariableNames.AspNetCoreDir); + step.Set(x => x.GroupName, "UiRazor"); + step.Set(x => x.TargetDirectory, x => x.GetVariable(VariableNames.AspNetCoreDir)); } ).WithName(ActivityNames.UiRazor) /* Add menu name */ .Then( step => { - step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}Menus.cs`"); + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}Menus.cs"; + }); } ) .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(MultiFileFinderStep.DefaultFileParameterName); }, + step => + { + step.Set(x => x.Items, + x => x.GetVariable>(MultiFileFinderStep.DefaultFileParameterName)); + }, branch => branch.When(OutcomeNames.Iterate) - .Then(step => step.SourceFile = new JavaScriptExpression("CurrentValue")) - .Then(step => step.TargetFile = new JavaScriptExpression("CurrentValue")) - .Then(branch) + .Then(step => { step.Set(x => x.SourceFile, x => x.GetInput()); }) + .Then(step => + { + step.Set(x => x.TargetFile, x => x.GetInput()); + }) ) /* Add menu */ .Then( step => { - step.BaseDirectory = new JavaScriptExpression(@"`${AspNetCoreDir}/src`"); - step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}MenuContributor.cs`"); + step.Set(x => x.BaseDirectory, x => + { + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir); + return $"{aspNetCoreDir}/src"; + }); + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}MenuContributor.cs"; + }); + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); } ) .Then( - x => { x.CollectionExpression = new JavaScriptExpression>(MultiFileFinderStep.DefaultFileParameterName); }, + step => + { + step.Set(x => x.Items, + x => x.GetVariable>(MultiFileFinderStep.DefaultFileParameterName)); + }, branch => branch.When(OutcomeNames.Iterate) - .Then(step => step.SourceFile = new JavaScriptExpression("CurrentValue")) - .Then(step => step.TargetFile = new JavaScriptExpression("CurrentValue")) - .Then(branch) + .Then(step => + { + step.Set(x => x.SourceFile, x => x.GetInput()); + }) + .Then(step => + { + step.Set(x => x.TargetFile, x => x.GetInput()); + }) ) /* Add mapping */ .Then( step => { - step.BaseDirectory = new JavaScriptExpression(@"`${AspNetCoreDir}/src`"); - step.SearchFileName = new JavaScriptExpression("`${ProjectInfo.Name}WebAutoMapperProfile.cs`"); + step.Set(x => x.BaseDirectory, x => + { + var aspNetCoreDir = x.GetVariable(VariableNames.AspNetCoreDir); + return $"{aspNetCoreDir}/src"; + }); + step.Set(x => x.SearchFileName, x => + { + var projectInfo = x.GetVariable("ProjectInfo")!; + return $"{projectInfo.Name}WebAutoMapperProfile.cs"; + }); + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); }) .Then() .Then() diff --git a/src/AbpHelper.Core/Workflow/Generate/OverwriteWorkflow.cs b/src/AbpHelper.Core/Workflow/Generate/OverwriteWorkflow.cs index 4f707b70..7ecd0e0a 100644 --- a/src/AbpHelper.Core/Workflow/Generate/OverwriteWorkflow.cs +++ b/src/AbpHelper.Core/Workflow/Generate/OverwriteWorkflow.cs @@ -1,22 +1,20 @@ using EasyAbp.AbpHelper.Core.Commands; using EasyAbp.AbpHelper.Core.Commands.Generate; -using Elsa.Activities; -using Elsa.Scripting.JavaScript; -using Elsa.Services; +using Elsa.Activities.Primitives; +using Elsa.Builders; namespace EasyAbp.AbpHelper.Core.Workflow.Generate { public static class OverwriteWorkflow { - public static IActivityBuilder AddOverwriteWorkflow(this IActivityBuilder builder) + public static IActivityBuilder AddOverwriteWorkflow(this IActivityBuilder builder, GenerateCommandOption option) { return builder - .Then( - step => - { - step.VariableName = CommandConsts.OverwriteVariableName; - step.ValueExpression = new JavaScriptExpression($"!{CommandConsts.OptionVariableName}.{nameof(GenerateCommandOption.NoOverwrite)}"); - }) + .Then(step => + { + step.Set(x => x.VariableName, CommandConsts.OverwriteVariableName); + step.Set(x => x.Value, option.NoOverwrite); + }) ; } } diff --git a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs index 4687cc84..3177bac3 100644 --- a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs +++ b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs @@ -68,7 +68,7 @@ await UsingEntityFile(code, async file => ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var info = ctx.GetVariable("EntityInfo"); @@ -128,7 +128,7 @@ await UsingEntityFile(code, async file => ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var info = ctx.GetVariable("EntityInfo"); @@ -165,7 +165,7 @@ await UsingEntityFile("invalid c# code", async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Arrange _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); diff --git a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs index 18f13656..764cbc4f 100644 --- a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs +++ b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs @@ -67,7 +67,7 @@ await UsingEntityFile(code, async file => ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var info = ctx.GetVariable("EntityInfo"); @@ -126,7 +126,7 @@ await UsingEntityFile(code, async file => ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var info = ctx.GetVariable("EntityInfo"); @@ -163,7 +163,7 @@ await UsingEntityFile("invalid c# code", async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Arrange _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); diff --git a/test/AbpHelper.Tests/Steps/FileModifierStep_Tests.cs b/test/AbpHelper.Tests/Steps/FileModifierStep_Tests.cs index ddaa4e48..1e8c9f84 100644 --- a/test/AbpHelper.Tests/Steps/FileModifierStep_Tests.cs +++ b/test/AbpHelper.Tests/Steps/FileModifierStep_Tests.cs @@ -58,7 +58,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -82,7 +82,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -110,7 +110,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -142,7 +142,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -177,7 +177,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -208,7 +208,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -242,7 +242,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Assert _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); @@ -268,7 +268,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Assert _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); @@ -294,7 +294,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Assert _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); @@ -320,7 +320,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, CancellationToken.None)); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Assert _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); @@ -342,7 +342,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - await _step.ExecuteAsync(ctx, CancellationToken.None); + await _step.ExecuteAsync(ctx); // Assert var contents = await File.ReadAllTextAsync(file); @@ -373,7 +373,7 @@ await UsingTempFile(DefaultFileContents, async file => ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); // Act - var ex = await Assert.ThrowsAsync(() => _step.ExecuteAsync(ctx, new CancellationToken())); + var ex = await Assert.ThrowsAsync(async () => await _step.ExecuteAsync(ctx)); // Assert _output.WriteLine(string.Join(Environment.NewLine, ex.Errors)); diff --git a/test/AbpHelper.Tests/Steps/StepTestsBase.cs b/test/AbpHelper.Tests/Steps/StepTestsBase.cs index 6ea517d0..0b1a89d7 100644 --- a/test/AbpHelper.Tests/Steps/StepTestsBase.cs +++ b/test/AbpHelper.Tests/Steps/StepTestsBase.cs @@ -1,14 +1,19 @@ using System; +using System.Threading; using System.Threading.Tasks; +using Elsa.Models; using Elsa.Services.Models; namespace EasyApp.AbpHelper.Tests.Steps { public class StepTestsBase : AbpHelperTestBase { - protected async Task UsingWorkflowContext(Func action) + protected async Task UsingWorkflowContext(Func action) { - var context = new WorkflowExecutionContext(new Workflow(), null, Application.ServiceProvider); + var context = + new ActivityExecutionContext(ServiceProvider, + new WorkflowExecutionContext(ServiceProvider, new WorkflowBlueprint(), new WorkflowInstance()), + new ActivityBlueprint(), null, false, CancellationToken.None); await action(context); } } From c9ac73b67928be786ba1a33de54c777ed92f22f5 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 23 Jun 2022 02:34:15 +0800 Subject: [PATCH 2/5] Fix CommandWithOption --- src/AbpHelper.Core/Commands/CommandWithOption.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/AbpHelper.Core/Commands/CommandWithOption.cs b/src/AbpHelper.Core/Commands/CommandWithOption.cs index 03ff3193..b3e2b543 100644 --- a/src/AbpHelper.Core/Commands/CommandWithOption.cs +++ b/src/AbpHelper.Core/Commands/CommandWithOption.cs @@ -65,7 +65,12 @@ await RunWorkflow(builder => step.Set(x => x.VariableName, ExcludeDirectoriesVariableName); step.Set(x => x.Value, option.Exclude); }) - .Then() + .Then(step => + { + step.Set(x => x.ExcludeDirectories, + x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); + step.Set(x => x.Overwrite, x => x.GetVariable(CommandConsts.OverwriteVariableName)); + }) ; return ConfigureBuild(option, activityBuilder).Build(); From d7d786b6a1fa02559d4f28577fd7d67fe01cc126 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 23 Jun 2022 02:41:24 +0800 Subject: [PATCH 3/5] Fix CommandWithOption --- src/AbpHelper.Core/Commands/CommandWithOption.cs | 4 +--- src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/AbpHelper.Core/Commands/CommandWithOption.cs b/src/AbpHelper.Core/Commands/CommandWithOption.cs index b3e2b543..b7f4e22b 100644 --- a/src/AbpHelper.Core/Commands/CommandWithOption.cs +++ b/src/AbpHelper.Core/Commands/CommandWithOption.cs @@ -67,9 +67,7 @@ await RunWorkflow(builder => }) .Then(step => { - step.Set(x => x.ExcludeDirectories, - x => x.GetVariable(CommandConsts.ExcludeDirectoriesVariableName)); - step.Set(x => x.Overwrite, x => x.GetVariable(CommandConsts.OverwriteVariableName)); + step.Set(x => x.ExcludeDirectories, option.Exclude); }) ; diff --git a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs index 9f257267..ef92a003 100644 --- a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs @@ -25,7 +25,6 @@ protected override async ValueTask OnExecuteAsync(Acti LogInput(() => ExcludeDirectories, string.Join("; ", ExcludeDirectories)); LogInput(() => BaseDirectory); - LogInput(() => Overwrite); TemplateType templateType; if (FileExistsInDirectory(BaseDirectory, "*.Host.Shared.csproj", ExcludeDirectories)) From c6cce1f470d9fd87e93b0978b6fb03ca2ba3edbc Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 23 Jun 2022 03:26:40 +0800 Subject: [PATCH 4/5] Move AddElsa to AbpHelperModule --- src/AbpHelper.Core/AbpHelperCoreModule.cs | 11 ----------- src/AbpHelper/AbpHelperModule.cs | 13 +++++++++---- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/AbpHelper.Core/AbpHelperCoreModule.cs b/src/AbpHelper.Core/AbpHelperCoreModule.cs index 5760536b..0c58dbb3 100644 --- a/src/AbpHelper.Core/AbpHelperCoreModule.cs +++ b/src/AbpHelper.Core/AbpHelperCoreModule.cs @@ -1,5 +1,4 @@ using System.Reflection; -using EasyAbp.AbpHelper.Core.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Volo.Abp.Autofac; @@ -15,7 +14,6 @@ public class AbpHelperCoreModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - ConfigureElsaActivities(context); ConfigureTemplateFiles(context); ConfigureVirtualFileSystem(); } @@ -28,15 +26,6 @@ private void ConfigureVirtualFileSystem() }); } - private void ConfigureElsaActivities(ServiceConfigurationContext context) - { - context.Services - .AddElsa(x => - { - x.AddAbpHelperActivities(); - }); - } - private void ConfigureTemplateFiles(ServiceConfigurationContext context) { context.Services.AddSingleton(sp => new ManifestEmbeddedFileProvider(Assembly.GetExecutingAssembly())); diff --git a/src/AbpHelper/AbpHelperModule.cs b/src/AbpHelper/AbpHelperModule.cs index a9163f01..65e7f02e 100644 --- a/src/AbpHelper/AbpHelperModule.cs +++ b/src/AbpHelper/AbpHelperModule.cs @@ -1,9 +1,6 @@ -using System.Reflection; -using EasyAbp.AbpHelper.Core; +using EasyAbp.AbpHelper.Core; using EasyAbp.AbpHelper.Core.Extensions; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.FileProviders; -using Volo.Abp.Autofac; using Volo.Abp.Modularity; namespace EasyAbp.AbpHelper @@ -11,5 +8,13 @@ namespace EasyAbp.AbpHelper [DependsOn(typeof(AbpHelperCoreModule))] public class AbpHelperModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services + .AddElsa(x => + { + x.AddAbpHelperActivities(); + }); + } } } \ No newline at end of file From f5756aee9309c22bd53e89f50543b0e9c9890eb4 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 29 Jun 2022 21:37:44 +0800 Subject: [PATCH 5/5] Fix steps --- src/AbpHelper.Core/Models/ProjectInfo.cs | 4 +- .../Steps/Abp/ProjectInfoProviderStep.cs | 8 +- .../Steps/Abp/SetModelVariableStep.cs | 101 +++++++++++++++--- .../Steps/EntityParserStep_Tests.cs | 4 +- .../Steps/EntityParserStep_Tests2.cs | 4 +- 5 files changed, 100 insertions(+), 21 deletions(-) diff --git a/src/AbpHelper.Core/Models/ProjectInfo.cs b/src/AbpHelper.Core/Models/ProjectInfo.cs index 16af1b27..3b44a240 100644 --- a/src/AbpHelper.Core/Models/ProjectInfo.cs +++ b/src/AbpHelper.Core/Models/ProjectInfo.cs @@ -4,9 +4,10 @@ namespace EasyAbp.AbpHelper.Core.Models { public class ProjectInfo { - public ProjectInfo(string baseDirectory, string fullName, TemplateType templateType, UiFramework uiFramework, bool tiered) + public ProjectInfo(string baseDirectory, string aspNetCoreDir, string fullName, TemplateType templateType, UiFramework uiFramework, bool tiered) { BaseDirectory = baseDirectory; + AspNetCoreDir = aspNetCoreDir; TemplateType = templateType; UiFramework = uiFramework; Tiered = tiered; @@ -14,6 +15,7 @@ public ProjectInfo(string baseDirectory, string fullName, TemplateType templateT } public string BaseDirectory { get; } + public string AspNetCoreDir { get; } public string FullName { get; } public string Name => FullName.Split('.').Last(); public TemplateType TemplateType { get; } diff --git a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs index ef92a003..84c82eb0 100644 --- a/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/ProjectInfoProviderStep.cs @@ -6,8 +6,6 @@ using Elsa; using Elsa.ActivityResults; using Elsa.Attributes; -using Elsa.Design; -using Elsa.Expressions; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Abp @@ -19,6 +17,9 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp )] public class ProjectInfoProviderStep : StepWithOption { + [ActivityOutput(Hint = "Output.")] + public ProjectInfo? Output { get; set; } + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) { BaseDirectory ??= context.GetVariable(BaseDirectoryVariableName)!; @@ -81,9 +82,10 @@ protected override async ValueTask OnExecuteAsync(Acti tiered = FileExistsInDirectory(BaseDirectory, "*.IdentityServer.csproj", ExcludeDirectories); } - var projectInfo = new ProjectInfo(BaseDirectory, fullName, templateType, uiFramework, tiered); + var projectInfo = new ProjectInfo(BaseDirectory, aspNetCoreDir, fullName, templateType, uiFramework, tiered); context.Output = projectInfo; + Output = projectInfo; context.SetVariable("ProjectInfo", projectInfo); LogOutput(() => projectInfo); diff --git a/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs b/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs index 39a94301..6622c85e 100644 --- a/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs +++ b/src/AbpHelper.Core/Steps/Abp/SetModelVariableStep.cs @@ -7,6 +7,8 @@ using Elsa; using Elsa.ActivityResults; using Elsa.Attributes; +using Elsa.Design; +using Elsa.Expressions; using Elsa.Services.Models; namespace EasyAbp.AbpHelper.Core.Steps.Abp @@ -18,32 +20,105 @@ namespace EasyAbp.AbpHelper.Core.Steps.Abp )] public class SetModelVariableStep : Step { + [ActivityInput( + Hint = "ProjectInfo", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public ProjectInfo? ProjectInfo + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "Option", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public object? Option + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "EntityInfo", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public EntityInfo? EntityInfo + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "InterfaceInfo", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public TypeInfo? InterfaceInfo + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "ClassInfo", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public TypeInfo? ClassInfo + { + get => GetState(); + set => SetState(value); + } + + [ActivityInput( + Hint = "DtoInfo", + UIHint = ActivityInputUIHints.SingleLine, + DefaultSyntax = SyntaxNames.JavaScript, + SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid } + )] + public DtoInfo? DtoInfo + { + get => GetState(); + set => SetState(value); + } + protected override ValueTask OnExecuteAsync(ActivityExecutionContext context) { - var projectInfo = context.GetVariable("ProjectInfo"); - var option = context.GetVariable("Option"); - var entityInfo = context.GetVariable("EntityInfo"); - var interfaceInfo = context.GetVariable("InterfaceInfo"); - var classInfo = context.GetVariable("ClassInfo"); - var dtoInfo = context.GetVariable("DtoInfo"); + ProjectInfo ??= context.GetVariable("ProjectInfo"); + Option ??= context.GetVariable("Option"); + EntityInfo ??= context.GetVariable("EntityInfo"); + InterfaceInfo ??= context.GetVariable("InterfaceInfo"); + ClassInfo ??= context.GetVariable("ClassInfo"); + DtoInfo ??= context.GetVariable("DtoInfo"); + var variables = context.WorkflowExecutionContext.GetMergedVariables().Data .Where(v => v.Key.StartsWith("Bag.")); var bag = new ExpandoObject(); foreach (var variable in variables) { - ((IDictionary) bag)[variable.Key.RemovePreFix("Bag.")] = variable.Value; + ((IDictionary)bag)[variable.Key.RemovePreFix("Bag.")] = variable.Value; } context.SetVariable("Model", new { - ProjectInfo = projectInfo, - Option = option, - EntityInfo = entityInfo, - InterfaceInfo = interfaceInfo, - ClassInfo = classInfo, + ProjectInfo, + Option, + EntityInfo, + InterfaceInfo, + ClassInfo, Bag = bag, - DtoInfo = dtoInfo, + DtoInfo, }); return new ValueTask(Done()); diff --git a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs index 3177bac3..84f221ee 100644 --- a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs +++ b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests.cs @@ -65,7 +65,7 @@ await UsingEntityFile(code, async file => { // Arrange ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); - ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); + ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", @"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); // Act await _step.ExecuteAsync(ctx); @@ -125,7 +125,7 @@ await UsingEntityFile(code, async file => { // Arrange ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); - ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); + ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", @"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); // Act await _step.ExecuteAsync(ctx); diff --git a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs index 764cbc4f..d391f757 100644 --- a/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs +++ b/test/AbpHelper.Tests/Steps/EntityParserStep_Tests2.cs @@ -64,7 +64,7 @@ await UsingEntityFile(code, async file => { // Arrange ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); - ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); + ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", @"c:\abp", "Acme.BookStore", TemplateType.Application, UiFramework.RazorPages, false)); // Act await _step.ExecuteAsync(ctx); @@ -123,7 +123,7 @@ await UsingEntityFile(code, async file => { // Arrange ctx.SetVariable(FileFinderStep.DefaultFileParameterName, file); - ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); + ctx.SetVariable("ProjectInfo", new ProjectInfo(@"c:\abp", @"c:\abp", "Acme.BookStore", TemplateType.Module, UiFramework.RazorPages, false)); // Act await _step.ExecuteAsync(ctx);