Browse Source

Merge pull request #12486 from abpframework/issue/12411

Cli: Create migrations after project generation
pull/12504/head
maliming 4 years ago
committed by GitHub
parent
commit
0c8f04cc08
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 100
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs
  2. 6
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
  3. 41
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
  4. 43
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/DotnetEfToolManager.cs
  5. 111
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/InitialMigrationCreator.cs

100
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
@ -12,14 +13,18 @@ namespace Volo.Abp.Cli.Commands;
public class CreateMigrationAndRunMigratorCommand : IConsoleCommand, ITransientDependency
{
private readonly InitialMigrationCreator _ınıtialMigrationCreator;
public const string Name = "create-migration-and-run-migrator";
public ICmdHelper CmdHelper { get; }
public DotnetEfToolManager DotnetEfToolManager { get; }
public ILogger<CreateMigrationAndRunMigratorCommand> Logger { get; set; }
public CreateMigrationAndRunMigratorCommand(ICmdHelper cmdHelper)
public CreateMigrationAndRunMigratorCommand(ICmdHelper cmdHelper, InitialMigrationCreator ınıtialMigrationCreator, DotnetEfToolManager dotnetEfToolManager)
{
_ınıtialMigrationCreator = ınıtialMigrationCreator;
CmdHelper = cmdHelper;
DotnetEfToolManager = dotnetEfToolManager;
Logger = NullLogger<CreateMigrationAndRunMigratorCommand>.Instance;
}
@ -39,110 +44,31 @@ public class CreateMigrationAndRunMigratorCommand : IConsoleCommand, ITransientD
throw new Exception("DbMigrator is not found!");
}
if (!IsDotNetEfToolInstalled())
{
InstallDotnetEfTool();
}
await DotnetEfToolManager.BeSureInstalledAsync();
var tenantDbContextName = FindTenantDbContextName(dbMigrationsFolder);
var dbContextName = tenantDbContextName != null ?
FindDbContextName(dbMigrationsFolder)
: null;
var migrationsCreatedSuccessfully = await _ınıtialMigrationCreator.CreateAsync(commandLineArgs.Target, !nolayers);
var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbContextName, "Migrations");
var tenantMigrationOutput = tenantDbContextName != null ?
AddMigrationAndGetOutput(dbMigrationsFolder, tenantDbContextName, "TenantMigrations")
: null;
if (CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput))
if (migrationsCreatedSuccessfully)
{
if (nolayers)
{
// Migration added successfully
CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(Path.Combine(dbMigrationsFolder, "MyCompanyName.MyProjectName")) + "\" && dotnet run --migrate-database");
CmdHelper.RunCmd("dotnet run --migrate-database", Path.GetDirectoryName(Path.Combine(dbMigrationsFolder, "MyCompanyName.MyProjectName")));
}
else
{
// Migration added successfully
CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run");
CmdHelper.RunCmd("dotnet run", Path.GetDirectoryName(dbMigratorProjectPath));
}
await Task.CompletedTask;
}
else
{
var exceptionMsg = "Migrations failed! A migration command didn't run successfully:" +
Environment.NewLine +
Environment.NewLine + migrationOutput +
Environment.NewLine +
Environment.NewLine + tenantMigrationOutput;
var exceptionMsg = "Migrations failed! A migration command didn't run successfully.";
Logger.LogError(exceptionMsg);
throw new Exception(exceptionMsg);
}
}
private string FindTenantDbContextName(string dbMigrationsFolder)
{
var tenantDbContext = Directory.GetFiles(dbMigrationsFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault() ??
Directory.GetFiles(dbMigrationsFolder, "*TenantDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault();
if (tenantDbContext == null)
{
return null;
}
return Path.GetFileName(tenantDbContext).RemovePostFix(".cs");
}
private string FindDbContextName(string dbMigrationsFolder)
{
var dbContext = Directory.GetFiles(dbMigrationsFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")) ??
Directory.GetFiles(dbMigrationsFolder, "*DbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault(fp => !fp.EndsWith("TenantDbContext.cs"));
if (dbContext == null)
{
return null;
}
return Path.GetFileName(dbContext).RemovePostFix(".cs");
}
private string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext, string outputDirectory)
{
var dbContextOption = string.IsNullOrWhiteSpace(dbContext)
? string.Empty
: $"--context {dbContext}";
var addMigrationCmd = $"cd \"{dbMigrationsFolder}\" && " +
$"dotnet ef migrations add Initial --output-dir {outputDirectory} {dbContextOption}";
return CmdHelper.RunCmdAndGetOutput(addMigrationCmd, out int exitCode);
}
private bool IsDotNetEfToolInstalled()
{
var output = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g", out int exitCode);
return output.Contains("dotnet-ef");
}
private static bool CheckMigrationOutput(string output)
{
return output == null || (output.Contains("Done.") &&
output.Contains("To undo this action") &&
output.Contains("ef migrations remove"));
}
private void InstallDotnetEfTool()
{
Logger.LogInformation("Installing dotnet-ef tool...");
CmdHelper.RunCmd("dotnet tool install --global dotnet-ef");
Logger.LogInformation("dotnet-ef tool is installed.");
}
private static string GetDbMigratorProjectPath(string dbMigrationsFolderPath)
{
var srcFolder = Directory.GetParent(dbMigrationsFolderPath);

6
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs

@ -32,8 +32,9 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien
SolutionPackageVersionFinder solutionPackageVersionFinder,
ICmdHelper cmdHelper,
IInstallLibsService installLibsService,
AngularPwaSupportAdder angularPwaSupportAdder)
: base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder)
AngularPwaSupportAdder angularPwaSupportAdder,
InitialMigrationCreator ınitialMigrationCreator)
: base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder, ınitialMigrationCreator)
{
TemplateProjectBuilder = templateProjectBuilder;
TemplateInfoProvider = templateInfoProvider;
@ -79,6 +80,7 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien
Logger.LogInformation($"'{projectName}' has been successfully created to '{projectArgs.OutputFolder}'");
RunGraphBuildForMicroserviceServiceTemplate(projectArgs);
await CreateInitialMigrationsAsync(projectArgs);
await RunInstallLibsForWebTemplateAsync(projectArgs);
ConfigurePwaSupportForAngular(projectArgs);

41
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs

@ -6,6 +6,7 @@ using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NUglify.Helpers;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Services;
@ -26,6 +27,7 @@ public abstract class ProjectCreationCommandBase
public ICmdHelper CmdHelper { get; }
public IInstallLibsService InstallLibsService { get; }
public AngularPwaSupportAdder AngularPwaSupportAdder { get; }
public InitialMigrationCreator InitialMigrationCreator { get; }
public ILogger<NewCommand> Logger { get; set; }
public ProjectCreationCommandBase(
@ -33,13 +35,15 @@ public abstract class ProjectCreationCommandBase
SolutionPackageVersionFinder solutionPackageVersionFinder,
ICmdHelper cmdHelper,
IInstallLibsService installLibsService,
AngularPwaSupportAdder angularPwaSupportAdder)
AngularPwaSupportAdder angularPwaSupportAdder,
InitialMigrationCreator ınitialMigrationCreator)
{
ConnectionStringProvider = connectionStringProvider;
SolutionPackageVersionFinder = solutionPackageVersionFinder;
CmdHelper = cmdHelper;
InstallLibsService = installLibsService;
AngularPwaSupportAdder = angularPwaSupportAdder;
InitialMigrationCreator = ınitialMigrationCreator;
Logger = NullLogger<NewCommand>.Instance;
}
@ -337,6 +341,41 @@ public abstract class ProjectCreationCommandBase
}
}
protected async Task CreateInitialMigrationsAsync(ProjectBuildArgs projectArgs)
{
if (projectArgs.DatabaseProvider == DatabaseProvider.MongoDb)
{
return;
}
var efCoreProjectPath = string.Empty;
bool isLayeredTemplate;
switch (projectArgs.TemplateName)
{
case AppTemplate.TemplateName:
case AppProTemplate.TemplateName:
efCoreProjectPath = Directory.GetFiles(projectArgs.OutputFolder, "*EntityFrameworkCore.csproj", SearchOption.AllDirectories).FirstOrDefault();
isLayeredTemplate = true;
break;
case AppNoLayersTemplate.TemplateName:
case AppNoLayersProTemplate.TemplateName:
efCoreProjectPath = Directory.GetFiles(projectArgs.OutputFolder, "*.csproj", SearchOption.AllDirectories).FirstOrDefault();
isLayeredTemplate = false;
break;
default:
return;
}
if (string.IsNullOrWhiteSpace(efCoreProjectPath))
{
Logger.LogWarning("Couldn't find the project to create initial migrations!");
return;
}
await InitialMigrationCreator.CreateAsync(Path.GetDirectoryName(efCoreProjectPath), isLayeredTemplate);
}
protected void ConfigurePwaSupportForAngular(ProjectBuildArgs projectArgs)
{
var isAngular = projectArgs.UiFramework == UiFramework.Angular;

43
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/DotnetEfToolManager.cs

@ -0,0 +1,43 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands.Services;
public class DotnetEfToolManager : ISingletonDependency
{
public ICmdHelper CmdHelper { get; }
public ILogger<DotnetEfToolManager> Logger { get; set; }
public DotnetEfToolManager(ICmdHelper cmdHelper)
{
CmdHelper = cmdHelper;
Logger = NullLogger<DotnetEfToolManager>.Instance;
}
public async Task BeSureInstalledAsync()
{
if (IsDotNetEfToolInstalled())
{
return;
}
InstallDotnetEfTool();
}
private bool IsDotNetEfToolInstalled()
{
var output = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g");
return output.Contains("dotnet-ef");
}
private void InstallDotnetEfTool()
{
Logger.LogInformation("Installing dotnet-ef tool...");
CmdHelper.RunCmd("dotnet tool install --global dotnet-ef");
Logger.LogInformation("dotnet-ef tool is installed.");
}
}

111
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/InitialMigrationCreator.cs

@ -0,0 +1,111 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands.Services;
public class InitialMigrationCreator : ITransientDependency
{
public ICmdHelper CmdHelper { get; }
public DotnetEfToolManager DotnetEfToolManager { get; }
public ILogger<InitialMigrationCreator> Logger { get; set; }
public InitialMigrationCreator(ICmdHelper cmdHelper, DotnetEfToolManager dotnetEfToolManager)
{
CmdHelper = cmdHelper;
DotnetEfToolManager = dotnetEfToolManager;
Logger = NullLogger<InitialMigrationCreator>.Instance;
}
public async Task<bool> CreateAsync(string targetProjectFolder, bool layeredTemplate = true)
{
if (targetProjectFolder == null || !Directory.Exists(targetProjectFolder))
{
Logger.LogError($"This path doesn't exist: {targetProjectFolder}");
return false;
}
Logger.LogInformation("Creating initial migrations...");
await DotnetEfToolManager.BeSureInstalledAsync();
var tenantDbContextName = FindTenantDbContextName(targetProjectFolder);
var dbContextName = tenantDbContextName != null ?
FindDbContextName(targetProjectFolder)
: null;
var migrationOutput = AddMigrationAndGetOutput(targetProjectFolder, dbContextName, "Migrations");
var tenantMigrationOutput = tenantDbContextName != null ?
AddMigrationAndGetOutput(targetProjectFolder, tenantDbContextName, "TenantMigrations")
: null;
var migrationSuccess = CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput);
if (migrationSuccess)
{
Logger.LogInformation("Initial migrations are created.");
}
else
{
Logger.LogError("Creating initial migrations process is failed! Details:" + Environment.NewLine
+ migrationOutput + Environment.NewLine
+ tenantMigrationOutput + Environment.NewLine);
}
return migrationSuccess;
}
private string FindTenantDbContextName(string projectFolder)
{
var tenantDbContext = Directory.GetFiles(projectFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault() ??
Directory.GetFiles(projectFolder, "*TenantDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault();
if (tenantDbContext == null)
{
return null;
}
return Path.GetFileName(tenantDbContext).RemovePostFix(".cs");
}
private string FindDbContextName(string projectFolder)
{
var dbContext = Directory.GetFiles(projectFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")) ??
Directory.GetFiles(projectFolder, "*DbContext.cs", SearchOption.AllDirectories)
.FirstOrDefault(fp => !fp.EndsWith("TenantDbContext.cs"));
if (dbContext == null)
{
return null;
}
return Path.GetFileName(dbContext).RemovePostFix(".cs");
}
private string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext, string outputDirectory)
{
var dbContextOption = string.IsNullOrWhiteSpace(dbContext)
? string.Empty
: $"--context {dbContext}";
var addMigrationCmd = $"dotnet ef migrations add Initial --output-dir {outputDirectory} {dbContextOption}";
return CmdHelper.RunCmdAndGetOutput(addMigrationCmd, out int exitCode, dbMigrationsFolder);
}
private static bool CheckMigrationOutput(string output)
{
return output == null || (output.Contains("Done.") &&
output.Contains("To undo this action") &&
output.Contains("ef migrations remove"));
}
}
Loading…
Cancel
Save