diff --git a/src/AbpDevTools/Commands/RunCommand.cs b/src/AbpDevTools/Commands/RunCommand.cs index b35d294..4e2b081 100644 --- a/src/AbpDevTools/Commands/RunCommand.cs +++ b/src/AbpDevTools/Commands/RunCommand.cs @@ -88,6 +88,8 @@ public async ValueTask ExecuteAsync(IConsole console) var _runnableProjects = runConfiguration.GetOptions().RunnableProjects; + localConfigurationManager.TryLoad(WorkingDirectory!, out var localRootConfig, FileSearchDirection.Descendants); + FileInfo[] csprojs = await AnsiConsole.Status() .StartAsync("Looking for projects", async ctx => { @@ -103,7 +105,7 @@ public async ValueTask ExecuteAsync(IConsole console) await console.Output.WriteLineAsync($"{csprojs.Length} csproj file(s) found."); - if (!SkipMigration) + if (!SkipMigration && localRootConfig?.Run?.SkipMigrate != true) { migrateCommand.WorkingDirectory = this.WorkingDirectory; migrateCommand.NoBuild = this.NoBuild; @@ -120,7 +122,9 @@ public async ValueTask ExecuteAsync(IConsole console) { await console.Output.WriteLineAsync($"\n"); - if (Projects == null || Projects.Length == 0) + ApplyLocalProjects(localRootConfig); + + if (Projects.Length == 0) { var choosedProjects = AnsiConsole.Prompt( new MultiSelectionPrompt() @@ -142,21 +146,16 @@ public async ValueTask ExecuteAsync(IConsole console) } } - var commandPrefix = Watch ? "watch " : string.Empty; - var commandSuffix = NoBuild ? " --no-build" : string.Empty; - - if (GraphBuild) + foreach (var csproj in projectFiles) { - commandSuffix += " /graphBuild"; - } + localConfigurationManager.TryLoad(csproj.FullName, out var localConfiguration); - if (!string.IsNullOrEmpty(Configuration)) - { - commandSuffix += $" --configuration {Configuration}"; - } + var commandPrefix = BuildCommandPrefix(localConfiguration?.Run?.Watch); + var commandSuffix = BuildCommandSuffix( + localConfiguration?.Run?.NoBuild, + localConfiguration?.Run?.GraphBuild, + localConfiguration?.Run?.Configuration); - foreach (var csproj in projectFiles) - { var tools = toolsConfiguration.GetOptions(); var startInfo = new ProcessStartInfo(tools["dotnet"], commandPrefix + $"run --project {csproj.FullName}" + commandSuffix) { @@ -166,7 +165,7 @@ public async ValueTask ExecuteAsync(IConsole console) RedirectStandardError = true, }; - localConfigurationManager.ApplyLocalEnvironmentForProcess(csproj.FullName, startInfo); + localConfigurationManager.ApplyLocalEnvironmentForProcess(csproj.FullName, startInfo, localConfiguration); if (!string.IsNullOrEmpty(EnvironmentName)) { @@ -203,6 +202,47 @@ public async ValueTask ExecuteAsync(IConsole console) await updateCheckCommand.SoftCheckAsync(console); } + private void ApplyLocalProjects(LocalConfiguration? localConfiguration) + { + if(localConfiguration is not null) + { + if (Projects.Length == 0 && localConfiguration?.Run?.Projects.Length > 0) + { + Projects = localConfiguration.Run.Projects; + } + } + } + + private string BuildCommandSuffix(bool? noBuild = null, bool? graphBuild = null, string? configuration = null) + { + var commandSuffix = (NoBuild || noBuild == true) ? " --no-build" : string.Empty; + + if (GraphBuild || graphBuild == true) + { + commandSuffix += " /graphBuild"; + } + + if (configuration != null) + { + commandSuffix += $" --configuration {configuration}"; + } + else if (!string.IsNullOrEmpty(Configuration)) + { + commandSuffix += $" --configuration {Configuration}"; + } + + return commandSuffix; + } + + private string BuildCommandPrefix(bool? watchOverride) + { + if (watchOverride is not null) + { + return watchOverride.Value ? "watch " : string.Empty; + } + return Watch ? "watch " : string.Empty; + } + private async Task RenderProcesses(CancellationToken cancellationToken) { var table = new Table().Ascii2Border(); diff --git a/src/AbpDevTools/LocalConfigurations/LocalConfiguration.cs b/src/AbpDevTools/LocalConfigurations/LocalConfiguration.cs index 00b8086..faf2de4 100644 --- a/src/AbpDevTools/LocalConfigurations/LocalConfiguration.cs +++ b/src/AbpDevTools/LocalConfigurations/LocalConfiguration.cs @@ -3,10 +3,21 @@ namespace AbpDevTools.LocalConfigurations; public class LocalConfiguration { + public LocalRunOption? Run { get; set; } public LocalEnvironmentOption? Environment { get; set; } public class LocalEnvironmentOption : EnvironmentOption { public string? Name { get; set; } } + + public class LocalRunOption + { + public bool Watch { get; set; } + public bool NoBuild { get; set; } + public bool GraphBuild { get; set; } + public string? Configuration { get; set; } + public bool SkipMigrate { get; set; } + public string[] Projects { get; set; } = Array.Empty(); + } } diff --git a/src/AbpDevTools/LocalConfigurations/LocalConfigurationManager.cs b/src/AbpDevTools/LocalConfigurations/LocalConfigurationManager.cs index 4d54fe2..af9551d 100644 --- a/src/AbpDevTools/LocalConfigurations/LocalConfigurationManager.cs +++ b/src/AbpDevTools/LocalConfigurations/LocalConfigurationManager.cs @@ -18,37 +18,36 @@ public LocalConfigurationManager(IDeserializer deserializer, FileExplorer fileEx this.environmentManager = environmentManager; } - public bool TryLoad(string filePath, out LocalConfiguration? localConfiguration) + public bool TryLoad(string path, out LocalConfiguration? localConfiguration, FileSearchDirection direction = FileSearchDirection.Ascendants) { - if (!File.Exists(filePath)) - { - localConfiguration = null; - return false; - } - - var yml = File.ReadAllText(filePath); - - localConfiguration = _deserializer.Deserialize(yml); + localConfiguration = null; - return true; - } - - public void ApplyLocalEnvironmentForProcess(string path, ProcessStartInfo process) - { var directory = Path.GetDirectoryName(path); if (directory == null) { - return; + return false; } - var ymlPath = fileExplorer.FindAscendants(directory, "abpdev.yml").First(); + var ymlPath = direction == FileSearchDirection.Ascendants ? + fileExplorer.FindAscendants(directory, "abpdev.yml").FirstOrDefault() : + fileExplorer.FindDescendants(directory, "abpdev.yml").FirstOrDefault() + ; if (string.IsNullOrEmpty(ymlPath)) { - return; + return false; } - if (TryLoad(ymlPath, out var localConfiguration)) + var ymlContent = File.ReadAllText(ymlPath); + + localConfiguration = _deserializer.Deserialize(ymlContent); + + return true; + } + + public void ApplyLocalEnvironmentForProcess(string path, ProcessStartInfo process, LocalConfiguration? localConfiguration = null) + { + if (localConfiguration is not null || TryLoad(path, out localConfiguration)) { if (!string.IsNullOrEmpty(localConfiguration?.Environment?.Name)) { @@ -63,4 +62,10 @@ public void ApplyLocalEnvironmentForProcess(string path, ProcessStartInfo proces } } } +} + +public enum FileSearchDirection : byte +{ + Ascendants, + Descendants } \ No newline at end of file diff --git a/src/AbpDevTools/Program.cs b/src/AbpDevTools/Program.cs index 5857038..a7d1ed4 100644 --- a/src/AbpDevTools/Program.cs +++ b/src/AbpDevTools/Program.cs @@ -73,14 +73,14 @@ public static CliApplicationBuilder BuildServices(this CliApplicationBuilder bui services.AutoRegisterFromAbpDevTools(); var yamlSerializer = new SerializerBuilder() - .WithNamingConvention(CamelCaseNamingConvention.Instance) + .WithNamingConvention(HyphenatedNamingConvention.Instance) .Build(); services.AddSingleton(yamlSerializer); services.AddSingleton( new DeserializerBuilder() - .WithNamingConvention(CamelCaseNamingConvention.Instance) + .WithNamingConvention(HyphenatedNamingConvention.Instance) .Build()); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))