Implemented SolutionModuleAdder

pull/1466/head^2
Halil ibrahim Kalkan 7 years ago
parent c4a61242d8
commit 9e4764a395

@ -36,7 +36,7 @@ namespace Volo.Abp.Cli.Commands
);
}
private string GetSolutionFile(CommandLineArgs commandLineArgs)
protected virtual string GetSolutionFile(CommandLineArgs commandLineArgs)
{
var providedSolutionFile = PathHelper.NormalizePath(
commandLineArgs.Options.GetOrNull(

@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace Volo.Abp.ProjectModification
{
public class ModuleInfo
{
public string Name { get; set; }
public string DisplayName { get; set; }
public List<NugetPackageInfo> NugetPackages { get; set; }
public List<NpmPackageInfo> NpmPackages { get; set; }
}
}

@ -5,7 +5,5 @@
public string Name { get; set; }
public int ApplicationType { get; set; } //TODO: Enum?
public bool IsPro { get; set; }
}
}

@ -6,7 +6,7 @@
public string ModuleClass { get; set; }
public int Target { get; set; } //TODO: Enum?
public NugetPackageTarget Target { get; set; }
public NpmPackageInfo DependedNpmPackage { get; set; }
}

@ -0,0 +1,15 @@
namespace Volo.Abp.ProjectModification
{
public enum NugetPackageTarget : byte
{
DomainShared = 1,
Domain = 2,
ApplicationContracts = 3,
Application = 4,
HttpApi = 5,
HttpApiClient = 6,
Web = 7,
EntityFrameworkCore = 8,
MongoDB = 9
}
}

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IO;
namespace Volo.Abp.ProjectModification
{
@ -26,15 +27,16 @@ namespace Volo.Abp.ProjectModification
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();
using (DirectoryHelper.ChangeCurrentDirectory(directory))
{
Logger.LogInformation("yarn add " + npmPackage.Name + "... " + Directory.GetCurrentDirectory());
var procStartInfo = new ProcessStartInfo("cmd.exe", "/C yarn add " + npmPackage.Name);
Process.Start(procStartInfo).WaitForExit();
Logger.LogInformation("gulp...");
procStartInfo = new ProcessStartInfo("cmd.exe", "/C gulp");
procStartInfo.WindowStyle = ProcessWindowStyle.Normal;
Process.Start(procStartInfo).WaitForExit();
Logger.LogInformation("gulp... " + Directory.GetCurrentDirectory());
procStartInfo = new ProcessStartInfo("cmd.exe", "/C gulp");
Process.Start(procStartInfo).WaitForExit();
}
return Task.CompletedTask;
}

@ -1,13 +1,16 @@
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
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.Cli;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IO;
using Volo.Abp.Json;
namespace Volo.Abp.ProjectModification
@ -36,29 +39,45 @@ namespace Volo.Abp.ProjectModification
public async Task AddAsync(string projectFile, string packageName)
{
var packageInfo = await FindNugetPackageInfoAsync(packageName);
if (packageInfo == null)
await AddAsync(
projectFile,
await FindNugetPackageInfoAsync(packageName)
);
}
public async Task AddAsync(string projectFile, NugetPackageInfo package)
{
using (DirectoryHelper.ChangeCurrentDirectory(Path.GetDirectoryName(projectFile)))
{
return;
}
Logger.LogInformation($"Installing '{package.Name}' package to the project '{Path.GetFileNameWithoutExtension(projectFile)}'...");
Logger.LogInformation($"Installing '{packageName}' package to the project '{Path.GetFileNameWithoutExtension(projectFile)}'...");
var procStartInfo = new ProcessStartInfo("dotnet", "add package " + packageName);
Process.Start(procStartInfo).WaitForExit();
var procStartInfo = new ProcessStartInfo("dotnet", "add package " + package.Name);
Process.Start(procStartInfo).WaitForExit();
var moduleFile = ModuleClassFinder.Find(projectFile).First();
//TODO: Handle multiple module classes!
ModuleClassDependcyAdder.Add(moduleFile, packageInfo.ModuleClass);
var moduleFiles = ModuleClassFinder.Find(projectFile);
if (moduleFiles.Count == 0)
{
throw new CliUsageException($"Could not find a class derived from AbpModule in the project {projectFile}");
}
if (packageInfo.DependedNpmPackage != null)
{
await NpmPackageAdder.AddAsync(Path.GetDirectoryName(projectFile), packageInfo.DependedNpmPackage);
}
if (moduleFiles.Count > 1)
{
throw new CliUsageException($"There are multiple classes derived from AbpModule in the project {projectFile}: " + moduleFiles.JoinAsString(", "));
}
ModuleClassDependcyAdder.Add(moduleFiles.First(), package.ModuleClass);
if (package.DependedNpmPackage != null)
{
await NpmPackageAdder.AddAsync(Path.GetDirectoryName(projectFile), package.DependedNpmPackage);
}
Logger.LogInformation("Successfully installed.");
Logger.LogInformation("Successfully installed.");
}
}
private async Task<NugetPackageInfo> FindNugetPackageInfoAsync(string moduleName)
protected virtual async Task<NugetPackageInfo> FindNugetPackageInfoAsync(string moduleName)
{
using (var client = new HttpClient())
{
@ -70,14 +89,10 @@ namespace Volo.Abp.ProjectModification
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
Logger.LogError($"ERROR: '{moduleName}' module could not be found.");
}
else
{
Logger.LogError($"ERROR: Remote server returns '{response.StatusCode}'");
throw new CliUsageException($"'{moduleName}' nuget package could not be found!");
}
return null;
throw new Exception($"ERROR: Remote server returns '{response.StatusCode}'");
}
var responseContent = await response.Content.ReadAsStringAsync();

