mirror of https://github.com/abpframework/abp.git
committed by
GitHub
8 changed files with 310 additions and 46 deletions
@ -0,0 +1,84 @@ |
|||
using System; |
|||
using System.IO; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectModification |
|||
{ |
|||
public class DbContextFileBuilderConfigureAdder : ITransientDependency |
|||
{ |
|||
public ILogger<DbContextFileBuilderConfigureAdder> Logger { get; set; } |
|||
|
|||
protected UsingStatementAdder UsingStatementAdder { get; } |
|||
|
|||
public DbContextFileBuilderConfigureAdder(UsingStatementAdder usingStatementAdder) |
|||
{ |
|||
UsingStatementAdder = usingStatementAdder; |
|||
Logger = NullLogger<DbContextFileBuilderConfigureAdder>.Instance; |
|||
} |
|||
|
|||
public void Add(string path, string moduleConfiguration) |
|||
{ |
|||
var file = File.ReadAllText(path); |
|||
|
|||
file = UsingStatementAdder.Add(file, GetNamespace(moduleConfiguration)); |
|||
|
|||
var stringToAdd = GetLineToAdd(moduleConfiguration); |
|||
if (!file.Contains(stringToAdd)) |
|||
{ |
|||
var indexToInsert = FindIndexToInsert(file); |
|||
|
|||
if (indexToInsert <= 0 || indexToInsert >= file.Length) |
|||
{ |
|||
Logger.LogWarning($"\"OnModelCreating(ModelBuilder builder)\" method couldn't be found in {path}"); |
|||
return; |
|||
} |
|||
file = file.Insert(indexToInsert, " " + stringToAdd + Environment.NewLine + " "); |
|||
} |
|||
|
|||
|
|||
File.WriteAllText(path, file); |
|||
} |
|||
|
|||
protected int FindIndexToInsert(string file) |
|||
{ |
|||
var indexOfMethodDeclaration = file.IndexOf("OnModelCreating(", StringComparison.Ordinal); |
|||
var indexOfOpeningBracket = indexOfMethodDeclaration + file.Substring(indexOfMethodDeclaration).IndexOf('{'); |
|||
|
|||
var stack = 1; |
|||
var index = indexOfOpeningBracket; |
|||
|
|||
while (stack > 0) |
|||
{ |
|||
index++; |
|||
|
|||
if (index >= file.Length) |
|||
{ |
|||
break; |
|||
} |
|||
|
|||
if (file[index] == '{') |
|||
{ |
|||
stack++; |
|||
} |
|||
else if (file[index] == '}') |
|||
{ |
|||
stack--; |
|||
} |
|||
} |
|||
|
|||
return index; |
|||
} |
|||
|
|||
protected string GetLineToAdd(string moduleConfiguration) |
|||
{ |
|||
return "builder." + moduleConfiguration.Split(':')[1] + "();"; |
|||
} |
|||
|
|||
protected string GetNamespace(string moduleConfiguration) |
|||
{ |
|||
return string.Join(".", moduleConfiguration.Split(':')[0]); |
|||
} |
|||
} |
|||
} |
|||
@ -1,42 +1,83 @@ |
|||
using System.Collections.Generic; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Microsoft.CodeAnalysis.CSharp; |
|||
using Microsoft.CodeAnalysis.CSharp.Syntax; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectModification |
|||
{ |
|||
public class DerivedClassFinder : ITransientDependency |
|||
{ |
|||
public ILogger<DerivedClassFinder> Logger { get; set; } |
|||
|
|||
public DerivedClassFinder() |
|||
{ |
|||
Logger = NullLogger<DerivedClassFinder>.Instance; |
|||
} |
|||
|
|||
public virtual List<string> Find(string csprojFilePath, string baseClass) |
|||
{ |
|||
var moduleFilePaths = new List<string>(); |
|||
var csprojFileDirectory = Path.GetDirectoryName(csprojFilePath); |
|||
var binFile = Path.Combine(csprojFileDirectory, "bin"); |
|||
var objFile = Path.Combine(csprojFileDirectory, "obj"); |
|||
|
|||
|
|||
var csFiles = new DirectoryInfo(Path.GetDirectoryName(csprojFilePath)) |
|||
var csFiles = new DirectoryInfo(csprojFileDirectory) |
|||
.GetFiles("*.cs", SearchOption.AllDirectories) |
|||
.Where(f => !f.DirectoryName.StartsWith(binFile)) |
|||
.Where(f => !f.DirectoryName.StartsWith(objFile)) |
|||
.Select(f => f.FullName) |
|||
.ToList(); |
|||
|
|||
foreach (var csFile in csFiles) |
|||
{ |
|||
if (IsDerivedFromAbpModule(csFile, baseClass)) |
|||
try |
|||
{ |
|||
moduleFilePaths.Add(csFile); |
|||
if (IsDerived(csFile, baseClass)) |
|||
{ |
|||
moduleFilePaths.Add(csFile); |
|||
} |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
Logger.LogDebug($"Couldn't parse {csFile}."); |
|||
} |
|||
} |
|||
|
|||
return moduleFilePaths; |
|||
} |
|||
|
|||
protected bool IsDerivedFromAbpModule(string csFile, string baseClass) |
|||
protected bool IsDerived(string csFile, string baseClass) |
|||
{ |
|||
Logger.LogDebug(csFile); |
|||
var root = CSharpSyntaxTree.ParseText(File.ReadAllText(csFile)).GetRoot(); |
|||
var namespaceSyntax = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().First(); |
|||
var classDeclaration = (namespaceSyntax.DescendantNodes().OfType<ClassDeclarationSyntax>()).First(); |
|||
var baseTypeList = classDeclaration.BaseList?.Types.Select(t => t.ToString()).ToList(); |
|||
|
|||
if (baseTypeList == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
foreach (var baseType in baseTypeList) |
|||
{ |
|||
if (baseType.Contains('<') && baseType.Substring(0, baseType.IndexOf('<')) == baseClass) |
|||
{ |
|||
return true; |
|||
} |
|||
if (baseType == baseClass) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return classDeclaration.BaseList?.Types |
|||
.Any(t => t.ToString().Equals(baseClass)) ?? false; |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,47 @@ |
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectModification |
|||
{ |
|||
public class EfCoreMigrationAdder : ITransientDependency |
|||
{ |
|||
public void AddMigration(string csprojFile, string module, bool updateDatabase = true) |
|||
{ |
|||
var moduleName = ParseModuleName(module); |
|||
var migrationName = "Added_" + moduleName + "_Module" + GetUniquePostFix(); |
|||
|
|||
var process = Process.Start("CMD.exe", "/C cd \"" + Path.GetDirectoryName(csprojFile) + "\" & dotnet ef migrations add " + migrationName); |
|||
process.WaitForExit(); |
|||
|
|||
if (updateDatabase) |
|||
{ |
|||
UpdateDatabase(csprojFile); |
|||
} |
|||
} |
|||
|
|||
protected void UpdateDatabase(string csprojFile) |
|||
{ |
|||
var process = Process.Start("CMD.exe", "/C cd \"" + Path.GetDirectoryName(csprojFile) + "\" & dotnet ef database update"); |
|||
process.WaitForExit(); |
|||
} |
|||
|
|||
protected virtual string ParseModuleName(string fullModuleName) |
|||
{ |
|||
var words = fullModuleName?.Split('.'); |
|||
|
|||
if (words == null || words.Length <= 1) |
|||
{ |
|||
return ""; |
|||
} |
|||
|
|||
return words[words.Length - 1]; |
|||
} |
|||
|
|||
protected virtual string GetUniquePostFix() |
|||
{ |
|||
return "_" + new Random().Next(1,99999); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectModification |
|||
{ |
|||
public class UsingStatementAdder : ITransientDependency |
|||
{ |
|||
public string Add(string fileContent, string nameSpace) |
|||
{ |
|||
if (fileContent.Contains(nameSpace)) |
|||
{ |
|||
return fileContent; |
|||
} |
|||
|
|||
var index = GetIndexOfTheEndOfTheLastUsingStatement(fileContent); |
|||
|
|||
if (index < 0 || index >= fileContent.Length) |
|||
{ |
|||
index = 0; |
|||
} |
|||
|
|||
var usingStatement = GetUsingStatement(nameSpace); |
|||
|
|||
return fileContent.Insert(index, usingStatement); |
|||
} |
|||
|
|||
protected string GetUsingStatement(string nameSpace) |
|||
{ |
|||
return Environment.NewLine + "using " + nameSpace + ";"; |
|||
} |
|||
|
|||
protected virtual int GetIndexOfTheEndOfTheLastUsingStatement(string fileContent) |
|||
{ |
|||
var indexOfNamespaceDeclaration = fileContent.IndexOf("namespace", StringComparison.Ordinal); |
|||
|
|||
if (indexOfNamespaceDeclaration < 0) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
fileContent = fileContent.Substring(0, indexOfNamespaceDeclaration); |
|||
|
|||
var indexOfTheStartOfLastUsingStatement = |
|||
fileContent.LastIndexOf("using ", StringComparison.Ordinal); |
|||
|
|||
if (indexOfTheStartOfLastUsingStatement < 0) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
var indexOfFirstSemiColonAfterLastUsingStatement = |
|||
fileContent.Substring(indexOfTheStartOfLastUsingStatement).IndexOf(';'); |
|||
|
|||
if (indexOfFirstSemiColonAfterLastUsingStatement < 0) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
return indexOfTheStartOfLastUsingStatement |
|||
+ indexOfFirstSemiColonAfterLastUsingStatement + 1; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue