using CommandLine; using MultiversalDiplomacy.Script; namespace MultiversalDiplomacy.CommandLine; [Verb("repl", HelpText = "Begin an interactive 5dplomacy session.")] public class ReplOptions { [Option('i', "input", HelpText = "Begin the repl session by executing the commands in this file.")] public string? InputFile { get; set; } [Option('o', "output", HelpText = "Echo the repl session to this file. Specify a directory to autogenerate a filename.")] public string? OutputFile { get; set; } public static void Execute(ReplOptions args) { IEnumerable? inputFileLines = null; if (args.InputFile is not null) { var fullPath = Path.GetFullPath(args.InputFile); inputFileLines = File.ReadAllLines(fullPath); Console.WriteLine($"Reading from {fullPath}"); } // Create a writer to the output file, if specified. StreamWriter? outputWriter = null; if (args.OutputFile is not null) { string fullPath = Path.GetFullPath(args.OutputFile); string outputPath = Directory.Exists(fullPath) ? Path.Combine(fullPath, $"{DateTime.UtcNow:yyyyMMddHHmmss}.log") : fullPath; Console.WriteLine($"Echoing to {outputPath}"); outputWriter = File.CreateText(outputPath); } IEnumerable GetInputs() { foreach (string line in inputFileLines ?? []) { var trimmed = line.Trim(); // File inputs weren't echoed to the terminal so they need to be echoed here Console.WriteLine($"{trimmed}"); yield return trimmed; } string? input; do { input = Console.ReadLine(); yield return input; } while (input is not null); // The last null is returned because an EOF means we should quit the repl. } IScriptHandler? handler = new ReplScriptHandler(Console.WriteLine); Console.Write(handler.Prompt); foreach (string? nextInput in GetInputs()) { // Handle quitting directly. if (nextInput is null || nextInput == "quit" || nextInput == "exit") { break; } string input = nextInput.Trim(); outputWriter?.WriteLine(input); outputWriter?.Flush(); // Delegate all other command parsing to the handler. var result = handler.HandleInput(input); // Report errors if they occured. if (!result.Success) { Console.WriteLine($"Error: {result.Message}"); } // Quit if the handler didn't continue processing. if (result.NextHandler is null) { break; } // Otherwise prompt for the next command. Console.Write(handler.Prompt); } Console.WriteLine("exiting"); } }