Browse Source

Cli: Allow to generate code with Suite

resolves https://github.com/volosoft/volo/issues/9596
pull/12231/head
Yunus Emre Kalkan 4 years ago
parent
commit
8eaaf6b045
  1. 198
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs
  2. 16
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs
  3. 6
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ICmdHelper.cs

198
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs

@ -1,33 +1,51 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json.Linq;
using NuGet.Versioning;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.NuGet;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.Json;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.Commands;
public class SuiteCommand : IConsoleCommand, ITransientDependency
{
public const string Name = "suite";
public ICmdHelper CmdHelper { get; }
private readonly AbpNuGetIndexUrlService _nuGetIndexUrlService;
private readonly NuGetService _nuGetService;
private readonly CliHttpClientFactory _cliHttpClientFactory;
private const string SuitePackageName = "Volo.Abp.Suite";
public ILogger<SuiteCommand> Logger { get; set; }
public SuiteCommand(AbpNuGetIndexUrlService nuGetIndexUrlService, NuGetService nuGetService, ICmdHelper cmdHelper)
public SuiteCommand(
AbpNuGetIndexUrlService nuGetIndexUrlService,
NuGetService nuGetService,
ICmdHelper cmdHelper,
CliHttpClientFactory cliHttpClientFactory)
{
CmdHelper = cmdHelper;
_nuGetIndexUrlService = nuGetIndexUrlService;
_nuGetService = nuGetService;
_cliHttpClientFactory = cliHttpClientFactory;
Logger = NullLogger<SuiteCommand>.Instance;
}
@ -48,6 +66,13 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
RunSuite();
break;
case "generate":
await InstallSuiteIfNotInstalledAsync();
var suiteProcess = RunSuiteTemporary();
await GenerateCrudOnSuiteAsync(commandLineArgs);
suiteProcess?.Kill();
break;
case "install":
await InstallSuiteAsync(version, preview);
break;
@ -63,6 +88,115 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
}
}
private async Task GenerateCrudOnSuiteAsync(CommandLineArgs args)
{
var entityFile = args.Options.GetOrNull(Options.Crud.Entity.Short, Options.Crud.Entity.Long);
var solutionFile = args.Options.GetOrNull(Options.Crud.Solution.Short, Options.Crud.Solution.Long);
if (entityFile.IsNullOrEmpty() || !entityFile.EndsWith(".json") || !File.Exists(entityFile) ||
solutionFile.IsNullOrEmpty() || !solutionFile.EndsWith(".sln"))
{
throw new UserFriendlyException("Invalid Arguments!");
}
Logger.LogInformation("Generating CRUD Page...");
var client = _cliHttpClientFactory.CreateClient(false);
var solutionId = await GetSolutionIdAsync(client, solutionFile);
if (!solutionId.HasValue)
{
return;
}
var entityContent = new StringContent(
File.ReadAllText(entityFile),
Encoding.UTF8,
MimeTypes.Application.Json
);
var responseMessage = await client.PostAsync(
$"http://localhost:3000/api/abpSuite/crudPageGenerator/{solutionId.ToString()}/save-and-generate-entity",
entityContent
);
var response = await responseMessage.Content.ReadAsStringAsync();
if (!response.IsNullOrWhiteSpace())
{
Logger.LogError(response);
}
else
{
Logger.LogInformation("CRUD page generated.");
}
}
private async Task<Guid?> GetSolutionIdAsync(HttpClient client, string solutionPath)
{
var timeIntervals = new List<TimeSpan>();
for (var i = 0; i < 10; i++)
{
timeIntervals.Add(TimeSpan.FromSeconds(5));
}
var responseMessage = await client.GetHttpResponseMessageWithRetryAsync(
"http://localhost:3000/api/abpSuite/solutions",
_cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10)),
Logger,
timeIntervals.ToArray());
var response = await responseMessage.Content.ReadAsStringAsync();
JArray solutions;
try
{
solutions = (JArray)(JObject.Parse(response)["solutions"]);
}
catch (Exception)
{
Logger.LogError(response);
return await AddSolutionToSuiteAsync(client, solutionPath);
}
foreach (JObject solution in solutions)
{
if (solution["path"].ToString() == solutionPath)
{
return Guid.Parse(solution["id"].ToString());
}
}
return await AddSolutionToSuiteAsync(client, solutionPath);
}
private async Task<Guid?> AddSolutionToSuiteAsync(HttpClient client, string solutionPath)
{
var entityContent = new StringContent(
"{\"Path\": \"" + solutionPath.Replace("\\", "\\\\") + "\"}",
Encoding.UTF8,
MimeTypes.Application.Json
);
var responseMessage = await client.PostAsync(
"http://localhost:3000/api/abpSuite/addSolution",
entityContent,
_cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10))
);
var response = await responseMessage.Content.ReadAsStringAsync();
try
{
return Guid.Parse(JObject.Parse(response)["id"].ToString());
}
catch (Exception)
{
Logger.LogError(response);
return null;
}
}
private async Task InstallSuiteIfNotInstalledAsync()
{
var currentSuiteVersionAsString = GetCurrentSuiteVersion();
@ -132,7 +266,8 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
}
CmdHelper.RunCmd(
$"dotnet tool install {SuitePackageName}{versionOption} --add-source {nugetIndexUrl} -g", out int exitCode
$"dotnet tool install {SuitePackageName}{versionOption} --add-source {nugetIndexUrl} -g",
out int exitCode
);
if (exitCode == 0)
@ -155,7 +290,8 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
private void ShowSuiteManualInstallCommand()
{
Logger.LogInformation("You can also run the following command to install ABP Suite.");
Logger.LogInformation("dotnet tool install -g Volo.Abp.Suite --add-source https://nuget.abp.io/<your-private-key>/v3/index.json");
Logger.LogInformation(
"dotnet tool install -g Volo.Abp.Suite --add-source https://nuget.abp.io/<your-private-key>/v3/index.json");
}
private async Task UpdateSuiteAsync(string version = null, bool preview = false)
@ -202,7 +338,8 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
}
CmdHelper.RunCmd(
$"dotnet tool update {SuitePackageName}{versionOption} --add-source {nugetIndexUrl} -g", out int exitCode
$"dotnet tool update {SuitePackageName}{versionOption} --add-source {nugetIndexUrl} -g",
out int exitCode
);
if (exitCode != 0)
@ -231,7 +368,8 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
private void ShowSuiteManualUpdateCommand()
{
Logger.LogError("You can also run the following command to update ABP Suite.");
Logger.LogError("dotnet tool update -g Volo.Abp.Suite --add-source https://nuget.abp.io/<your-private-key>/v3/index.json");
Logger.LogError(
"dotnet tool update -g Volo.Abp.Suite --add-source https://nuget.abp.io/<your-private-key>/v3/index.json");
}
private void RemoveSuite()
@ -258,6 +396,37 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
CmdHelper.RunCmd("abp-suite");
}
private Process RunSuiteTemporary()
{
try
{
if (!GlobalToolHelper.IsGlobalToolInstalled("abp-suite"))
{
Logger.LogWarning(
"ABP Suite is not installed! To install it you can run the command: \"abp suite install\"");
return null;
}
}
catch (Exception ex)
{
Logger.LogWarning("Couldn't check ABP Suite installed status: " + ex.Message);
}
if (IsSuiteAlreadyRunning())
{
return null;
}
return CmdHelper.RunCmdAndGetProcess("abp-suite --no-browser");
}
bool IsSuiteAlreadyRunning()
{
var ipGP = IPGlobalProperties.GetIPGlobalProperties();
var endpoints = ipGP.GetActiveTcpListeners();
return endpoints.Any(e => e.Port == 3000);
}
public string GetUsageInfo()
{
var sb = new StringBuilder();
@ -306,5 +475,20 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency
public const string Long = "version";
public const string Short = "v";
}
public static class Crud
{
public static class Solution
{
public const string Long = "solution";
public const string Short = "s";
}
public static class Entity
{
public const string Long = "entity";
public const string Short = "e";
}
}
}
}
}

16
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs

@ -58,6 +58,22 @@ public class CmdHelper : ICmdHelper, ITransientDependency
}
}
public Process RunCmdAndGetProcess(string command, string workingDirectory = null)
{
var procStartInfo = new ProcessStartInfo(
GetFileName(),
GetArguments(command)
);
if (!string.IsNullOrEmpty(workingDirectory))
{
procStartInfo.WorkingDirectory = workingDirectory;
procStartInfo.CreateNoWindow = false;
}
return Process.Start(procStartInfo);
}
public string RunCmdAndGetOutput(string command, string workingDirectory = null)
{
return RunCmdAndGetOutput(command, out int _, workingDirectory);

6
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ICmdHelper.cs

@ -1,4 +1,6 @@
namespace Volo.Abp.Cli.Utils;
using System.Diagnostics;
namespace Volo.Abp.Cli.Utils;
public interface ICmdHelper
{
@ -12,6 +14,8 @@ public interface ICmdHelper
void RunCmd(string command, string workingDirectory = null);
Process RunCmdAndGetProcess(string command, string workingDirectory = null);
void RunCmd(string command, out int exitCode, string workingDirectory = null);
string RunCmdAndGetOutput(string command, string workingDirectory = null);

Loading…
Cancel
Save