From e96be6e8243e9c2d166102a64f816809ad383bb2 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 27 Aug 2021 11:52:10 +0300 Subject: [PATCH] Moved studio modules --- build/common.ps1 | 1 + .../Volo.Abp.Identity.Installer.csproj | 2 +- nupkg/common.ps1 | 7 + studio/Volo.Abp.Studio.Open.sln | 49 ++++++ ...o.Abp.Studio.Analyzing.Abstractions.csproj | 12 ++ .../AbpStudioAnalyzingAbstractionsModule.cs | 9 ++ .../Application/ApplicationServiceModel.cs | 21 +++ .../Models/Authorization/PermissionModel.cs | 24 +++ .../Database/DatabaseCollectionModel.cs | 17 ++ .../Models/Database/DatabaseTableModel.cs | 17 ++ .../Models/Database/EfCoreDbContextModel.cs | 25 +++ .../Models/Database/IDbContextModel.cs | 7 + .../Models/Database/MongoDbContextModel.cs | 25 +++ .../Models/Domain/AggregateRootModel.cs | 12 ++ .../Models/Domain/DomainServiceModel.cs | 18 +++ .../Analyzing/Models/Domain/EntityModel.cs | 25 +++ .../Models/Domain/RepositoryInterfaceModel.cs | 20 +++ .../Analyzing/Models/Feature/FeatureModel.cs | 40 +++++ .../Analyzing/Models/Module/AbpModuleModel.cs | 16 ++ .../Models/PackageContentItemModel.cs | 16 ++ .../Models/PackageContentItemNameAttribute.cs | 26 +++ .../Analyzing/Models/PackageContentList.cs | 9 ++ .../Studio/Analyzing/Models/PackageModel.cs | 20 +++ .../Analyzing/Models/Setting/SettingModel.cs | 26 +++ ...lo.Abp.Studio.Domain.CommonServices.csproj | 21 +++ .../AbpStudioDomainCommonServicesModule.cs | 17 ++ .../Volo/Abp/Studio/AbpStudioException.cs | 28 ++++ .../Volo/Abp/Studio/Helpers/CmdHelper.cs | 103 ++++++++++++ .../Volo/Abp/Studio/Helpers/ICmdHelper.cs | 9 ++ .../Volo/Abp/Studio/Helpers/PathHelper.cs | 37 +++++ .../Studio/Modifying/AbpModuleFileManager.cs | 77 +++++++++ .../Abp/Studio/Modifying/CsprojFileManager.cs | 95 +++++++++++ .../Studio/Modifying/IAbpModuleFileManager.cs | 11 ++ .../Studio/Modifying/ICsprojFileManager.cs | 11 ++ .../Abp/Studio/Nuget/INugetSourceCodeStore.cs | 18 +++ .../Studio/Nuget/NugetPackageCacheManager.cs | 35 ++++ .../Abp/Studio/Nuget/NugetSourceCodeStore.cs | 151 ++++++++++++++++++ .../Nuget/TemplateNugetPackageInfoProvider.cs | 18 +++ .../Volo/Abp/Studio/Xml/XmlFileManagerBase.cs | 51 ++++++ .../Volo.Abp.Studio.Domain.Shared.csproj | 15 ++ .../Abp/Studio/AbpStudioDomainSharedModule.cs | 13 ++ .../Volo/Abp/Studio/AbpStudioErrorCodes.cs | 30 ++++ ...Studio.ModuleInstaller.Abstractions.csproj | 13 ++ ...StudioModuleInstallerAbstractionsModule.cs | 13 ++ .../Abp/Studio/Analyzing/AnalyzingOptions.cs | 45 ++++++ .../IModuleInstallingPipelineBuilder.cs | 9 ++ .../ModuleInstallingContext.cs | 56 +++++++ .../ModuleInstallingPipeline.cs | 26 +++ .../ModuleInstallingPipelineStep.cs | 9 ++ .../Volo.Abp.Studio.ModuleInstaller.csproj | 16 ++ .../Studio/AbpStudioModuleInstallerModule.cs | 16 ++ .../ModuleInstallingPipelineBuilderBase.cs | 16 ++ .../Steps/PackageReferencingStep.cs | 74 +++++++++ 53 files changed, 1476 insertions(+), 1 deletion(-) create mode 100644 studio/Volo.Abp.Studio.Open.sln create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo.Abp.Studio.Analyzing.Abstractions.csproj create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/AbpStudioAnalyzingAbstractionsModule.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Application/ApplicationServiceModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Authorization/PermissionModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseCollectionModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseTableModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/EfCoreDbContextModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/IDbContextModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/MongoDbContextModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/AggregateRootModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/DomainServiceModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/EntityModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/RepositoryInterfaceModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Feature/FeatureModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Module/AbpModuleModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemNameAttribute.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentList.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Setting/SettingModel.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo.Abp.Studio.Domain.CommonServices.csproj create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioDomainCommonServicesModule.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioException.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/CmdHelper.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/ICmdHelper.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/PathHelper.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/AbpModuleFileManager.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/CsprojFileManager.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/IAbpModuleFileManager.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/ICsprojFileManager.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/INugetSourceCodeStore.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetPackageCacheManager.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetSourceCodeStore.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/TemplateNugetPackageInfoProvider.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Xml/XmlFileManagerBase.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.Shared/Volo.Abp.Studio.Domain.Shared.csproj create mode 100644 studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioDomainSharedModule.cs create mode 100644 studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioErrorCodes.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/AbpStudioModuleInstallerAbstractionsModule.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/Analyzing/AnalyzingOptions.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/IModuleInstallingPipelineBuilder.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingContext.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipeline.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineStep.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller/Volo.Abp.Studio.ModuleInstaller.csproj create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/AbpStudioModuleInstallerModule.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineBuilderBase.cs create mode 100644 studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/Steps/PackageReferencingStep.cs diff --git a/build/common.ps1 b/build/common.ps1 index 172e22ad6a..16a6747d0f 100644 --- a/build/common.ps1 +++ b/build/common.ps1 @@ -7,6 +7,7 @@ $rootFolder = (Get-Item -Path "./" -Verbose).FullName # List of solutions used only in development mode $solutionPaths = @( "../framework", + "../studio", "../modules/basic-theme", "../modules/users", "../modules/permission-management", diff --git a/modules/identity/src/Volo.Abp.Identity.Installer/Volo.Abp.Identity.Installer.csproj b/modules/identity/src/Volo.Abp.Identity.Installer/Volo.Abp.Identity.Installer.csproj index 49fa7c35bf..80a1b51bb0 100644 --- a/modules/identity/src/Volo.Abp.Identity.Installer/Volo.Abp.Identity.Installer.csproj +++ b/modules/identity/src/Volo.Abp.Identity.Installer/Volo.Abp.Identity.Installer.csproj @@ -10,7 +10,7 @@ - + diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index a96de2bb00..8043c02306 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -336,4 +336,11 @@ $projects = ( "modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client", "modules/cms-kit/src/Volo.CmsKit.Public.Web", "modules/cms-kit/src/Volo.CmsKit.Web" + + # abp/studio + "studio/src/Volo.Abp.Studio.Analyzing.Abstractions", + "studio/src/Volo.Abp.Studio.Domain.CommonServices", + "studio/src/Volo.Abp.Studio.Domain.Shared", + "studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions", + "studio/src/Volo.Abp.Studio.ModuleInstaller" ) diff --git a/studio/Volo.Abp.Studio.Open.sln b/studio/Volo.Abp.Studio.Open.sln new file mode 100644 index 0000000000..563e1d4602 --- /dev/null +++ b/studio/Volo.Abp.Studio.Open.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{344A1096-CC05-42D1-BDDB-E254C27508A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Studio.Analyzing.Abstractions", "src\Volo.Abp.Studio.Analyzing.Abstractions\Volo.Abp.Studio.Analyzing.Abstractions.csproj", "{2271296E-33FD-46BE-97FD-9938193CB7D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Studio.Domain.CommonServices", "src\Volo.Abp.Studio.Domain.CommonServices\Volo.Abp.Studio.Domain.CommonServices.csproj", "{1C86021F-E522-41A1-AC3F-01B0E474D75E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Studio.Domain.Shared", "src\Volo.Abp.Studio.Domain.Shared\Volo.Abp.Studio.Domain.Shared.csproj", "{28132E4E-FFB9-45C4-99AD-1BCA04B3E597}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Studio.ModuleInstaller", "src\Volo.Abp.Studio.ModuleInstaller\Volo.Abp.Studio.ModuleInstaller.csproj", "{4FA11334-D727-4C14-9D71-1DB46AC3BE9C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Studio.ModuleInstaller.Abstractions", "src\Volo.Abp.Studio.ModuleInstaller.Abstractions\Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj", "{99679BF9-B888-4814-8E85-F751984CAFF8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2271296E-33FD-46BE-97FD-9938193CB7D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2271296E-33FD-46BE-97FD-9938193CB7D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2271296E-33FD-46BE-97FD-9938193CB7D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2271296E-33FD-46BE-97FD-9938193CB7D1}.Release|Any CPU.Build.0 = Release|Any CPU + {1C86021F-E522-41A1-AC3F-01B0E474D75E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C86021F-E522-41A1-AC3F-01B0E474D75E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C86021F-E522-41A1-AC3F-01B0E474D75E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C86021F-E522-41A1-AC3F-01B0E474D75E}.Release|Any CPU.Build.0 = Release|Any CPU + {28132E4E-FFB9-45C4-99AD-1BCA04B3E597}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28132E4E-FFB9-45C4-99AD-1BCA04B3E597}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28132E4E-FFB9-45C4-99AD-1BCA04B3E597}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28132E4E-FFB9-45C4-99AD-1BCA04B3E597}.Release|Any CPU.Build.0 = Release|Any CPU + {4FA11334-D727-4C14-9D71-1DB46AC3BE9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FA11334-D727-4C14-9D71-1DB46AC3BE9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FA11334-D727-4C14-9D71-1DB46AC3BE9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FA11334-D727-4C14-9D71-1DB46AC3BE9C}.Release|Any CPU.Build.0 = Release|Any CPU + {99679BF9-B888-4814-8E85-F751984CAFF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99679BF9-B888-4814-8E85-F751984CAFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99679BF9-B888-4814-8E85-F751984CAFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99679BF9-B888-4814-8E85-F751984CAFF8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2271296E-33FD-46BE-97FD-9938193CB7D1} = {344A1096-CC05-42D1-BDDB-E254C27508A9} + {1C86021F-E522-41A1-AC3F-01B0E474D75E} = {344A1096-CC05-42D1-BDDB-E254C27508A9} + {28132E4E-FFB9-45C4-99AD-1BCA04B3E597} = {344A1096-CC05-42D1-BDDB-E254C27508A9} + {4FA11334-D727-4C14-9D71-1DB46AC3BE9C} = {344A1096-CC05-42D1-BDDB-E254C27508A9} + {99679BF9-B888-4814-8E85-F751984CAFF8} = {344A1096-CC05-42D1-BDDB-E254C27508A9} + EndGlobalSection +EndGlobal diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo.Abp.Studio.Analyzing.Abstractions.csproj b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo.Abp.Studio.Analyzing.Abstractions.csproj new file mode 100644 index 0000000000..2b0847ae72 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo.Abp.Studio.Analyzing.Abstractions.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + + + + + + + + diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/AbpStudioAnalyzingAbstractionsModule.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/AbpStudioAnalyzingAbstractionsModule.cs new file mode 100644 index 0000000000..6935ae3755 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/AbpStudioAnalyzingAbstractionsModule.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Studio.Analyzing +{ + public class AbpStudioAnalyzingAbstractionsModule : AbpModule + { + + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Application/ApplicationServiceModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Application/ApplicationServiceModel.cs new file mode 100644 index 0000000000..3618b58711 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Application/ApplicationServiceModel.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Application +{ + [PackageContentItemName(ContentTypeName)] + public class ApplicationServiceModel : PackageContentItemModel + { + public const string ContentTypeName = "applicationService"; + + public string Namespace { get; set; } + + public string Summary { get; set; } + + public List ImplementingInterfaces { get; set; } + + public ApplicationServiceModel([NotNull] string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Authorization/PermissionModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Authorization/PermissionModel.cs new file mode 100644 index 0000000000..a386f5c4d5 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Authorization/PermissionModel.cs @@ -0,0 +1,24 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Authorization +{ + [PackageContentItemName(ContentTypeName)] + public class PermissionModel : PackageContentItemModel + { + public const string ContentTypeName = "permission"; + + public string DisplayName { get; } + + public bool IsEnabled { get; } + + public PermissionModel( + [NotNull] string name, + string displayName, + bool isEnabled) + : base(name) + { + DisplayName = displayName; + IsEnabled = isEnabled; + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseCollectionModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseCollectionModel.cs new file mode 100644 index 0000000000..5e78f54f87 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseCollectionModel.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Database +{ + [PackageContentItemName(ContentTypeName)] + public class DatabaseCollectionModel : PackageContentItemModel + { + public const string ContentTypeName = "databaseCollection"; + + public string EntityFullName { get; private set; } + + public DatabaseCollectionModel([NotNull] string name, string entityFullName) : base(name) + { + EntityFullName = Check.NotNullOrWhiteSpace(entityFullName, nameof(entityFullName)); + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseTableModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseTableModel.cs new file mode 100644 index 0000000000..a2af1acdbb --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/DatabaseTableModel.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Database +{ + [PackageContentItemName(ContentTypeName)] + public class DatabaseTableModel : PackageContentItemModel + { + public const string ContentTypeName = "databaseTable"; + + public string EntityFullName { get; private set; } + + public DatabaseTableModel([NotNull] string name, string entityFullName) : base(name) + { + EntityFullName = Check.NotNullOrWhiteSpace(entityFullName, nameof(entityFullName)); + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/EfCoreDbContextModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/EfCoreDbContextModel.cs new file mode 100644 index 0000000000..292b58e65f --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/EfCoreDbContextModel.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Database +{ + [PackageContentItemName(ContentTypeName)] + public class EfCoreDbContextModel : PackageContentItemModel, IDbContextModel + { + public const string ContentTypeName = "efCoreDbContext"; + + public string Namespace { get; private set; } + + public string ConnectionStringName { get; set; } + + public List DatabaseTables { get; set; } + + public EfCoreDbContextModel( + [NotNull] string name, + [NotNull] string @namespace + ) : base(name) + { + Namespace = Check.NotNullOrWhiteSpace(@namespace, nameof(@namespace)); + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/IDbContextModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/IDbContextModel.cs new file mode 100644 index 0000000000..08c00162f5 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/IDbContextModel.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Studio.Analyzing.Models.Database +{ + public interface IDbContextModel + { + string ConnectionStringName { get; set; } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/MongoDbContextModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/MongoDbContextModel.cs new file mode 100644 index 0000000000..6fa6c80f79 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Database/MongoDbContextModel.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Database +{ + [PackageContentItemName(ContentTypeName)] + public class MongoDbContextModel : PackageContentItemModel, IDbContextModel + { + public const string ContentTypeName = "mongoDbContext"; + + public string Namespace { get; private set; } + + public string ConnectionStringName { get; set; } + + public List DatabaseCollections { get; set; } + + public MongoDbContextModel( + [NotNull] string name, + [NotNull] string @namespace + ) : base(name) + { + Namespace = Check.NotNullOrWhiteSpace(@namespace, nameof(@namespace)); + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/AggregateRootModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/AggregateRootModel.cs new file mode 100644 index 0000000000..f31e07d8b1 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/AggregateRootModel.cs @@ -0,0 +1,12 @@ +namespace Volo.Abp.Studio.Analyzing.Models.Domain +{ + [PackageContentItemName(ContentTypeName)] + public class AggregateRootModel : EntityModel + { + public new const string ContentTypeName = "aggregateRoot"; + + public AggregateRootModel(string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/DomainServiceModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/DomainServiceModel.cs new file mode 100644 index 0000000000..6b4a648bcd --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/DomainServiceModel.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Domain +{ + [PackageContentItemName(ContentTypeName)] + public class DomainServiceModel : PackageContentItemModel + { + public const string ContentTypeName = "domainService"; + + public string Namespace { get; set; } + + public string Summary { get; set; } + + public DomainServiceModel([NotNull] string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/EntityModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/EntityModel.cs new file mode 100644 index 0000000000..0b3e5a5708 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/EntityModel.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Studio.Analyzing.Models.Domain +{ + [PackageContentItemName(ContentTypeName)] + public class EntityModel : PackageContentItemModel + { + public const string ContentTypeName = "entity"; + + public string Namespace { get; set; } + + public string PrimaryKeyType { get; set; } + + public string Summary { get; set; } + + public List CollectionProperties { get; set; } + public List NavigationProperties { get; set; } + + public EntityModel(string name) : base(name) + { + CollectionProperties = new List(); + NavigationProperties = new List(); + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/RepositoryInterfaceModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/RepositoryInterfaceModel.cs new file mode 100644 index 0000000000..a44613b335 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Domain/RepositoryInterfaceModel.cs @@ -0,0 +1,20 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Domain +{ + [PackageContentItemName(ContentTypeName)] + public class RepositoryInterfaceModel : PackageContentItemModel + { + public const string ContentTypeName = "repositoryInterface"; + + public string Namespace { get; set; } + + public string Summary { get; set; } + + public EntityModel EntityModel { get; set; } + + public RepositoryInterfaceModel([NotNull] string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Feature/FeatureModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Feature/FeatureModel.cs new file mode 100644 index 0000000000..ee2b7ef48b --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Feature/FeatureModel.cs @@ -0,0 +1,40 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Feature +{ + [PackageContentItemName(ContentTypeName)] + public class FeatureModel : PackageContentItemModel + { + public const string ContentTypeName = "feature"; + + public string ValueType { get; } + + public string DefaultValue { get; } + + public string DisplayName { get; } + + public string Description { get; } + + public bool IsAvailableToHost { get; } + + public bool IsVisibleToClients { get; } + + public FeatureModel( + [NotNull] string name, + [NotNull] string valueType, + string defaultValue, + string displayName, + string description, + bool isAvailableToHost, + bool isVisibleToClients + ) : base(name) + { + ValueType = valueType; + DefaultValue = defaultValue; + DisplayName = displayName; + Description = description; + IsAvailableToHost = isAvailableToHost; + IsVisibleToClients = isVisibleToClients; + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Module/AbpModuleModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Module/AbpModuleModel.cs new file mode 100644 index 0000000000..9094d7d0b8 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Module/AbpModuleModel.cs @@ -0,0 +1,16 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Module +{ + [PackageContentItemName(ContentTypeName)] + public class AbpModuleModel : PackageContentItemModel + { + public const string ContentTypeName = "abpModule"; + + public string Namespace { get; set; } + + public AbpModuleModel([NotNull] string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemModel.cs new file mode 100644 index 0000000000..749ecd8fa9 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemModel.cs @@ -0,0 +1,16 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models +{ + public abstract class PackageContentItemModel + { + public string ContentType { get; } + public string Name { get; } + + public PackageContentItemModel([NotNull] string name) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + ContentType = PackageContentItemNameAttribute.GetName(GetType()); + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemNameAttribute.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemNameAttribute.cs new file mode 100644 index 0000000000..9a04fa274b --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentItemNameAttribute.cs @@ -0,0 +1,26 @@ +using System; +using Volo.Abp.Reflection; + +namespace Volo.Abp.Studio.Analyzing.Models +{ + public class PackageContentItemNameAttribute : Attribute + { + public string Name { get; } + + public PackageContentItemNameAttribute(string name) + { + Name = name; + } + + public static string GetName(Type type) + { + var attribute = ReflectionHelper.GetSingleAttributeOrDefault(type); + if (attribute == null) + { + throw new ApplicationException($"Given type {type.FullName} must have an {nameof(PackageContentItemNameAttribute)}, but not defined!"); + } + + return attribute.Name; + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentList.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentList.cs new file mode 100644 index 0000000000..ab519cb264 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageContentList.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Studio.Analyzing.Models +{ + public class PackageContentList : List + { + + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageModel.cs new file mode 100644 index 0000000000..74bcaac9cf --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/PackageModel.cs @@ -0,0 +1,20 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models +{ + public class PackageModel + { + public string Name { get; } + + public string Hash { get; } + + public PackageContentList Contents { get; } + + public PackageModel([NotNull] string name, [NotNull] string hash) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + Contents = new PackageContentList(); + Hash = hash; + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Setting/SettingModel.cs b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Setting/SettingModel.cs new file mode 100644 index 0000000000..910f81099f --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Analyzing.Abstractions/Volo/Abp/Studio/Analyzing/Models/Setting/SettingModel.cs @@ -0,0 +1,26 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing.Models.Setting +{ + [PackageContentItemName(ContentTypeName)] + public class SettingModel : PackageContentItemModel + { + public const string ContentTypeName = "setting"; + + public string DefaultValue { get; set; } + + public string DisplayName { get; set; } + + public string Description { get; set; } + + public bool IsVisibleToClient { get; set; } + + public bool IsInherited { get; set; } + + public bool IsEncrypted { get; set; } + + public SettingModel([NotNull] string name) : base(name) + { + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo.Abp.Studio.Domain.CommonServices.csproj b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo.Abp.Studio.Domain.CommonServices.csproj new file mode 100644 index 0000000000..b63a2e30be --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo.Abp.Studio.Domain.CommonServices.csproj @@ -0,0 +1,21 @@ + + + + + + net5.0 + true + + + + + + + + + + + + + + diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioDomainCommonServicesModule.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioDomainCommonServicesModule.cs new file mode 100644 index 0000000000..84b2dba930 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioDomainCommonServicesModule.cs @@ -0,0 +1,17 @@ +using System.IO.Abstractions; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Studio +{ + [DependsOn( + typeof(AbpStudioDomainSharedModule) + )] + public class AbpStudioDomainCommonServicesModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(new FileSystem()); + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioException.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioException.cs new file mode 100644 index 0000000000..418e6067b9 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/AbpStudioException.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.Serialization; +using Microsoft.Extensions.Logging; + +namespace Volo.Abp.Studio +{ + public class AbpStudioException : BusinessException + { + public AbpStudioException( + string code = null, + string message = null, + string details = null, + Exception innerException = null, + LogLevel logLevel = LogLevel.Warning) + : base(code, message, details, innerException, logLevel) + { + Code = code; + Details = details; + LogLevel = logLevel; + } + + public AbpStudioException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) + { + + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/CmdHelper.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/CmdHelper.cs new file mode 100644 index 0000000000..3b8b8f0775 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/CmdHelper.cs @@ -0,0 +1,103 @@ +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Studio.Helpers +{ + //todo: move this to volo.abp.cli.core! + public class CmdHelper : ICmdHelper, ITransientDependency + { + public void RunCmd(string command, string workingDirectory = null) + { + var procStartInfo = new ProcessStartInfo( + GetFileName(), + GetArguments(command) + ); + + if (!string.IsNullOrEmpty(workingDirectory)) + { + procStartInfo.WorkingDirectory = workingDirectory; + } + + using (var process = Process.Start(procStartInfo)) + { + process?.WaitForExit(); + } + } + + public string RunCmdAndGetOutput(string command, string workingDirectory = null) + { + string output; + + using (var process = new Process()) + { + process.StartInfo = new ProcessStartInfo(GetFileName()) + { + Arguments = GetArguments(command), + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + if (!string.IsNullOrEmpty(workingDirectory)) + { + process.StartInfo.WorkingDirectory = workingDirectory; + } + + process.Start(); + + using (var standardOutput = process.StandardOutput) + { + using (var standardError = process.StandardError) + { + output = standardOutput.ReadToEnd(); + output += standardError.ReadToEnd(); + } + } + + process.WaitForExit(); + } + + return output.Trim(); + } + + private string GetArguments(string command) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return "-c \"" + command + "\""; + } + + //Windows default. + return "/C \"" + command + "\""; + } + + private string GetFileName() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + //Windows + return "cmd.exe"; + } + + //Linux or OSX + if (File.Exists("/bin/bash")) + { + return "/bin/bash"; + } + + if (File.Exists("/bin/sh")) + { + return "/bin/sh"; //some Linux distributions like Alpine doesn't have bash + } + + throw new AbpException($"Cannot determine shell command for this OS! " + + $"Running on OS: {System.Runtime.InteropServices.RuntimeInformation.OSDescription} | " + + $"OS Architecture: {System.Runtime.InteropServices.RuntimeInformation.OSArchitecture} | " + + $"Framework: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription} | " + + $"Process Architecture{System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture}"); + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/ICmdHelper.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/ICmdHelper.cs new file mode 100644 index 0000000000..f91bc7e69a --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/ICmdHelper.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Studio.Helpers +{ + public interface ICmdHelper + { + void RunCmd(string command, string workingDirectory = null); + + string RunCmdAndGetOutput(string command, string workingDirectory = null); + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/PathHelper.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/PathHelper.cs new file mode 100644 index 0000000000..b741e37cf8 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Helpers/PathHelper.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Helpers +{ + public static class PathHelper + { + public static string GetRelativePath([NotNull] string basePath, [NotNull] string targetPath) + { + Check.NotNull(basePath, nameof(basePath)); + Check.NotNull(targetPath, nameof(targetPath)); + + return new Uri(basePath).MakeRelativeUri(new Uri(targetPath)).ToString(); + } + + public static string EnsureForwardSlash(string path) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return path.Replace("\\", "/"); + } + + return path; + } + + public static string Normalize(string path) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return path.Replace("/", "\\"); + } + + return path; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/AbpModuleFileManager.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/AbpModuleFileManager.cs new file mode 100644 index 0000000000..ccb90ad2e4 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/AbpModuleFileManager.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.IO.Abstractions; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Studio.Packages.Modifying +{ + public class AbpModuleFileManager : IAbpModuleFileManager, ITransientDependency + { + public IFileSystem FileSystem { get; } + + public AbpModuleFileManager(IFileSystem fileSystem) + { + FileSystem = fileSystem; + } + + public async Task AddDependency(string filePath, string moduleToAdd) + { + var fileContent = await FileSystem.File.ReadAllTextAsync(filePath); + var moduleName = moduleToAdd.Split(".").Last(); + var moduleNamespace = moduleToAdd.RemovePostFix("." + moduleName); + var usingStatement = $"using {moduleNamespace};"; + var dependsOnStart = $"DependsOn("; + + if (fileContent.Contains($"typeof({moduleName})")) + { + // module already added + return; + } + + if (!fileContent.NormalizeLineEndings().SplitToLines().Any(l=> l.Trim().StartsWith("namespace ") && l.Contains(moduleNamespace)) && + !fileContent.Contains(usingStatement) + ) + { + fileContent = usingStatement + Environment.NewLine + fileContent; + } + + if (!fileContent.Contains(dependsOnStart)) + { + var fileLines = fileContent.NormalizeLineEndings().SplitToLines().ToList(); + fileLines.InsertBefore(l=> l.Contains("public") && l.Contains("class"), $" [DependsOn(typeof({moduleName}))]"); + fileContent = fileLines.JoinAsString(Environment.NewLine); + } + else + { + var fileLines = fileContent.NormalizeLineEndings().SplitToLines().ToList(); + var dependsOnStartLine = fileLines.First(l=> l.Contains(dependsOnStart)); + var dependsOnStartLineModified = dependsOnStartLine.Replace(dependsOnStart, + dependsOnStart + Environment.NewLine + + $" typeof({moduleName})," + ); + fileContent = fileContent.Replace(dependsOnStartLine, dependsOnStartLineModified); + } + + FileSystem.File.WriteAllTextAsync(filePath, fileContent); + } + + public async Task ExtractModuleNameWithNamespace(string filePath) + { + var fileContent = await FileSystem.File.ReadAllTextAsync(filePath); + + var fileLines = fileContent.NormalizeLineEndings().SplitToLines(); + + var lineOfClassName = fileLines.First(l=> l.Contains("public") && l.Contains("class")); + + var moduleName = lineOfClassName.Split(":")[0].Trim().Split(" ").Last(); + + var lineOfNamespace = fileLines.First(l=> l.Trim().StartsWith("namespace")); + + var moduleNamespace = lineOfNamespace.Split(" ").Skip(1).First(); + + return moduleNamespace + "." + moduleName; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/CsprojFileManager.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/CsprojFileManager.cs new file mode 100644 index 0000000000..4087f5d6ae --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/CsprojFileManager.cs @@ -0,0 +1,95 @@ +using System; +using System.Threading.Tasks; +using System.Xml; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Studio.Helpers; +using Volo.Abp.Studio.Xml; + +namespace Volo.Abp.Studio.Packages.Modifying +{ + public class CsprojFileManager: XmlFileManagerBase, ICsprojFileManager, ITransientDependency + { + public async Task AddProjectReferenceAsync(string filePath, string projectToReference) + { + var document = await GetXmlDocumentAsync(filePath); + + if (document.SelectNodes($"/Project/ItemGroup/ProjectReference[starts-with(@Include, '{projectToReference}')]").Count > 0) + { + // Project reference is already added. + return; + } + + var relativePath = PathHelper.GetRelativePath(filePath, projectToReference); + + var itemGroupNode = GetOrCreateItemGroupNode(document); + + var newNode = document.CreateElement("ProjectReference"); + + var includeAttr = document.CreateAttribute("Include"); + includeAttr.Value = relativePath; + newNode.Attributes.Append(includeAttr); + + itemGroupNode.AppendChild(newNode); + + await SaveXmlDocumentAsync(filePath, document); + } + + public async Task AddPackageReferenceAsync(string filePath, string packageName, string version) + { + var document = await GetXmlDocumentAsync(filePath); + + if (document.SelectNodes($"/Project/ItemGroup/PackageReference[starts-with(@Include, '{packageName}')]").Count > 0) + { + // Package reference is already added. + return; + } + + var itemGroupNode = GetOrCreateItemGroupNode(document); + + var newNode = document.CreateElement("PackageReference"); + + var includeAttr = document.CreateAttribute("Include"); + includeAttr.Value = packageName; + newNode.Attributes.Append(includeAttr); + + var versionAttr = document.CreateAttribute("Version"); + versionAttr.Value = version; + newNode.Attributes.Append(versionAttr); + + itemGroupNode.AppendChild(newNode); + itemGroupNode.AppendChild(document.CreateWhitespace(Environment.NewLine + " ")); + + await SaveXmlDocumentAsync(filePath, document); + } + + private XmlNode GetOrCreateItemGroupNode(XmlDocument document) + { + var nodes = document["Project"].SelectNodes("ItemGroup"); + + if (nodes == null || nodes.Count < 1) + { + var newNode = document.CreateElement("ItemGroup"); + document["Project"].AppendChild(newNode); + return newNode; + } + + foreach (XmlNode node in nodes) + { + if (node.SelectNodes("ProjectReference").Count > 0) + { + return node; + } + } + + foreach (XmlNode node in nodes) + { + if (node.SelectNodes("PackageReference").Count > 0) + { + return node; + } + } + + return nodes[0]; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/IAbpModuleFileManager.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/IAbpModuleFileManager.cs new file mode 100644 index 0000000000..7eb2060e48 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/IAbpModuleFileManager.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.Packages.Modifying +{ + public interface IAbpModuleFileManager + { + Task AddDependency(string filePath, string moduleToAdd); + + Task ExtractModuleNameWithNamespace(string filePath); + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/ICsprojFileManager.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/ICsprojFileManager.cs new file mode 100644 index 0000000000..29aa3f34b3 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Modifying/ICsprojFileManager.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.Packages.Modifying +{ + public interface ICsprojFileManager + { + Task AddProjectReferenceAsync(string filePath, string projectToReference); + + Task AddPackageReferenceAsync(string filePath, string packageName, string version); + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/INugetSourceCodeStore.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/INugetSourceCodeStore.cs new file mode 100644 index 0000000000..6fce22dbe0 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/INugetSourceCodeStore.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.Nuget +{ + public interface INugetSourceCodeStore + { + Task GetCachedSourceCodeFilePathAsync(string name, + string type, + string version = null, + bool includePreReleases = false); + + Task GetCachedDllFilePathAsync(string name, + string type, + string version = null, + bool includePreReleases = false, + bool includeDependencies = false); + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetPackageCacheManager.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetPackageCacheManager.cs new file mode 100644 index 0000000000..935ed85573 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetPackageCacheManager.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Studio.Helpers; + +namespace Volo.Abp.Studio.Nuget +{ + public class NugetPackageCacheManager : ITransientDependency + { + private readonly ICmdHelper _cmdHelper; + + public NugetPackageCacheManager(ICmdHelper cmdHelper) + { + _cmdHelper = cmdHelper; + } + + public async Task CachePackageAsync(string packageName, string version, bool deleteAfter = true) + { + var temporaryFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + + Directory.CreateDirectory(temporaryFolder); + + _cmdHelper.RunCmdAndGetOutput("dotnet new console -lang c#", temporaryFolder); + _cmdHelper.RunCmdAndGetOutput($"dotnet add package {packageName} --version {version}", temporaryFolder); + + if (deleteAfter) + { + Directory.Delete(temporaryFolder, true); + } + + return temporaryFolder; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetSourceCodeStore.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetSourceCodeStore.cs new file mode 100644 index 0000000000..52613f2f49 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/NugetSourceCodeStore.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Cli.NuGet; +using Volo.Abp.Cli.ProjectBuilding; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Studio.Helpers; + +namespace Volo.Abp.Studio.Nuget +{ + [Dependency(ReplaceServices = true)] + public class NugetSourceCodeStore : ISourceCodeStore, INugetSourceCodeStore, ITransientDependency + { + private readonly NuGetService _nuGetService; + private readonly NugetPackageCacheManager _nugetPackageCacheManager; + private readonly ICmdHelper _cmdHelper; + + public NugetSourceCodeStore( + NuGetService nuGetService, + NugetPackageCacheManager nugetPackageCacheManager, + ICmdHelper cmdHelper) + { + _nuGetService = nuGetService; + _nugetPackageCacheManager = nugetPackageCacheManager; + _cmdHelper = cmdHelper; + } + + public async Task GetAsync( + string name, + string type, + string version = null, + string templateSource = null, + bool includePreReleases = false) + { + if (type == SourceCodeTypes.Template) + { + name = TemplateNugetPackageInfoProvider.GetNugetPackageName(name); + } + + var latestVersion = await GetLatestVersionAsync(name, includePreReleases); + + if (version == null) + { + version = latestVersion; + } + + var localCachedFilePath = await GetLocalCacheSourceCodeFilePathInternal(name, version); + + return new TemplateFile(await File.ReadAllBytesAsync(localCachedFilePath), version, latestVersion, latestVersion); + } + + public async Task GetCachedSourceCodeFilePathAsync(string name, string type, string version = null, + bool includePreReleases = false) + { + if (type == SourceCodeTypes.Template) + { + name = TemplateNugetPackageInfoProvider.GetNugetPackageName(name); + } + + if (version == null) + { + version = await GetLatestVersionAsync(name, includePreReleases); + } + + return await GetLocalCacheSourceCodeFilePathInternal(name, version); + } + + public async Task GetCachedDllFilePathAsync(string name, string type, string version = null, bool includePreReleases = false, bool includeDependencies = false) + { + if (type == SourceCodeTypes.Template) + { + name = TemplateNugetPackageInfoProvider.GetNugetPackageName(name); + } + + if (version == null) + { + version = await GetLatestVersionAsync(name, includePreReleases); + } + + var localDllFolder = Path.Combine( + GetLocalNugetCachePath(), + name, + version, + "lib"); + + if (!Directory.Exists(localDllFolder) || + (includeDependencies && !Directory.GetFiles(localDllFolder, $"*Volo.Abp.Studio.ModuleInstaller.dll", SearchOption.AllDirectories).Any())) + { + if (includeDependencies) + { + var temporaryFolder = await _nugetPackageCacheManager.CachePackageAsync(name, version, false); + + var outputFolder = Path.GetDirectoryName( + Directory + .GetFiles(localDllFolder, $"*{name}.dll", SearchOption.AllDirectories) + .First() + ); + + _cmdHelper.RunCmdAndGetOutput($"dotnet build -o {outputFolder}", temporaryFolder); + + Directory.Delete(temporaryFolder, true); + } + else + { + await _nugetPackageCacheManager.CachePackageAsync(name, version); + } + } + + if (!Directory.Exists(localDllFolder)) + { + return null; + } + + return Directory.GetFiles(localDllFolder, $"{name}.dll", SearchOption.AllDirectories).First(); + } + + private async Task GetLatestVersionAsync(string nugetPackage, bool includePreReleases) + { + var v = await _nuGetService.GetLatestVersionOrNullAsync(nugetPackage, includePreReleases); + + return v.ToString(); + } + + private async Task GetLocalCacheSourceCodeFilePathInternal(string name, string version) + { + var localCacheFile = Path.Combine( + GetLocalNugetCachePath(), + name, + version, + "content", + $"{name}.zip"); + + + if (!File.Exists(localCacheFile)) + { + await _nugetPackageCacheManager.CachePackageAsync(name, version); + } + + return localCacheFile; + } + + private string GetLocalNugetCachePath() + { + return Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".nuget", + "packages"); + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/TemplateNugetPackageInfoProvider.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/TemplateNugetPackageInfoProvider.cs new file mode 100644 index 0000000000..7654279fec --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Nuget/TemplateNugetPackageInfoProvider.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.Nuget +{ + public static class TemplateNugetPackageInfoProvider + { + public static string GetNugetPackageName(string template) + { + switch (template) + { + case "app": + return "Cotur.Basic.Template"; // todo: replace with real template! + default: + return null; + } + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Xml/XmlFileManagerBase.cs b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Xml/XmlFileManagerBase.cs new file mode 100644 index 0000000000..74eb5379c2 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.CommonServices/Volo/Abp/Studio/Xml/XmlFileManagerBase.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using System.IO.Abstractions; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; +using Volo.Abp.Threading; + +namespace Volo.Abp.Studio.Xml +{ + public abstract class XmlFileManagerBase + { + public IFileSystem FileSystem { get; set; } + + public ICancellationTokenProvider CancellationTokenProvider { get; set; } + + protected async Task GetXmlDocumentAsync(string filePath) + { + try + { + var doc = new XmlDocument() { PreserveWhitespace = true }; + doc.Load(GenerateStreamFromString(await FileSystem.File.ReadAllTextAsync(filePath))); + return doc; + } + catch (Exception ex) + { + throw new AbpException($"Error while reading {filePath} as XML document.", innerException: ex); + } + } + + protected async Task SaveXmlDocumentAsync(string filePath, XmlDocument rootNode) + { + await SaveFileContentAsync(filePath, XDocument.Parse(rootNode.OuterXml).ToString()); + } + + protected async Task SaveFileContentAsync(string filePath, string content) + { + await FileSystem.File.WriteAllTextAsync(filePath, content, CancellationTokenProvider.Token); + } + + private MemoryStream GenerateStreamFromString(string s) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.Shared/Volo.Abp.Studio.Domain.Shared.csproj b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo.Abp.Studio.Domain.Shared.csproj new file mode 100644 index 0000000000..23144285d3 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo.Abp.Studio.Domain.Shared.csproj @@ -0,0 +1,15 @@ + + + + + + netstandard2.0 + + + + + + + + + diff --git a/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioDomainSharedModule.cs b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioDomainSharedModule.cs new file mode 100644 index 0000000000..9693bc2577 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioDomainSharedModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Cli; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Studio +{ + [DependsOn( + typeof(AbpCliCoreModule) + )] + public class AbpStudioDomainSharedModule : AbpModule + { + + } +} diff --git a/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioErrorCodes.cs b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioErrorCodes.cs new file mode 100644 index 0000000000..e687f840d7 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.Domain.Shared/Volo/Abp/Studio/AbpStudioErrorCodes.cs @@ -0,0 +1,30 @@ +namespace Volo.Abp.Studio +{ + public static class AbpStudioErrorCodes + { + public const string SolutionAlreadyExists = "AbpStudio:SolutionAlreadyExists"; + public const string ModuleAlreadyExistsInTheSolution = "AbpStudio:ModuleAlreadyExistsInTheSolution"; + public const string ModuleFileAlreadyExists = "AbpStudio:ModuleFileAlreadyExists"; + public const string IncorrectFileFormat = "AbpStudio:IncorrectFileFormat"; + public const string ModuleNotFound = "AbpStudio:ModuleNotFound"; + public const string ModuleNotSpecified = "AbpStudio:ModuleNotSpecified"; + public const string SolutionNotSpecified = "AbpStudio:SolutionNotSpecified"; + public const string ProjectAlreadyExistInTheModule = "AbpStudio:ProjectAlreadyExistInTheModule"; + public const string IncorrectSolutionFileFormat = "AbpStudio:IncorrectSolutionFileFormat"; + public const string FolderNotFound = "AbpStudio:FolderNotFound"; + public const string ProjectWithSameNameAlreadyExistInTheSolutionFile = "AbpStudio:ProjectWithSameNameAlreadyExistInTheSolutionFile"; + public const string UndefinedPackageTemplate = "AbpStudio:UndefinedPackageTemplate"; + public const string PackageTemplateNotSpecified = "AbpStudio:PackageTemplateNotSpecified"; + public const string PackageNameMustBeSpecified = "AbpStudio:PackageNameMustBeSpecified"; + public const string FileAlreadyExists = "AbpStudio:FileAlreadyExists"; + public const string PackageNotSpecified = "AbpStudio:PackageNotSpecified"; + public const string DbmsMustBeSpecified = "AbpStudio:DbmsMustBeSpecified"; + public const string UserNotLoggedIn = "AbpStudio:UserNotLoggedIn"; + public const string PackageAlreadyExist = "AbpStudio:PackageAlreadyExist"; + public const string AbpModuleFileNotFound = "AbpStudio:AbpModuleFileNotFound"; + public const string DllNotFound = "AbpStudio:DllNotFound"; + public const string PackageNotFound = "AbpStudio:PackageNotFound"; + public const string FileNotFound = "AbpStudio:FileNotFound"; + public const string IncorrectFolderName = "AbpStudio:IncorrectFolderName "; + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj new file mode 100644 index 0000000000..143944d975 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/AbpStudioModuleInstallerAbstractionsModule.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/AbpStudioModuleInstallerAbstractionsModule.cs new file mode 100644 index 0000000000..c9e68ec940 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/AbpStudioModuleInstallerAbstractionsModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Modularity; +using Volo.Abp.Studio.Analyzing; + +namespace Volo.Abp.Studio +{ + [DependsOn( + typeof(AbpStudioAnalyzingAbstractionsModule) + )] + public class AbpStudioModuleInstallerAbstractionsModule : AbpModule + { + + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/Analyzing/AnalyzingOptions.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/Analyzing/AnalyzingOptions.cs new file mode 100644 index 0000000000..7296dfce74 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/Analyzing/AnalyzingOptions.cs @@ -0,0 +1,45 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Studio.Analyzing +{ + public class AnalyzingOptions + { + public bool Force { get; set; } = false; + + [CanBeNull] + public string AnalyzeConfigurationFile { get; set; } + + [CanBeNull] + public string SettingNamePrefix { get; set; } + + [CanBeNull] + public string FeatureNamePrefix { get; set; } + + // Combines two options + // The second option has more priority + public static AnalyzingOptions Combine([CanBeNull] AnalyzingOptions first, [CanBeNull] AnalyzingOptions second) + { + if (second == null && first == null) + { + return new AnalyzingOptions(); + } + + if (second == null) + { + return first; + } + + if (first == null) + { + return second; + } + + return new AnalyzingOptions + { + AnalyzeConfigurationFile = second.AnalyzeConfigurationFile ?? first.AnalyzeConfigurationFile, + SettingNamePrefix = second.SettingNamePrefix ?? first.SettingNamePrefix, + FeatureNamePrefix = second.FeatureNamePrefix ?? first.FeatureNamePrefix + }; + } + } +} \ No newline at end of file diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/IModuleInstallingPipelineBuilder.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/IModuleInstallingPipelineBuilder.cs new file mode 100644 index 0000000000..1112328675 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/IModuleInstallingPipelineBuilder.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.ModuleInstalling +{ + public interface IModuleInstallingPipelineBuilder + { + Task BuildAsync(ModuleInstallingContext context); + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingContext.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingContext.cs new file mode 100644 index 0000000000..06393b210e --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingContext.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using Volo.Abp.Studio.Packages; + +namespace Volo.Abp.Studio.ModuleInstalling +{ + public class ModuleInstallingContext + { + public bool WithSourceCode { get; set; } + + public bool AddToSolutionFile { get; set; } + + public string Version { get; set; } + + public List TargetModulePackages { get; protected set; } + + public List ReferenceModulePackages { get; protected set; } + + public Dictionary Options { get; } + + public IServiceProvider ServiceProvider { get; } + + public ModuleInstallingContext( + bool withSourceCode, + bool addToSolutionFile, + string version, + Dictionary options, + IServiceProvider serviceProvider) + { + WithSourceCode = withSourceCode; + AddToSolutionFile = addToSolutionFile; + Version = version; + Options = options; + + TargetModulePackages = new List(); + ReferenceModulePackages = new List(); + + ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); + } + + public void SetReferenceModulePackages([NotNull] List referenceModulePackages) + { + Check.NotNull(referenceModulePackages, nameof(referenceModulePackages)); + + ReferenceModulePackages = referenceModulePackages; + } + + public void SetTargetModulePackages([NotNull] List targetModulePackages) + { + Check.NotNull(targetModulePackages, nameof(targetModulePackages)); + + TargetModulePackages = targetModulePackages; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipeline.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipeline.cs new file mode 100644 index 0000000000..82d77780f7 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipeline.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.ModuleInstalling +{ + public class ModuleInstallingPipeline + { + public ModuleInstallingContext Context { get; } + + public List Steps { get; } + + public ModuleInstallingPipeline(ModuleInstallingContext context) + { + Context = context; + Steps = new List(); + } + + public async Task ExecuteAsync() + { + foreach (var step in Steps) + { + await step.ExecuteAsync(Context); + } + } + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineStep.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineStep.cs new file mode 100644 index 0000000000..b98d32b32a --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller.Abstractions/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineStep.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Studio.ModuleInstalling +{ + public abstract class ModuleInstallingPipelineStep + { + public abstract Task ExecuteAsync(ModuleInstallingContext context); + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo.Abp.Studio.ModuleInstaller.csproj b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo.Abp.Studio.ModuleInstaller.csproj new file mode 100644 index 0000000000..25d0e8cbeb --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo.Abp.Studio.ModuleInstaller.csproj @@ -0,0 +1,16 @@ + + + + + + net5.0 + true + + + + + + + + + diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/AbpStudioModuleInstallerModule.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/AbpStudioModuleInstallerModule.cs new file mode 100644 index 0000000000..3450ab8a5c --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/AbpStudioModuleInstallerModule.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Studio +{ + [DependsOn( + typeof(AbpStudioDomainCommonServicesModule), + typeof(AbpStudioModuleInstallerAbstractionsModule) + )] + public class AbpStudioModuleInstallerModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + + } + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineBuilderBase.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineBuilderBase.cs new file mode 100644 index 0000000000..8bc8a65304 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/ModuleInstallingPipelineBuilderBase.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Studio.ModuleInstalling.Steps; + +namespace Volo.Abp.Studio.ModuleInstalling +{ + public abstract class ModuleInstallingPipelineBuilderBase + { + protected ModuleInstallingPipeline GetBasePipeline(ModuleInstallingContext context) + { + var pipeline = new ModuleInstallingPipeline(context); + + pipeline.Steps.Add(new PackageReferencingStep()); + + return pipeline; + } + } +} diff --git a/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/Steps/PackageReferencingStep.cs b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/Steps/PackageReferencingStep.cs new file mode 100644 index 0000000000..94f97ff9d2 --- /dev/null +++ b/studio/src/Volo.Abp.Studio.ModuleInstaller/Volo/Abp/Studio/ModuleInstalling/Steps/PackageReferencingStep.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Studio.Packages; +using Volo.Abp.Studio.Packages.Modifying; +using Volo.Abp.Studio.Analyzing.Models.Module; + +namespace Volo.Abp.Studio.ModuleInstalling.Steps +{ + public class PackageReferencingStep : ModuleInstallingPipelineStep + { + public override async Task ExecuteAsync(ModuleInstallingContext context) + { + var _csprojFileManager = context.ServiceProvider.GetRequiredService(); + var _abpModuleFileManager = context.ServiceProvider.GetRequiredService(); + + foreach (var referencePackage in context.ReferenceModulePackages) + { + var targetPackages = GetTargetPackages(context.TargetModulePackages, referencePackage); + + foreach (var targetPackage in targetPackages) + { + await _csprojFileManager.AddPackageReferenceAsync( + targetPackage.Path.RemovePostFix(PackageConsts.FileExtension) + ".csproj", + referencePackage.Name, + context.Version); + + var targetAbpModulePath = FindAbpModuleFile(targetPackage.Path); + + await _abpModuleFileManager.AddDependency(targetAbpModulePath, FindAbpModuleName(referencePackage)); + } + } + } + + private string FindAbpModuleFile(string targetPackagePath) + { + return Directory.GetFiles(Path.GetDirectoryName(targetPackagePath), "*Module.cs", + SearchOption.AllDirectories) + .FirstOrDefault(); + } + + private string FindAbpModuleName(PackageInfoWithAnalyze package) + { + var abpModuleModel = package.Analyze.Contents.Where(y => + y.ContentType == AbpModuleModel.ContentTypeName + ).Cast().First(); + + return abpModuleModel.Namespace + "." + abpModuleModel.Name; + } + + private List GetTargetPackages(List targetModulePackages, + PackageInfoWithAnalyze referencePackage) + { + if (PackageTypes.IsHostProject(referencePackage.Role)) + { + return new List(); + } + + if (PackageTypes.IsUiProject(referencePackage.Role)) + { + var useHostBlazorServerForMvcPackages = targetModulePackages.All(p => p.Role != PackageTypes.HostMvc); + var targetHostType = + PackageTypes.GetHostTypeOfUi(referencePackage.Role, useHostBlazorServerForMvcPackages); + + return targetModulePackages.Where(p => p.Role == targetHostType).ToList(); + } + + return targetModulePackages.Where(p => p.Role == referencePackage.Role).ToList(); + } + } +}