split CLI modes to separate files

This commit is contained in:
Timerix 2025-04-06 13:53:21 +05:00
parent eeb8f43d3d
commit 3c1d195849
5 changed files with 85 additions and 71 deletions

View File

@ -12,51 +12,11 @@ internal enum Mode
Unset, Search, Interactive
}
internal static class Modes
internal static partial class Modes
{
internal static void Search(string searchQuery, IOPath inputPath, IOPath? outputPath)
{
Stream inputStream = File.OpenRead(inputPath);
try
{
byte[] head4 = new byte[4];
inputStream.ReadExactly(head4);
inputStream.Seek(0, SeekOrigin.Begin);
if (head4.SequenceEqual<byte>([(byte)'P', (byte)'K', 3, 4]))
{
var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read);
var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "gamestate");
if (zipEntry is null)
throw new Exception("'gamestate' file not found in zip archive");
var unzipped = new MemoryStream((int)zipEntry.Length);
zipEntry.Open().CopyTo(unzipped);
zipArchive.Dispose(); // closes inputStream
unzipped.Seek(0, SeekOrigin.Begin);
inputStream = unzipped;
}
using var outputStream = outputPath is null
? Console.OpenStandardOutput()
: File.OpenWrite(outputPath.Value);
var searchExpression = SearchExpressionCompiler.Compile(searchQuery);
var parser = new SaveParserEU4(inputStream, searchExpression);
var parsedValue = parser.Parse();
JsonSerializer.Serialize(outputStream, parsedValue,
ParsedValueJsonContext.Default.DictionaryStringListObject);
outputStream.WriteByte((byte)'\n');
}
finally
{
inputStream.Dispose();
}
}
internal static void Interactive()
{
Console.Clear();
Console.ResetColor();
ColoredConsole.Clear();
ColoredConsole.WriteTitle("interactive mode", fg: ConsoleColor.Cyan);
ColoredConsole.WriteLine($"working directory: '{Environment.CurrentDirectory}'", ConsoleColor.Gray);
IOPath? inputPath = null;
@ -67,8 +27,7 @@ internal static class Modes
try
{
ColoredConsole.Write("> ", ConsoleColor.Blue);
Console.ForegroundColor = ConsoleColor.Gray;
string? input = Console.ReadLine();
string input = ColoredConsole.ReadLine(ConsoleColor.Gray);
if (string.IsNullOrEmpty(input))
continue;
@ -108,13 +67,13 @@ internal static class Modes
case "h":
case "help":
ColoredConsole.WriteLine(helpMessage, fg: ConsoleColor.White);
ColoredConsole.WriteLine(helpMessage, ConsoleColor.White);
break;
case "i":
case "input":
input = ColoredConsole.ReadLine("Input file path",
ConsoleColor.Blue);
ColoredConsole.Write("Input file path: ", ConsoleColor.Blue);
input = ColoredConsole.ReadLine(ConsoleColor.Gray);
if (string.IsNullOrEmpty(input))
throw new NullReferenceException();
inputPath = input;
@ -122,8 +81,8 @@ internal static class Modes
case "o":
case "output":
input = ColoredConsole.ReadLine("Output file path [default=stdout]",
ConsoleColor.Blue);
ColoredConsole.Write("Output file path [default=stdout]: ", ConsoleColor.Blue);
input = ColoredConsole.ReadLine(ConsoleColor.Gray);
if (string.IsNullOrEmpty(input))
throw new ArgumentException("Input file path is required");
inputPath = input;
@ -134,8 +93,8 @@ internal static class Modes
if (inputPath is null)
throw new ArgumentException("Input file path is required");
var searchQuery = ColoredConsole.ReadLine("search expression",
ConsoleColor.Blue);
ColoredConsole.Write("search expression: ", ConsoleColor.Blue);
var searchQuery = ColoredConsole.ReadLine(ConsoleColor.Gray);
if (string.IsNullOrEmpty(searchQuery))
throw new ArgumentException("Search expression is required");
@ -150,8 +109,8 @@ internal static class Modes
break;
case "cd":
input = ColoredConsole.ReadLine("Change working directory to",
ConsoleColor.Blue);
ColoredConsole.Write("Change working directory to: ", ConsoleColor.Blue);
input = ColoredConsole.ReadLine(ConsoleColor.Gray);
if (!string.IsNullOrEmpty(input))
{
Environment.CurrentDirectory = new IOPath(input).Str;

View File

@ -0,0 +1,49 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using ParadoxSaveParser.Lib;
namespace ParadoxSaveParser.CLI;
internal static partial class Modes
{
internal static void Search(string searchQuery, IOPath inputPath, IOPath? outputPath)
{
Stream inputStream = File.OpenRead(inputPath);
try
{
byte[] head4 = new byte[4];
inputStream.ReadExactly(head4);
inputStream.Seek(0, SeekOrigin.Begin);
if (head4.SequenceEqual<byte>([(byte)'P', (byte)'K', 3, 4]))
{
var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read);
var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "gamestate");
if (zipEntry is null)
throw new Exception("'gamestate' file not found in zip archive");
var unzipped = new MemoryStream((int)zipEntry.Length);
zipEntry.Open().CopyTo(unzipped);
zipArchive.Dispose(); // closes inputStream
unzipped.Seek(0, SeekOrigin.Begin);
inputStream = unzipped;
}
using var outputStream = outputPath is null
? Console.OpenStandardOutput()
: File.OpenWrite(outputPath.Value);
var searchExpression = SearchExpressionCompiler.Compile(searchQuery);
var parser = new SaveParserEU4(inputStream, searchExpression);
var parsedValue = parser.Parse();
JsonSerializer.Serialize(outputStream, parsedValue,
ParsedValueJsonContext.Default.DictionaryStringListObject);
outputStream.WriteByte((byte)'\n');
}
finally
{
inputStream.Dispose();
}
}
}

View File

@ -14,6 +14,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DTLib" Version="1.6.5"/>
<PackageReference Include="DTLib" Version="1.7.0"/>
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modes/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -33,7 +33,7 @@ try
},
"search expression")
)
.WithNoExit()
.AllowNoArguments()
.ParseAndHandle(args);
if (args.Length == 0)
@ -57,6 +57,10 @@ try
break;
}
}
catch (LaunchArgumentParser.ExitAfterHelpException)
{
// this exception is throwed after -h argument to close the program
}
catch (Exception ex)
{
ColoredConsole.WriteLine(ex.ToStringDemystified(), ConsoleColor.Red);