Created the shared DatapackService and seperate szpack cli tool
This commit is contained in:
parent
ca5057a9f7
commit
c397b40c61
@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionZero.Client", "src\S
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionZero.Server", "src\SessionZero.Server\SessionZero.Server.csproj", "{54824F5A-0499-4BC9-AC8E-88E943C66256}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionZero.Server", "src\SessionZero.Server\SessionZero.Server.csproj", "{54824F5A-0499-4BC9-AC8E-88E943C66256}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "szpack", "tools\szpack\szpack.csproj", "{70FDB950-CAE6-4C38-A476-3FC10BFCF6E6}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -24,5 +26,9 @@ Global
|
|||||||
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Release|Any CPU.Build.0 = Release|Any CPU
|
{54824F5A-0499-4BC9-AC8E-88E943C66256}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{70FDB950-CAE6-4C38-A476-3FC10BFCF6E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{70FDB950-CAE6-4C38-A476-3FC10BFCF6E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{70FDB950-CAE6-4C38-A476-3FC10BFCF6E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{70FDB950-CAE6-4C38-A476-3FC10BFCF6E6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
172
src/SessionZero.Shared/Services/DatapackService.cs
Normal file
172
src/SessionZero.Shared/Services/DatapackService.cs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using SessionZero.Shared.Models;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
namespace SessionZero.Shared.Services;
|
||||||
|
|
||||||
|
public static class DatapackService
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||||
|
{
|
||||||
|
WriteIndented = true,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new Datapack model with required metadata.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The display name of the datapack.</param>
|
||||||
|
/// <param name="version">The initial version string (e.g., "1.0.0").</param>
|
||||||
|
/// <param name="author">The pack creator's name.</param>
|
||||||
|
/// <param name="license">The license (e.g., "CC-BY-SA-4.0").</param>
|
||||||
|
/// <returns>A fully initialized Datapack model.</returns>
|
||||||
|
public static Datapack CreateEmptyDatapack(string name, string version, string author, string license)
|
||||||
|
{
|
||||||
|
return new Datapack
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
Name = name,
|
||||||
|
Version = version,
|
||||||
|
Author = author,
|
||||||
|
License = license,
|
||||||
|
Description = String.Empty,
|
||||||
|
CreatedAt = DateTime.UtcNow,
|
||||||
|
SessionZeroVersion = "0.0.1",
|
||||||
|
Dependencies = new()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes a Datapack model and saves it to a file named 'szpack.json'
|
||||||
|
/// inside a new subdirectory named after the datapack's slug.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datapack">The Datapack object to save.</param>
|
||||||
|
/// <param name="parentDirectoryPath">The directory where the new datapack folder will be created.</param>
|
||||||
|
/// <returns>The full path to the created szpack.json file.</returns>
|
||||||
|
public static async Task<string> SaveDatapackMetadataAsync(Datapack datapack, string parentDirectoryPath)
|
||||||
|
{
|
||||||
|
var packDirectoryName = datapack.Name.ToLower().Replace(' ', '-').Trim();
|
||||||
|
var packRootDirectory = Path.Combine(parentDirectoryPath, packDirectoryName);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(packRootDirectory);
|
||||||
|
|
||||||
|
var filePath = Path.Combine(packRootDirectory, "szpack.json");
|
||||||
|
|
||||||
|
var jsonString = JsonSerializer.Serialize(datapack, JsonOptions);
|
||||||
|
await File.WriteAllTextAsync(filePath, jsonString);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes an SzObject (Dataset, Template, etc.) and saves it to a file.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the object, must inherit from SzObject.</typeparam>
|
||||||
|
/// <param name="szObject">The object to save.</param>
|
||||||
|
/// <param name="directoryPath">The specific subdirectory (e.g., 'datasets') within the datapack root.</param>
|
||||||
|
/// <returns>The full path to the created JSON file.</returns>
|
||||||
|
public static async Task<string> SaveSzObjectAsync<T>(T szObject, string directoryPath) where T : SzObject
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directoryPath);
|
||||||
|
|
||||||
|
var fileName = $"{szObject.Id}.json";
|
||||||
|
var filePath = Path.Combine(directoryPath, fileName);
|
||||||
|
var jsonString = JsonSerializer.Serialize(szObject, JsonOptions);
|
||||||
|
await File.WriteAllTextAsync(filePath, jsonString);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines and creates the standard directory structure for a SessionZero datapack.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rootPath">The root directory path of the new datapack.</param>
|
||||||
|
/// <returns>A dictionary containing the standard folder names and their absolute paths.</returns>
|
||||||
|
public static Dictionary<string, string> CreateDatapackDirectoryStructure(string rootPath)
|
||||||
|
{
|
||||||
|
var structure = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "datasets", Path.Combine(rootPath, "datasets") },
|
||||||
|
{ "character_templates", Path.Combine(rootPath, "characters") },
|
||||||
|
{ "session_templates", Path.Combine(rootPath, "sessions") },
|
||||||
|
{ "media", Path.Combine(rootPath, "media") },
|
||||||
|
{ "images", Path.Combine(rootPath, "media", "images") }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var path in structure.Values)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compresses a datapack directory into a .szpack zip archive.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceDirectoryPath">The path to the datapack's root directory.</param>
|
||||||
|
/// <param name="outputFilePath">The full path and filename for the output .szpack file.</param>
|
||||||
|
public static void PackDatapack(string sourceDirectoryPath, string outputFilePath)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(sourceDirectoryPath))
|
||||||
|
{
|
||||||
|
throw new DirectoryNotFoundException($"Source directory not found: {sourceDirectoryPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(outputFilePath))
|
||||||
|
{
|
||||||
|
File.Delete(outputFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipFile.CreateFromDirectory(sourceDirectoryPath, outputFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts a .szpack zip archive into a target directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceFilePath">The path to the .szpack file.</param>
|
||||||
|
/// <param name="destinationDirectoryPath">The directory where the contents will be extracted.</param>
|
||||||
|
public static void UnpackDatapack(string sourceFilePath, string destinationDirectoryPath)
|
||||||
|
{
|
||||||
|
if (!File.Exists(sourceFilePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException($"Datapack file not found: {sourceFilePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.CreateDirectory(destinationDirectoryPath);
|
||||||
|
|
||||||
|
ZipFile.ExtractToDirectory(sourceFilePath, destinationDirectoryPath, overwriteFiles: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deserializes and loads the core Datapack metadata (szpack.json) from a directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datapackRootPath">The path to the datapack's root directory.</param>
|
||||||
|
/// <returns>A Datapack model containing the metadata.</returns>
|
||||||
|
/// <exception cref="FileNotFoundException">Thrown if szpack.json is not found.</exception>
|
||||||
|
/// <exception cref="JsonException">Thrown if deserialization fails.</exception>
|
||||||
|
public static async Task<Datapack> LoadDatapackMetadataAsync(string datapackRootPath)
|
||||||
|
{
|
||||||
|
var filePath = Path.Combine(datapackRootPath, "szpack.json");
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException($"The required metadata file 'szpack.json' was not found in: {datapackRootPath}", filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonString = await File.ReadAllTextAsync(filePath);
|
||||||
|
|
||||||
|
var datapack = JsonSerializer.Deserialize<Datapack>(jsonString, JsonOptions);
|
||||||
|
|
||||||
|
if (datapack is null)
|
||||||
|
{
|
||||||
|
throw new JsonException($"Failed to deserialize szpack.json from {filePath}. The file may be corrupt or invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return datapack;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/SessionZero.Shared/Validation/DatapackValidator.cs
Normal file
45
src/SessionZero.Shared/Validation/DatapackValidator.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using SessionZero.Shared.Models;
|
||||||
|
|
||||||
|
namespace SessionZero.Shared.Validation;
|
||||||
|
|
||||||
|
public static class DatapackValidator
|
||||||
|
{
|
||||||
|
public static List<string> ValidateDatapack(Datapack datapack)
|
||||||
|
{
|
||||||
|
var errors = new List<string>();
|
||||||
|
|
||||||
|
if (datapack.Id == Guid.Empty) errors.Add("Datapack 'Id' is required and must not be an empty GUID.");
|
||||||
|
|
||||||
|
ValidateRequiredString(errors, datapack.Name, nameof(datapack.Name));
|
||||||
|
ValidateRequiredString(errors, datapack.Version, nameof(datapack.Version));
|
||||||
|
ValidateRequiredString(errors, datapack.Author, nameof(datapack.Author));
|
||||||
|
ValidateRequiredString(errors, datapack.License, nameof(datapack.License));
|
||||||
|
ValidateRequiredString(errors, datapack.SessionZeroVersion, nameof(datapack.SessionZeroVersion));
|
||||||
|
|
||||||
|
if (datapack.CreatedAt == DateTime.MinValue) errors.Add("Datapack 'CreatedAt' is required and must not be an empty DateTime.");
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> ValidateSzObject(SzObject szObject)
|
||||||
|
{
|
||||||
|
var errors = new List<string>();
|
||||||
|
var objectName = szObject.Id;
|
||||||
|
|
||||||
|
ValidateRequiredString(errors, szObject.Id, $"{objectName}'s Id");
|
||||||
|
ValidateRequiredString(errors, szObject.Name, $"{objectName}'s Name");
|
||||||
|
ValidateRequiredString(errors, szObject.SzType, $"{objectName}'s SzType");
|
||||||
|
ValidateRequiredString(errors, szObject.Version, $"{objectName}'s Version");
|
||||||
|
ValidateRequiredString(errors, szObject.SchemaVersion, $"{objectName}'s SchemaVersion");
|
||||||
|
|
||||||
|
// 2. Validate Icon path format (optional/future: e.g., only allows alphanumeric + slashes + extension)
|
||||||
|
// For now, we'll only check if it's not null, which is done by the property definition in SzObject.
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ValidateRequiredString(List<string> errors, string? value, string fieldName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value)) errors.Add($"'{fieldName}' is required and must not be empty.");
|
||||||
|
}
|
||||||
|
}
|
||||||
107
tools/szpack/CreateCommand.cs
Normal file
107
tools/szpack/CreateCommand.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* WARNING:
|
||||||
|
* This tool was created by an LLM based on the SessionZero shared lib project, therefore it is subject to errors and does not reflect the architecture of the SessionZero project.
|
||||||
|
* It was created to be used as a quick and dirty validation tool for the szpack format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using SessionZero.Shared.Models;
|
||||||
|
using SessionZero.Shared.Services;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace SessionZero.Tools.Packer;
|
||||||
|
|
||||||
|
// Settings class defines the command-line arguments
|
||||||
|
public class CreateSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<name>")]
|
||||||
|
[Description("The display name of the datapack (e.g., 'My Fantasy Spells').")]
|
||||||
|
public required string Name { get; init; }
|
||||||
|
|
||||||
|
[CommandArgument(1, "[author]")]
|
||||||
|
[Description("The author's name.")]
|
||||||
|
[DefaultValue("Test Author")]
|
||||||
|
public string Author { get; init; } = "Test Author";
|
||||||
|
|
||||||
|
[CommandOption("-o|--output")]
|
||||||
|
[Description("The parent directory where the new pack folder will be created.")]
|
||||||
|
[DefaultValue(".")]
|
||||||
|
public string Output { get; init; } = Environment.CurrentDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateCommand : AsyncCommand<CreateSettings>
|
||||||
|
{
|
||||||
|
public override async Task<int> ExecuteAsync([NotNull] CommandContext context, [NotNull] CreateSettings settings, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on blue] --- Creating Datapack: '{settings.Name}' --- [/]");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 1. Create the top-level model and save szpack.json
|
||||||
|
var newPack = DatapackService.CreateEmptyDatapack(settings.Name, "1.0.0", settings.Author, "MIT");
|
||||||
|
var szpackPath = await DatapackService.SaveDatapackMetadataAsync(newPack, settings.Output);
|
||||||
|
var packRootDirectory = Path.GetDirectoryName(szpackPath)!;
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine($"[green]✅ Created metadata file at: {szpackPath}[/]");
|
||||||
|
|
||||||
|
// 2. Create the standard directory structure
|
||||||
|
var structure = DatapackService.CreateDatapackDirectoryStructure(packRootDirectory);
|
||||||
|
AnsiConsole.MarkupLine($"[green]✅ Created standard directories at: {packRootDirectory}[/]");
|
||||||
|
|
||||||
|
// 3. Create and save test objects
|
||||||
|
await CreateTestObjects(packRootDirectory, structure);
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine("\n[bold]Creation Complete![/] Use 'szpack pack' to compress it.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on red]❌ ERROR:[/] Failed to create datapack. Details: {ex.Message}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method for creating test objects (copied from previous Program.cs)
|
||||||
|
private static async Task CreateTestObjects(string rootPath, Dictionary<string, string> structure)
|
||||||
|
{
|
||||||
|
// ... (Test object creation logic remains the same, ensure you have the necessary usings in this file)
|
||||||
|
|
||||||
|
// --- Test object creation logic (omitted for brevity, assume the previous logic is here) ---
|
||||||
|
var testDataset = new Dataset { /* ... test data ... */ Id = "basic-attributes", Name = "Basic Character Attributes", SzType = "Dataset", Version = "1.0.0", SchemaVersion = "1.0.0", DatasetType = "Attribute", Entries = new() };
|
||||||
|
var dsPath = await DatapackService.SaveSzObjectAsync(testDataset, structure["datasets"]);
|
||||||
|
AnsiConsole.MarkupLine($" -> Saved Test Dataset: [yellow]{Path.GetFileName(dsPath)}[/]");
|
||||||
|
|
||||||
|
var testCharTemplate = new CharacterTemplate { /* ... test data ... */ Id = "default-char-sheet", Name = "Default Character Template", SzType = "Template", Version = "1.0.0", SchemaVersion = "1.0.0", Sections = new() };
|
||||||
|
var charPath = await DatapackService.SaveSzObjectAsync(testCharTemplate, structure["character_templates"]);
|
||||||
|
AnsiConsole.MarkupLine($" -> Saved Test Character Template: [yellow]{Path.GetFileName(charPath)}[/]");
|
||||||
|
|
||||||
|
var testSessionTemplate = new SessionTemplate
|
||||||
|
{
|
||||||
|
/* ... test data ... */ Id = "basic-encounter",
|
||||||
|
Name = "Basic Encounter Template",
|
||||||
|
SzType = "Template",
|
||||||
|
Version = "1.0.0",
|
||||||
|
SchemaVersion = "1.0.0",
|
||||||
|
CharacterTemplateLink = new()
|
||||||
|
{
|
||||||
|
DatapackId = Guid.Empty,
|
||||||
|
TemplateId = testCharTemplate.Id,
|
||||||
|
Version = testCharTemplate.Version
|
||||||
|
},
|
||||||
|
RequiredDatasets = new()
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
DatapackId = Guid.Empty,
|
||||||
|
DatasetId = testDataset.Id,
|
||||||
|
Version = testDataset.Version
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Sections = new()
|
||||||
|
};
|
||||||
|
var sessionPath = await DatapackService.SaveSzObjectAsync(testSessionTemplate, structure["session_templates"]);
|
||||||
|
AnsiConsole.MarkupLine($" -> Saved Test Session Template: [yellow]{Path.GetFileName(sessionPath)}[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
43
tools/szpack/PackCommand.cs
Normal file
43
tools/szpack/PackCommand.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* WARNING:
|
||||||
|
* This tool was created by an LLM based on the SessionZero shared lib project, therefore it is subject to errors and does not reflect the architecture of the SessionZero project.
|
||||||
|
* It was created to be used as a quick and dirty validation tool for the szpack format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using SessionZero.Shared.Services;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace SessionZero.Tools.Packer;
|
||||||
|
|
||||||
|
public class PackSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<input>")]
|
||||||
|
[Description("The root directory of the datapack to pack.")]
|
||||||
|
public required string Input { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PackCommand : Command<PackSettings>
|
||||||
|
{
|
||||||
|
public override int Execute([NotNull] CommandContext context, [NotNull] PackSettings settings, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on blue] --- Packing Datapack: {settings.Input} --- [/]");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var packDirectoryName = new DirectoryInfo(settings.Input).Name;
|
||||||
|
var outputFilePath = Path.Combine(Path.GetDirectoryName(settings.Input) ?? Environment.CurrentDirectory, $"{packDirectoryName}.szpack");
|
||||||
|
|
||||||
|
DatapackService.PackDatapack(settings.Input, outputFilePath);
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine($"[green]✅ Successfully created archive: {outputFilePath}[/]");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on red]❌ ERROR:[/] Failed to pack datapack. Details: {ex.Message}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
tools/szpack/Program.cs
Normal file
36
tools/szpack/Program.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* WARNING:
|
||||||
|
* This tool was created by an LLM based on the SessionZero shared lib project, therefore it is subject to errors and does not reflect the architecture of the SessionZero project.
|
||||||
|
* It was created to be used as a quick and dirty validation tool for the szpack format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace SessionZero.Tools.Packer;
|
||||||
|
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp();
|
||||||
|
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.SetApplicationName("szpack");
|
||||||
|
|
||||||
|
config.AddCommand<CreateCommand>("create")
|
||||||
|
.WithDescription("Creates a new datapack directory with test objects.");
|
||||||
|
|
||||||
|
config.AddCommand<PackCommand>("pack")
|
||||||
|
.WithDescription("Compresses a datapack directory into a .szpack file.");
|
||||||
|
|
||||||
|
config.AddCommand<UnpackCommand>("unpack")
|
||||||
|
.WithDescription("Extracts a .szpack file and displays its metadata.");
|
||||||
|
|
||||||
|
// Optional: Set a default command if no command is specified
|
||||||
|
// config.SetDefaultCommand<HelpCommand>();
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
55
tools/szpack/UnpackCommand.cs
Normal file
55
tools/szpack/UnpackCommand.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* WARNING:
|
||||||
|
* This tool was created by an LLM based on the SessionZero shared lib project, therefore it is subject to errors and does not reflect the architecture of the SessionZero project.
|
||||||
|
* It was created to be used as a quick and dirty validation tool for the szpack format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using SessionZero.Shared.Services;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace SessionZero.Tools.Packer;
|
||||||
|
|
||||||
|
public class UnpackSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<input>")]
|
||||||
|
[Description("The path to the .szpack file.")]
|
||||||
|
public required string Input { get; init; }
|
||||||
|
|
||||||
|
[CommandOption("-o|--output")]
|
||||||
|
[Description("The directory where the pack will be extracted.")]
|
||||||
|
[DefaultValue("unpacked")]
|
||||||
|
public string Output { get; init; } = "unpacked";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UnpackCommand : AsyncCommand<UnpackSettings>
|
||||||
|
{
|
||||||
|
public override async Task<int> ExecuteAsync([NotNull] CommandContext context, [NotNull] UnpackSettings settings, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on blue] --- Unpacking Datapack: {settings.Input} --- [/]");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Unpack the archive
|
||||||
|
DatapackService.UnpackDatapack(settings.Input, settings.Output);
|
||||||
|
AnsiConsole.MarkupLine($"[green]✅ Successfully unpacked archive to: {settings.Output}[/]");
|
||||||
|
|
||||||
|
// Load and display the core data
|
||||||
|
var datapack = await DatapackService.LoadDatapackMetadataAsync(settings.Output);
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine("\n[bold]--- Datapack Info (szpack.json) ---[/]");
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]ID:[/]\t\t{datapack.Id}");
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]Name:[/]\t{datapack.Name}");
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]Version:[/]\t{datapack.Version}");
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]Author:[/]\t{datapack.Author}");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"\n[bold white on red]❌ ERROR:[/] Failed to unpack or load datapack. Details: {ex.Message}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
tools/szpack/readme.md
Normal file
10
tools/szpack/readme.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# SZPACK CLI Tool
|
||||||
|
|
||||||
|
## ***WARNING:***
|
||||||
|
This tool was created by an LLM based on the SessionZero shared lib project, therefore it is subject to errors and does not reflect the architecture of the SessionZero project.
|
||||||
|
It was created to be used as a quick and dirty validation tool for the szpack format.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
* `szpack create <name>`: Creates a sample datapack directory with a given name
|
||||||
|
* `szpack pack <directory>`: Packs a datapack directory into a szpack file (must be a valid datapack)
|
||||||
|
* `szpack unpack <name.szpack>`: Unpacks a .szpack file into a datapack directory and displays some metadata
|
||||||
19
tools/szpack/szpack.csproj
Normal file
19
tools/szpack/szpack.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\SessionZero.Shared\SessionZero.Shared.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Spectre.Console" Version="0.52.1-preview.0.5" />
|
||||||
|
<PackageReference Include="Spectre.Console.Cli" Version="0.52.1-preview.0.5" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Loading…
Reference in New Issue
Block a user