Moved studio modules

pull/10363/head
Yunus Emre Kalkan 4 years ago
parent 0871ea462c
commit e96be6e824

@ -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",

@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\volo\abp\studio\backend\src\Volo.Abp.Studio.ModuleInstaller\Volo.Abp.Studio.ModuleInstaller.csproj" />
<ProjectReference Include="..\..\..\..\studio\src\Volo.Abp.Studio.ModuleInstaller\Volo.Abp.Studio.ModuleInstaller.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
</ItemGroup>

@ -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"
)

@ -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

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.Core\Volo.Abp.Core.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,9 @@
using Volo.Abp.Modularity;
namespace Volo.Abp.Studio.Analyzing
{
public class AbpStudioAnalyzingAbstractionsModule : AbpModule
{
}
}

@ -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<string> ImplementingInterfaces { get; set; }
public ApplicationServiceModel([NotNull] string name) : base(name)
{
}
}
}

@ -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;
}
}
}

@ -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));
}
}
}

@ -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));
}
}
}

@ -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<DatabaseTableModel> DatabaseTables { get; set; }
public EfCoreDbContextModel(
[NotNull] string name,
[NotNull] string @namespace
) : base(name)
{
Namespace = Check.NotNullOrWhiteSpace(@namespace, nameof(@namespace));
}
}
}

@ -0,0 +1,7 @@
namespace Volo.Abp.Studio.Analyzing.Models.Database
{
public interface IDbContextModel
{
string ConnectionStringName { get; set; }
}
}

@ -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<DatabaseCollectionModel> DatabaseCollections { get; set; }
public MongoDbContextModel(
[NotNull] string name,
[NotNull] string @namespace
) : base(name)
{
Namespace = Check.NotNullOrWhiteSpace(@namespace, nameof(@namespace));
}
}
}

@ -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)
{
}
}
}

@ -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)
{
}
}
}

@ -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<string> CollectionProperties { get; set; }
public List<string> NavigationProperties { get; set; }
public EntityModel(string name) : base(name)
{
CollectionProperties = new List<string>();
NavigationProperties = new List<string>();
}
}
}

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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)
{
}
}
}

@ -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());
}
}
}

@ -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<PackageContentItemNameAttribute>(type);
if (attribute == null)
{
throw new ApplicationException($"Given type {type.FullName} must have an {nameof(PackageContentItemNameAttribute)}, but not defined!");
}
return attribute.Name;
}
}
}

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Volo.Abp.Studio.Analyzing.Models
{
public class PackageContentList : List<PackageContentItemModel>
{
}
}

@ -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;
}
}
}

@ -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)
{
}
}
}

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.IO.Abstractions" Version="13.2.28" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Studio.Domain.Shared\Volo.Abp.Studio.Domain.Shared.csproj" />
</ItemGroup>
</Project>

@ -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<IFileSystem>(new FileSystem());
}
}
}

@ -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)
{
}
}
}

@ -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}");
}
}
}

@ -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);
}
}

@ -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;
}
}
}

@ -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<string> 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;
}
}
}

@ -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];
}
}
}

@ -0,0 +1,11 @@
using System.Threading.Tasks;
namespace Volo.Abp.Studio.Packages.Modifying
{
public interface IAbpModuleFileManager
{
Task AddDependency(string filePath, string moduleToAdd);
Task<string> ExtractModuleNameWithNamespace(string filePath);
}
}

@ -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);
}
}

@ -0,0 +1,18 @@
using System.Threading.Tasks;
namespace Volo.Abp.Studio.Nuget
{
public interface INugetSourceCodeStore
{
Task<string> GetCachedSourceCodeFilePathAsync(string name,
string type,
string version = null,
bool includePreReleases = false);
Task<string> GetCachedDllFilePathAsync(string name,
string type,
string version = null,
bool includePreReleases = false,
bool includeDependencies = false);
}
}

@ -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<string> 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;
}
}
}

