Allow execution of multiple scripts

This commit is contained in:
Marcello 2022-03-11 16:32:53 +01:00
parent 190953f76b
commit 01b62cd882

View file

@ -2,59 +2,84 @@
using Cocona;
using Spectre.Console;
const int ScriptListSize = 15;
const int ErrorExitCode = 1;
var app = CoconaLiteApp.Create();
app.AddCommand(RootCommand);
app.Run();
static void RootCommand(
[Option("dir", new[] { 'd' }, Description = "Directory from which search the scripts")] string directory = ".",
[Option("ext", Description = "Comma separated list of script extensions to search")] string extensions = "*",
[Option("elevated", new[] { 'e' }, Description = "Run the script with elevated privileges")] bool elevated = false,
[Option("depth")] int depth = 0)
[Option("extensions", new char[] { 'e' }, Description = "Comma separated list of script extensions to search")] string extensions = "*",
[Option("depth", new char[] { 'd' }, Description = "Folder depth of the search")] int depth = 0,
[Option("elevated", new char[] { 'E' }, Description = "Run the script with elevated privileges")] bool elevated = false,
[Option("multiple", new char[] { 'm' }, Description = "Execute multiple scripts")] bool multiple = false,
[Argument(Name = "Directory", Description = "Directory from which search the scripts")] string directory = ".")
{
if (!Directory.Exists(directory))
{
AnsiConsole.Markup($"[red]The directory {directory} does not exist.[/]");
Environment.Exit(1);
AnsiConsole.Markup($"[red]The directory '{directory}' does not exist.[/]");
Environment.ExitCode = ErrorExitCode;
return;
}
var fileExtensions = extensions.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.ToHashSet()
.ToArray();
var finder = new ScriptFinder()
var finder = new ScriptFinder
{
Depth = depth,
Extensions = fileExtensions,
RootFolder = directory,
Depth = depth
};
var files = finder.GetScriptFiles(fileExtensions);
if (files.Length == 0)
{
AnsiConsole.Markup($"[red]No scripts script files found in {directory} with extensions '{string.Join("|", fileExtensions)}'[/]");
Environment.Exit(1);
AnsiConsole.Markup($"[red]No scripts script files found in '{directory}' with extensions '{string.Join("|", fileExtensions)}'[/]");
Environment.ExitCode = ErrorExitCode;
return;
}
var prompt = new SelectionPrompt<string>()
if (multiple)
{
var prompt = new MultiSelectionPrompt<FileInfo>()
.Title("Select scripts")
.NotRequired()
.PageSize(ScriptListSize)
.MoreChoicesText("[grey]Move up and down to reveal more options[/]")
.InstructionsText("[grey](Press [blue]<space>[/] to toggle a script, [green]<enter>[/] to accept)[/]")
.AddChoices(files);
var scripts = AnsiConsole.Prompt(prompt);
scripts.ForEach(ScriptExecutor.Exec);
}
else
{
var prompt = new SelectionPrompt<FileInfo>()
.Title("Select a script")
.AddChoices(files.Select(x => x.FullName));
.PageSize(ScriptListSize)
.MoreChoicesText("[grey]Move up and down to reveal more options[/]")
.AddChoices(files);
var script = AnsiConsole.Prompt(prompt);
var script = AnsiConsole.Prompt(prompt);
ScriptExecutor.Exec(script);
ScriptExecutor.Exec(script);
}
};
static class ScriptExecutor
{
internal static void Exec(string filename)
internal static void Exec(FileInfo file)
{
var info = new ProcessStartInfo
{
FileName = "powershell.exe",
Arguments = $"-File {filename}",
Arguments = $"-File {file.FullName}",
UseShellExecute = false,
};
@ -64,11 +89,11 @@ static class ScriptExecutor
internal static void Exec(ProcessStartInfo info) => Process.Start(info)?.WaitForExit();
}
class ScriptFinder
readonly struct ScriptFinder
{
public string RootFolder { get; set; } = ".";
public string[] Extensions { get; set; } = new[] { "ps1", "*sh", "bat", "cmd" };
public int Depth { get; set; } = 0;
public string RootFolder { get; init; } = ".";
public string[] Extensions { get; init; } = new[] { "ps1", "*sh", "bat", "cmd" };
public int Depth { get; init; } = 0;
private readonly EnumerationOptions _options;
@ -82,7 +107,7 @@ class ScriptFinder
};
}
internal FileInfo[] GetScriptFiles(string extension)
internal readonly FileInfo[] GetScriptFiles(string extension)
{
try
{
@ -95,6 +120,6 @@ class ScriptFinder
}
}
internal FileInfo[] GetScriptFiles(string[] extensions) =>
extensions.Select(GetScriptFiles).SelectMany(x => x).ToArray();
internal readonly FileInfo[] GetScriptFiles() =>
Extensions.Select(GetScriptFiles).SelectMany(x => x).ToArray();
}