diff --git a/src/Commands.cs b/src/Commands.cs index 7d0c5a5..4be0a59 100644 --- a/src/Commands.cs +++ b/src/Commands.cs @@ -5,7 +5,7 @@ using Spectre.Console.Cli; namespace ScriptLauncher; -internal sealed class RootCommand : AsyncCommand +public sealed class RootCommand : AsyncCommand { private const int Failure = 1; private const int Success = 0; @@ -15,6 +15,8 @@ internal sealed class RootCommand : AsyncCommand RootCommandSettings settings ) { + ArgumentNullException.ThrowIfNull(settings); + if (!Directory.Exists(settings.Directory)) { AnsiConsole.Markup($"[red]The directory '{settings.Directory}' does not exist.[/]"); @@ -72,7 +74,7 @@ internal sealed class RootCommand : AsyncCommand } } -internal class RootCommandSettings : CommandSettings +public sealed class RootCommandSettings : CommandSettings { [Description("Comma separated list of script extensions")] [CommandOption("-x|--extensions")] @@ -97,4 +99,4 @@ internal class RootCommandSettings : CommandSettings [Description("Starting directory (Default: .)")] [CommandArgument(0, "")] public string Directory { get; init; } = "."; -} +} \ No newline at end of file diff --git a/src/PromptConstructor.cs b/src/PromptConstructor.cs index baa6137..c624387 100644 --- a/src/PromptConstructor.cs +++ b/src/PromptConstructor.cs @@ -1,6 +1,7 @@ +using Spectre.Console; + using System.Globalization; using System.Text; -using Spectre.Console; namespace ScriptLauncher; diff --git a/src/ScriptExecutor.cs b/src/ScriptExecutor.cs index 2038f5c..77e1fe0 100644 --- a/src/ScriptExecutor.cs +++ b/src/ScriptExecutor.cs @@ -4,43 +4,58 @@ namespace ScriptLauncher; internal static class ScriptExecutor { - public static async Task ExecAsync(List files, bool elevated) => - await Parallel.ForEachAsync(files, (x, ct) => ExecAsync(x, elevated, ct)); + public static async Task ExecAsync(List files, bool elevated) => + await Parallel + .ForEachAsync(files, (file, ct) => ExecAsync(file, elevated, ct)) + .ConfigureAwait(ConfigureAwaitOptions.None); - private static async ValueTask ExecAsync(FileInfo file, bool elevated, CancellationToken cancellationToken = default) + private static async ValueTask ExecAsync( + FileInfo file, + bool elevated, + CancellationToken cancellationToken = default + ) { var process = GetExecutableProcessInfo(file, elevated); if (process is null) { return; } - - await (Process.Start(process)?.WaitForExitAsync(cancellationToken) ?? Task.CompletedTask); + + await ( + Process.Start(process)?.WaitForExitAsync(cancellationToken) ?? Task.CompletedTask + ).ConfigureAwait(ConfigureAwaitOptions.None); } - private static ProcessStartInfo? GetExecutableProcessInfo(FileInfo file, bool elevated) => file.Extension switch - { - ".bat" or ".cmd" => new ProcessStartInfo + private static ProcessStartInfo? GetExecutableProcessInfo(FileInfo file, bool elevated) => + file.Extension switch { - FileName = "cmd", - Arguments = $"/Q /C .\\{file.Name}", - Verb = elevated ? "runas /user:Administrator" : string.Empty, - WorkingDirectory = file.DirectoryName - }, - ".ps1" => new ProcessStartInfo - { - FileName = "powershell.exe", - Arguments = $"-NoProfile -ExecutionPolicy Bypass -File .\\{file.Name}", - Verb = elevated ? "runas /user:Administrator" : string.Empty, - WorkingDirectory = file.DirectoryName - }, - ".sh" or ".zsh" or ".fish" => new ProcessStartInfo - { - FileName = "sh", - Arguments = $"-c ./{file.Name}", - Verb = elevated ? "sudo" : string.Empty, - WorkingDirectory = file.DirectoryName - }, - var _ => null - }; -} \ No newline at end of file + ".bat" + or ".cmd" + => new ProcessStartInfo + { + FileName = "cmd", + Arguments = $"/Q /C .\\{file.Name}", + Verb = elevated ? "runas /user:Administrator" : string.Empty, + WorkingDirectory = file.DirectoryName + }, + ".ps1" + => new ProcessStartInfo + { + FileName = "powershell.exe", + Arguments = $"-NoProfile -ExecutionPolicy Bypass -File .\\{file.Name}", + Verb = elevated ? "runas /user:Administrator" : string.Empty, + WorkingDirectory = file.DirectoryName + }, + ".sh" + or ".zsh" + or ".fish" + => new ProcessStartInfo + { + FileName = "sh", + Arguments = $"-c ./{file.Name}", + Verb = elevated ? "sudo" : string.Empty, + WorkingDirectory = file.DirectoryName + }, + _ => null + }; +} diff --git a/src/ScriptFinder.cs b/src/ScriptFinder.cs index 375ca4f..3ea2f4a 100644 --- a/src/ScriptFinder.cs +++ b/src/ScriptFinder.cs @@ -2,17 +2,20 @@ namespace ScriptLauncher; internal readonly struct ScriptFinder { - static readonly string[] DefaultExtensions = new[] { ".ps1", ".*sh", ".bat", ".cmd" }; + private static readonly string[] DefaultExtensions = new[] { ".ps1", ".*sh", ".bat", ".cmd" }; + private static readonly char[] DefaultSeparators = new[] { ',', ' ' }; + public string[] Extensions { get; } public string RootDirectory { get; } public int Depth { get; } + private readonly EnumerationOptions _options; public ScriptFinder(string? extensions, string directory, int depth) { Extensions = extensions - ?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) + ?.Split(DefaultSeparators, StringSplitOptions.RemoveEmptyEntries) .ToHashSet() .Select(x => $".{x.TrimStart('.')}") .ToArray() ?? DefaultExtensions; diff --git a/src/ScriptLauncher.csproj b/src/ScriptLauncher.csproj index 1b1bd1d..7784893 100644 --- a/src/ScriptLauncher.csproj +++ b/src/ScriptLauncher.csproj @@ -1,12 +1,12 @@ - + Exe - net6.0 + net8.0 enable enable All - 0.1.4 + 0.1.5 true Tool to find and exec shell scripts README.md