From c8bf413cfeb3cc5a39719871487bc150a2b60d38 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 8 May 2019 22:24:54 +0300 Subject: [PATCH] Implemented add-module to project (initial, will be refactored). --- .../Volo.Abp.Cli.Core.csproj | 1 + .../Volo/Abp/Cli/AbpCliCoreModule.cs | 2 +- .../Volo/Abp/Cli/CliService.cs | 5 +- .../{AddCommand.cs => AddModuleCommand.cs} | 8 +- .../ProjectModification/AbpModuleFinder.cs | 71 ++++++++++++++++ .../Abp/ProjectModification/DependsOnAdder.cs | 45 +++++++++++ .../Abp/ProjectModification/ModuleAdder.cs | 8 +- .../Abp/ProjectModification/NpmPackageInfo.cs | 11 +++ .../ProjectModification/NugetPackageInfo.cs | 13 +++ .../ProjectModification/ProjectModuleAdder.cs | 13 --- .../ProjectNpmPackageAdder.cs | 42 ++++++++++ .../ProjectNugetPackageAdder.cs | 81 +++++++++++++++++++ 12 files changed, 277 insertions(+), 23 deletions(-) rename framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/{AddCommand.cs => AddModuleCommand.cs} (85%) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/AbpModuleFinder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/DependsOnAdder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NpmPackageInfo.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NugetPackageInfo.cs delete mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectModuleAdder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNpmPackageAdder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNugetPackageAdder.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index 41cb647649..46b59109c7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -17,6 +17,7 @@ + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 2dd39cdfce..101e9134d7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Cli { options.Commands["help"] = typeof(HelpCommand); options.Commands["new"] = typeof(NewCommand); - options.Commands["add"] = typeof(AddCommand); + options.Commands["add-module"] = typeof(AddModuleCommand); options.Commands["login"] = typeof(LoginCommand); options.Commands["logout"] = typeof(LogoutCommand); }); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index 502ab294e6..854eabea96 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -13,7 +13,10 @@ namespace Volo.Abp.Cli { public class CliService : ITransientDependency { - public static string Version => typeof(AbpCliCoreModule).Assembly.GetFileVersion(); + //public static string Version => typeof(AbpCliCoreModule).Assembly + // .GetFileVersion() + // .RemovePostFix(".0"); + public static string Version => "0.17.0.0"; public ILogger Logger { get; set; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs similarity index 85% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddCommand.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs index e5034725ba..6c5209c2e4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs @@ -7,16 +7,16 @@ using Volo.Abp.ProjectModification; namespace Volo.Abp.Cli.Commands { - public class AddCommand : IConsoleCommand, ITransientDependency + public class AddModuleCommand : IConsoleCommand, ITransientDependency { - public ILogger Logger { get; set; } + public ILogger Logger { get; set; } protected ModuleAdder ModuleAdder { get; } - public AddCommand(ModuleAdder moduleAdder) + public AddModuleCommand(ModuleAdder moduleAdder) { ModuleAdder = moduleAdder; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } public async Task ExecuteAsync(CommandLineArgs commandLineArgs) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/AbpModuleFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/AbpModuleFinder.cs new file mode 100644 index 0000000000..ca02137154 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/AbpModuleFinder.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Volo.Abp.ProjectModification +{ + public class AbpModuleFinder + { + public List Find(string csprojFilePath) + { + var modules = new List(); + + var csFiles = GetAllCsFilesUnderDirectory(Path.GetDirectoryName(csprojFilePath), new List()); + + foreach (var csFile in csFiles) + { + try + { + var root = CSharpSyntaxTree.ParseText(File.ReadAllText(csFile)).GetRoot(); + + var namespaceSyntaxs = root.DescendantNodes().OfType(); + + foreach (var namespaceSyntax in namespaceSyntaxs) + { + var classDeclarationSyntaxs = namespaceSyntax.DescendantNodes().OfType(); + var syntaxsArray = classDeclarationSyntaxs as ClassDeclarationSyntax[] ?? classDeclarationSyntaxs.ToArray(); + + foreach (var classDeclaration in syntaxsArray) + { + var classDerivedFromAbpModule = classDeclaration.BaseList?.Types.FirstOrDefault(t => t.ToString().Contains("AbpModule")); + + if (classDerivedFromAbpModule != null) + { + modules.Add(csFile); + } + } + } + } + catch (Exception) + { + //ignored! + } + } + + return modules; + } + + private static List GetAllCsFilesUnderDirectory(string path, List allCsFileList) + { + var directory = new DirectoryInfo(path); + var files = directory.GetFiles("*.cs").Select(f => f.DirectoryName + "\\" + f.Name).ToList(); + + foreach (var s in files) + { + allCsFileList.Add(s); + } + + var directories = directory.GetDirectories().Select(d => path + "\\" + d.Name).ToList(); + + foreach (var subDirectory in directories) + { + allCsFileList = GetAllCsFilesUnderDirectory(subDirectory, allCsFileList); + } + + return allCsFileList; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/DependsOnAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/DependsOnAdder.cs new file mode 100644 index 0000000000..d1dfd86d0a --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/DependsOnAdder.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using System.Linq; + +namespace Volo.Abp.ProjectModification +{ + public class DependsOnAdder + { + public void Add(string path, string module) + { + ParseModuleNameAndNameSpace(module, out var nameSpace, out var moduleName); + + var file = File.ReadAllText(path); + + var indexOfEndingPublicClass = file.IndexOf("public class", StringComparison.Ordinal); + + var dependsOnAttribute = "[DependsOn(" + moduleName + ")]" + Environment.NewLine + " "; + + file = file.Insert(indexOfEndingPublicClass, dependsOnAttribute); + file = file.Insert(0, GetUsingStatement(nameSpace) + Environment.NewLine); //TODO: Add as the last item in the using list! + + File.WriteAllText(path, file); + } + + private void ParseModuleNameAndNameSpace(string module, out string nameSpace, out string moduleName) + { + var words = module?.Split('.'); + + if (words == null || words.Length <= 1) + { + nameSpace = null; + moduleName = module; + return; + } + + moduleName = words[words.Length - 1]; + nameSpace = string.Join(".", words.Take(words.Length - 1)); + } + + private string GetUsingStatement(string nameSpace) + { + return "using " + nameSpace + ";"; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ModuleAdder.cs index b0e5f2a353..d6da6fea68 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ModuleAdder.cs @@ -15,12 +15,12 @@ namespace Volo.Abp.ProjectModification { public ILogger Logger { get; set; } - protected ProjectModuleAdder ProjectModuleAdder { get; } + protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; } protected SolutionModuleAdder SolutionModuleAdder { get; } - public ModuleAdder(ProjectModuleAdder projectModuleAdder, SolutionModuleAdder solutionModuleAdder) + public ModuleAdder(ProjectNugetPackageAdder projectNugetPackageAdder, SolutionModuleAdder solutionModuleAdder) { - ProjectModuleAdder = projectModuleAdder; + ProjectNugetPackageAdder = projectNugetPackageAdder; SolutionModuleAdder = solutionModuleAdder; Logger = NullLogger.Instance; @@ -43,7 +43,7 @@ namespace Volo.Abp.ProjectModification if (!args.ProjectFile.IsNullOrEmpty()) { - await ProjectModuleAdder.AddAsync(args.ProjectFile, args.ModuleName); + await ProjectNugetPackageAdder.AddAsync(args.ProjectFile, args.ModuleName); } if (!args.SolutionFile.IsNullOrEmpty()) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NpmPackageInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NpmPackageInfo.cs new file mode 100644 index 0000000000..09ee9a8042 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NpmPackageInfo.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.ProjectModification +{ + public class NpmPackageInfo + { + public string Name { get; set; } + + public int ApplicationType { get; set; } //TODO: Enum? + + public bool IsPro { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NugetPackageInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NugetPackageInfo.cs new file mode 100644 index 0000000000..59974f23d3 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/NugetPackageInfo.cs @@ -0,0 +1,13 @@ +namespace Volo.Abp.ProjectModification +{ + public class NugetPackageInfo + { + public string Name { get; set; } + + public string ModuleClass { get; set; } + + public int Target { get; set; } //TODO: Enum? + + public NpmPackageInfo DependedNpmPackage { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectModuleAdder.cs deleted file mode 100644 index 1960da10a5..0000000000 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectModuleAdder.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.ProjectModification -{ - public class ProjectModuleAdder : ITransientDependency - { - public async Task AddAsync(string projectFile, string moduleName) - { - - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNpmPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNpmPackageAdder.cs new file mode 100644 index 0000000000..e6566ce21f --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNpmPackageAdder.cs @@ -0,0 +1,42 @@ +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.ProjectModification +{ + public class ProjectNpmPackageAdder : ITransientDependency + { + public ILogger Logger { get; set; } + + public ProjectNpmPackageAdder() + { + Logger = NullLogger.Instance; + } + + public Task AddAsync(string directory, NpmPackageInfo npmPackage) + { + var packageJsonFilePath = Path.Combine(directory, "package.json"); + if (!File.Exists(packageJsonFilePath)) + { + return Task.CompletedTask; + } + + Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'..."); + + Logger.LogInformation("yarn add " + npmPackage.Name + "..."); + var procStartInfo = new ProcessStartInfo("cmd.exe", "/C yarn add " + npmPackage.Name); + procStartInfo.WindowStyle = ProcessWindowStyle.Normal; + Process.Start(procStartInfo).WaitForExit(); + + Logger.LogInformation("gulp..."); + procStartInfo = new ProcessStartInfo("cmd.exe", "/C gulp"); + procStartInfo.WindowStyle = ProcessWindowStyle.Normal; + Process.Start(procStartInfo).WaitForExit(); + + return Task.CompletedTask; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNugetPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNugetPackageAdder.cs new file mode 100644 index 0000000000..bf9c0f25f5 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/ProjectModification/ProjectNugetPackageAdder.cs @@ -0,0 +1,81 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; + +namespace Volo.Abp.ProjectModification +{ + public class ProjectNugetPackageAdder : ITransientDependency + { + public ILogger Logger { get; set; } + + protected IJsonSerializer JsonSerializer { get; } + protected ProjectNpmPackageAdder NpmPackageAdder { get; } + + public ProjectNugetPackageAdder( + IJsonSerializer jsonSerializer, + ProjectNpmPackageAdder npmPackageAdder) + { + JsonSerializer = jsonSerializer; + NpmPackageAdder = npmPackageAdder; + Logger = NullLogger.Instance; + } + + public async Task AddAsync(string projectFile, string packageName) + { + var packageInfo = await FindNugetPackageInfoAsync(packageName); + if (packageInfo == null) + { + return; + } + + Logger.LogInformation($"Installing '{packageName}' package to the project '{Path.GetFileNameWithoutExtension(projectFile)}'..."); + var procStartInfo = new ProcessStartInfo("dotnet", "add package " + packageName); + Process.Start(procStartInfo).WaitForExit(); + + var moduleFile = new AbpModuleFinder().Find(projectFile).First(); + new DependsOnAdder().Add(moduleFile, packageInfo.ModuleClass); + + if (packageInfo.DependedNpmPackage != null) + { + await NpmPackageAdder.AddAsync(Path.GetDirectoryName(projectFile), packageInfo.DependedNpmPackage); + } + + Logger.LogInformation("Successfully installed."); + } + + private async Task FindNugetPackageInfoAsync(string moduleName) + { + using (var client = new HttpClient()) + { + var url = "https://localhost:44328/api/app/nugetPackage/byName/?name=" + moduleName; + + var response = await client.GetAsync(url); + + if (!response.IsSuccessStatusCode) + { + if (response.StatusCode == HttpStatusCode.NotFound) + { + Logger.LogError($"ERROR: '{moduleName}' module could not be found."); + } + else + { + Logger.LogError($"ERROR: Remote server returns '{response.StatusCode}'"); + } + + return null; + } + + var responseContent = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(responseContent); + } + } + } +} \ No newline at end of file