diff --git a/src/AbpDevTools/Commands/DatabaseDropCommand.cs b/src/AbpDevTools/Commands/DatabaseDropCommand.cs new file mode 100644 index 0000000..73b3812 --- /dev/null +++ b/src/AbpDevTools/Commands/DatabaseDropCommand.cs @@ -0,0 +1,95 @@ +using System.Diagnostics; +using AbpDevTools.Notifications; +using CliFx.Infrastructure; +using Spectre.Console; + +namespace AbpDevTools.Commands; + +[Command("database-drop", Description = "Drops all databases in the working directory")] +public class DatabaseDropCommand : ICommand +{ + [CommandParameter(0, IsRequired = false, Description = "Working directory to search for EntityFramework projects. Default: . (Current Directory)")] + public string WorkingDirectory { get; set; } + + [CommandOption("force", 'f')] + public bool Force { get; set; } + + protected readonly INotificationManager notificationManager; + + public DatabaseDropCommand(INotificationManager notificationManager) + { + this.notificationManager = notificationManager; + } + + public async ValueTask ExecuteAsync(IConsole console) + { + if (string.IsNullOrEmpty(WorkingDirectory)) + { + WorkingDirectory = Directory.GetCurrentDirectory(); + } + + var efCoreProjects = await GetEfCoreProjectsAsync(); + + var cancellationToken = console.RegisterCancellationHandler(); + + var projectCount = efCoreProjects.Length; + if (projectCount == 0) + { + await console.Output.WriteLineAsync("Could not find any EntityFrameworkCore project in the working directory..."); + return; + } + + AnsiConsole.MarkupLine($"[green]{projectCount}[/] EntityFrameworkCore project(s) found in the directory. Trying to find and drop databases..."); + + var forcePostfix = Force ? " --force" : string.Empty; + + for (var i = 0; i < projectCount; i++) + { + var efCoreProject = efCoreProjects[i]; + + AnsiConsole.MarkupLine($"[blue]## Project{(i + 1)} - {efCoreProject.Name.Replace(".csproj", string.Empty)}[/]"); + + var startInfo = new ProcessStartInfo("dotnet", $"ef database drop{forcePostfix}") + { + WorkingDirectory = efCoreProject.DirectoryName!, + RedirectStandardOutput = true, + CreateNoWindow = false + }; + + var process = Process.Start(startInfo)!; + + process.OutputDataReceived += async (sender, args) => + { + if (args?.Data != null) + { + await console.Output.WriteLineAsync("* " + args.Data); + } + }; + + process.BeginOutputReadLine(); + + await process.WaitForExitAsync(cancellationToken); + } + + if (!cancellationToken.IsCancellationRequested) + { + await notificationManager.SendAsync("Dropped database(s)", $"Dropped all databases in {WorkingDirectory}"); + } + } + + private async Task GetEfCoreProjectsAsync() + { + return await AnsiConsole.Status() + .StartAsync("Searching EntityFrameworkCore projects...", ctx => + { + ctx.Spinner(Spinner.Known.SimpleDotsScrolling); + + var efCoreProjects = Directory.EnumerateFiles(WorkingDirectory, "*.csproj", SearchOption.AllDirectories) + .Where(x => x.EndsWith("EntityFrameworkCore.csproj")) + .Select(x => new FileInfo(x)) + .ToArray(); + + return Task.FromResult(efCoreProjects); + }); + } +} \ No newline at end of file diff --git a/src/AbpDevTools/Program.cs b/src/AbpDevTools/Program.cs index 4ff0c3a..141ebf9 100644 --- a/src/AbpDevTools/Program.cs +++ b/src/AbpDevTools/Program.cs @@ -52,7 +52,8 @@ public static CliApplicationBuilder BuildServices(this CliApplicationBuilder bui typeof(AbpBundleCommand), typeof(TestCommand), typeof(UpdateCheckCommand), - typeof(CleanCommand) + typeof(CleanCommand), + typeof(DatabaseDropCommand) }; foreach (var commandType in commands)