@ -1,17 +1,147 @@
using System.Threading.Tasks;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Volo.Abp.Cli;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace Volo.Abp.ProjectModification
{
public class SolutionModuleAdder : ITransientDependency
{
public virtual async Task AddAsync([NotNull] string solutionFile, [NotNull] string moduleName)
public ILogger<SolutionModuleAdder> Logger { get; set; }
protected IJsonSerializer JsonSerializer { get; }
protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; }
public SolutionModuleAdder(
IJsonSerializer jsonSerializer,
ProjectNugetPackageAdder projectNugetPackageAdder)
{
JsonSerializer = jsonSerializer;
ProjectNugetPackageAdder = projectNugetPackageAdder;
Logger = NullLogger<SolutionModuleAdder>.Instance;
}
public virtual async Task AddAsync(
[NotNull] string solutionFile,
[NotNull] string moduleName)
{
Check.NotNull(solutionFile, nameof(solutionFile));
Check.NotNull(moduleName, nameof(moduleName));
var module = await FindModuleInfoAsync(moduleName);
var projectFiles = GetProjectFiles(solutionFile);
foreach (var nugetPackage in module.NugetPackages)
{
var targetProjectFile = FindTargetProjectFile(projectFiles, nugetPackage.Target);
if (targetProjectFile == null)
{
continue;
}
await ProjectNugetPackageAdder.AddAsync(targetProjectFile, nugetPackage);
}
}
private string FindTargetProjectFile(string[] projectFiles, NugetPackageTarget target)
{
if (!projectFiles.Any())
{
return null;
}
var assemblyNames = projectFiles
.Select(
filePath => filePath
.Replace("\\", "/")
.Substring(filePath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1)
.RemovePostFix(StringComparison.OrdinalIgnoreCase, ".csproj")
).ToArray();
switch (target)
{
case NugetPackageTarget.Web:
return FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.EntityFrameworkCore:
return FindProjectEndsWith(assemblyNames, ".EntityFrameworkCore") ??
FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.MongoDB:
return FindProjectEndsWith(assemblyNames, ".MongoDB") ??
FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.Application:
return FindProjectEndsWith(assemblyNames, ".Application") ??
FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.ApplicationContracts:
return FindProjectEndsWith(assemblyNames, ".Application.Contracts");
case NugetPackageTarget.Domain:
return FindProjectEndsWith(assemblyNames, ".Domain") ??
FindProjectEndsWith(assemblyNames, ".Application") ??
FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.DomainShared:
return FindProjectEndsWith(assemblyNames, ".Domain.Shared");
case NugetPackageTarget.HttpApi:
return FindProjectEndsWith(assemblyNames, ".HttpApi") ??
FindProjectEndsWith(assemblyNames, ".Web");
case NugetPackageTarget.HttpApiClient:
return FindProjectEndsWith(assemblyNames, ".HttpApi.Client");
default:
throw new ApplicationException($"{nameof(NugetPackageTarget)} has not implemented: {target}");
}
}
private static string FindProjectEndsWith(string[] projectAssemblyNames, string postfix)
{
return projectAssemblyNames.FirstOrDefault(p => p.EndsWith(postfix, StringComparison.OrdinalIgnoreCase));
}
protected virtual string[] GetProjectFiles(string solutionFile)
{
var baseProjectFolder = GetBaseProjectFolder(solutionFile);
return Directory.GetFiles(baseProjectFolder, "*.csproj", SearchOption.AllDirectories);
}
protected virtual string GetBaseProjectFolder(string solutionFile)
{
var baseFolder = Path.GetDirectoryName(solutionFile);
var srcFolder = Path.Combine(baseFolder, "src");
if (Directory.Exists(srcFolder))
{
baseFolder = srcFolder;
}
return baseFolder;
}
protected virtual async Task<ModuleInfo> FindModuleInfoAsync(string moduleName)
{
using (var client = new HttpClient())
{
var url = "https://localhost:44328/api/app/module/byName/?name=" + moduleName;
var response = await client.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new CliUsageException($"ERROR: '{moduleName}' module could not be found!");
}
throw new Exception($"ERROR: Remote server returns '{response.StatusCode}'");
}
var responseContent = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<ModuleInfo>(responseContent);
}
}
}
}

@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using JetBrains.Annotations;
namespace Volo.Abp.IO
@ -45,5 +46,22 @@ namespace Volo.Abp.IO
return IsSubDirectoryOf(parentDirectory, parentOfChild);
}
public static IDisposable ChangeCurrentDirectory(string targetDirectory)
{
var currentDirectory = Directory.GetCurrentDirectory();
if (currentDirectory.Equals(targetDirectory, StringComparison.OrdinalIgnoreCase))
{
return NullDisposable.Instance;
}
Directory.SetCurrentDirectory(targetDirectory);
return new DisposeAction(() =>
{
Directory.SetCurrentDirectory(currentDirectory);
});
}
}
}

Loading…
Cancel
Save