From c53945f490108456a55ab508d0689fec788d2bf2 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 23 Dec 2020 15:06:39 +0300 Subject: [PATCH 1/3] DbMigrator creates the initial migration if no migration exists --- .../Volo/Abp/Cli/AbpCliCoreModule.cs | 1 + .../Commands/CreateMigrationAndRunMigrator.cs | 57 +++++++++++ .../Data/MyProjectNameDbMigrationService.cs | 98 ++++++++++++++++++- 3 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs 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 bc4db38c84..9208357d4a 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 @@ -40,6 +40,7 @@ namespace Volo.Abp.Cli options.Commands["translate"] = typeof(TranslateCommand); options.Commands["build"] = typeof(BuildCommand); options.Commands["bundle"] = typeof(BundleCommand); + options.Commands["create-migration-and-run-migrator"] = typeof(CreateMigrationAndRunMigrator); }); } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs new file mode 100644 index 0000000000..fcc7fc4e86 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.Utils; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.Commands +{ + public class CreateMigrationAndRunMigrator : IConsoleCommand, ITransientDependency + { + public virtual async Task ExecuteAsync(CommandLineArgs commandLineArgs) + { + if (commandLineArgs.Target.IsNullOrEmpty()) + { + throw new CliUsageException( + "DbMigrations folder path is missing!" + ); + } + + var dbMigratorProjectPath = GetDbMigratorProjectPath(commandLineArgs.Target); + + if (dbMigratorProjectPath == null) + { + throw new Exception("DbMigrator is not found!"); + } + + CmdHelper.RunCmd("cd \"" + commandLineArgs.Target + "\" && dotnet ef migrations add Initial -s " + dbMigratorProjectPath); + CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run"); + } + + private string GetDbMigratorProjectPath(string dbMigrationsFolderPath) + { + var srcFolder = Directory.GetParent(dbMigrationsFolderPath); + + var dbMigratorFolderPath = Directory.GetDirectories(srcFolder.FullName).FirstOrDefault(d => d.EndsWith(".DbMigrator")); + + if (dbMigratorFolderPath == null) + { + return null; + } + + return Directory.GetFiles(dbMigratorFolderPath).FirstOrDefault(f => f.EndsWith(".csproj")); + } + + public string GetUsageInfo() + { + return string.Empty; + } + + public string GetShortDescription() + { + return string.Empty; + } + } +} diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs index db5b9291a6..a339edde55 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs @@ -1,5 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -35,6 +39,19 @@ namespace MyCompanyName.MyProjectName.Data public async Task MigrateAsync() { + try + { + if (!await CheckMigrationsAsync()) + { + await AddInitialMigration(); + return; + } + } + catch (Exception e) + { + Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message); + } + Logger.LogInformation("Started database migrations..."); await MigrateDatabaseSchemaAsync(); @@ -69,7 +86,8 @@ namespace MyCompanyName.MyProjectName.Data Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations."); } - Logger.LogInformation("Successfully completed database migrations."); + Logger.LogInformation("Successfully completed all database migrations."); + Logger.LogInformation("You can stop this process safely, if it doesn't stop itself."); } private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null) @@ -89,5 +107,81 @@ namespace MyCompanyName.MyProjectName.Data await _dataSeeder.SeedAsync(tenant?.Id); } + + private async Task CheckMigrationsAsync() + { + var dbMigrationsProjectFolder = GetDbMigrationsProjectFolderPath(); + + if (!Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "migrations"))) + { + return false; + } + + return true; + } + + private async Task AddInitialMigration() + { + Logger.LogInformation("Creating initial migration..."); + + string argumentPrefix; + string fileName; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + argumentPrefix = "-c"; + fileName = "/bin/bash"; + } + else + { + argumentPrefix = "/C"; + fileName = "cmd.exe"; + } + + var procStartInfo = new ProcessStartInfo( fileName, + $"{argumentPrefix} \"abp create-migration-and-run-migrator {GetDbMigrationsProjectFolderPath()}\"" + ); + + try + { + Process.Start(procStartInfo); + } + catch (Exception) + { + throw new Exception("Couldn't run ABP CLI..."); + } + } + + private static string GetDbMigrationsProjectFolderPath() + { + var slnDirectoryPath = GetSolutionDirectoryPath(); + + if (slnDirectoryPath == null) + { + throw new Exception("Solution folder not found!"); + } + + var srcDirectoryPath = Path.Combine(slnDirectoryPath, "src"); + + return Directory.GetDirectories(srcDirectoryPath) + .FirstOrDefault(d => d.EndsWith(".DbMigrations")); + } + + private static string GetSolutionDirectoryPath() + { + var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); + + while (Directory.GetParent(currentDirectory.FullName) != null) + { + currentDirectory = Directory.GetParent(currentDirectory.FullName); + + if (Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null) + { + return currentDirectory.FullName; + } + } + + return null; + } } } From 589b540f99b17e597afe9708bb8574414911c863 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 24 Dec 2020 10:45:35 +0300 Subject: [PATCH 2/3] Make sure migration is added before running dbmigrator again --- .../Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs index fcc7fc4e86..0a79b7760a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigrator.cs @@ -26,8 +26,12 @@ namespace Volo.Abp.Cli.Commands throw new Exception("DbMigrator is not found!"); } - CmdHelper.RunCmd("cd \"" + commandLineArgs.Target + "\" && dotnet ef migrations add Initial -s " + dbMigratorProjectPath); - CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run"); + var output = CmdHelper.RunCmdAndGetOutput("cd \"" + commandLineArgs.Target + "\" && dotnet ef migrations add Initial -s " + dbMigratorProjectPath); + + if (output.Contains("Done.") && output.Contains("To undo this action") && output.Contains("ef migrations remove")) // Migration added successfully + { + CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run"); + } } private string GetDbMigratorProjectPath(string dbMigrationsFolderPath) From 7108266759816e96a8371196832babb46cf6c83c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 6 Jan 2021 09:50:41 +0300 Subject: [PATCH 3/3] refactor MyProjectNameDbMigrationService --- .../Data/MyProjectNameDbMigrationService.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs index a339edde55..aec2fb6de7 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/Data/MyProjectNameDbMigrationService.cs @@ -41,7 +41,7 @@ namespace MyCompanyName.MyProjectName.Data { try { - if (!await CheckMigrationsAsync()) + if (!await MigrationsFolderExists()) { await AddInitialMigration(); return; @@ -87,7 +87,7 @@ namespace MyCompanyName.MyProjectName.Data } Logger.LogInformation("Successfully completed all database migrations."); - Logger.LogInformation("You can stop this process safely, if it doesn't stop itself."); + Logger.LogInformation("You can safely end this process..."); } private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null) @@ -108,16 +108,11 @@ namespace MyCompanyName.MyProjectName.Data await _dataSeeder.SeedAsync(tenant?.Id); } - private async Task CheckMigrationsAsync() + private async Task MigrationsFolderExists() { var dbMigrationsProjectFolder = GetDbMigrationsProjectFolderPath(); - if (!Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "migrations"))) - { - return false; - } - - return true; + return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "migrations")); } private async Task AddInitialMigration()