@ -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<TemplateFile> 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<string> 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<string> 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<string> GetLatestVersionAsync(string nugetPackage, bool includePreReleases)
{
var v = await _nuGetService.GetLatestVersionOrNullAsync(nugetPackage, includePreReleases);
return v.ToString();
}
private async Task<string> 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");
}
}
}

@ -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;
}
}
}
}

@ -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<XmlDocument> 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;
}
}
}

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.Cli.Core\Volo.Abp.Cli.Core.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
using Volo.Abp.Cli;
using Volo.Abp.Modularity;
namespace Volo.Abp.Studio
{
[DependsOn(
typeof(AbpCliCoreModule)
)]
public class AbpStudioDomainSharedModule : AbpModule
{
}
}

@ -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 ";
}
}

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Studio.Analyzing.Abstractions\Volo.Abp.Studio.Analyzing.Abstractions.csproj" />
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.Core\Volo.Abp.Core.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
using Volo.Abp.Modularity;
using Volo.Abp.Studio.Analyzing;
namespace Volo.Abp.Studio
{
[DependsOn(
typeof(AbpStudioAnalyzingAbstractionsModule)
)]
public class AbpStudioModuleInstallerAbstractionsModule : AbpModule
{
}
}

@ -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
};
}
}
}

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.Studio.ModuleInstalling
{
public interface IModuleInstallingPipelineBuilder
{
Task<ModuleInstallingPipeline> BuildAsync(ModuleInstallingContext context);
}
}

@ -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<PackageInfo> TargetModulePackages { get; protected set; }
public List<PackageInfoWithAnalyze> ReferenceModulePackages { get; protected set; }
public Dictionary<string,string> Options { get; }
public IServiceProvider ServiceProvider { get; }
public ModuleInstallingContext(
bool withSourceCode,
bool addToSolutionFile,
string version,
Dictionary<string,string> options,
IServiceProvider serviceProvider)
{
WithSourceCode = withSourceCode;
AddToSolutionFile = addToSolutionFile;
Version = version;
Options = options;
TargetModulePackages = new List<PackageInfo>();
ReferenceModulePackages = new List<PackageInfoWithAnalyze>();
ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider));
}
public void SetReferenceModulePackages([NotNull] List<PackageInfoWithAnalyze> referenceModulePackages)
{
Check.NotNull(referenceModulePackages, nameof(referenceModulePackages));
ReferenceModulePackages = referenceModulePackages;
}
public void SetTargetModulePackages([NotNull] List<PackageInfo> targetModulePackages)
{
Check.NotNull(targetModulePackages, nameof(targetModulePackages));
TargetModulePackages = targetModulePackages;
}
}
}

@ -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<ModuleInstallingPipelineStep> Steps { get; }
public ModuleInstallingPipeline(ModuleInstallingContext context)
{
Context = context;
Steps = new List<ModuleInstallingPipelineStep>();
}
public async Task ExecuteAsync()
{
foreach (var step in Steps)
{
await step.ExecuteAsync(Context);
}
}
}
}

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.Studio.ModuleInstalling
{
public abstract class ModuleInstallingPipelineStep
{
public abstract Task ExecuteAsync(ModuleInstallingContext context);
}
}

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Studio.Domain.CommonServices\Volo.Abp.Studio.Domain.CommonServices.csproj" />
<ProjectReference Include="..\Volo.Abp.Studio.ModuleInstaller.Abstractions\Volo.Abp.Studio.ModuleInstaller.Abstractions.csproj" />
</ItemGroup>
</Project>

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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<ICsprojFileManager>();
var _abpModuleFileManager = context.ServiceProvider.GetRequiredService<IAbpModuleFileManager>();
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<AbpModuleModel>().First();
return abpModuleModel.Namespace + "." + abpModuleModel.Name;
}
private List<PackageInfo> GetTargetPackages(List<PackageInfo> targetModulePackages,
PackageInfoWithAnalyze referencePackage)
{
if (PackageTypes.IsHostProject(referencePackage.Role))
{
return new List<PackageInfo>();
}
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();
}
}
}
Loading…
Cancel
Save