fix: join legacy settings with download selections
This commit is contained in:
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Launcher.Next.Core;
|
||||||
|
|
||||||
|
namespace Launcher.Next.Application;
|
||||||
|
|
||||||
|
public sealed record LegacyPluginDefinition(string Id, string Renewal, string Catalog, string Install, int DefinitionOrder);
|
||||||
|
public sealed record LegacyProductPattern(string Name, string Filter, string Roster, IReadOnlyList<LegacyPluginDefinition> Plugins);
|
||||||
|
public sealed record LegacyLauncherSettings(string Help, string CareMarker, IReadOnlyList<LegacyProductPattern> Patterns);
|
||||||
|
public sealed record LegacyDownloadSelection(IReadOnlyList<string> PluginIds);
|
||||||
|
public sealed record LegacyCompatibilityMapping(string LegacyId, string PackageId, string Version, string Channel);
|
||||||
|
public sealed record LegacyCompatibilityOverlay(string MappingId, string Product, int ProductYear, string Architecture, bool AllowOfflineFallback, IReadOnlyList<LegacyCompatibilityMapping> Plugins);
|
||||||
|
|
||||||
|
public sealed class LegacyConfigurationAdapter
|
||||||
|
{
|
||||||
|
private static readonly XmlReaderSettings XmlSettings = new() { DtdProcessing = DtdProcessing.Prohibit, XmlResolver = null, MaxCharactersInDocument = 1_000_000 };
|
||||||
|
|
||||||
|
public LegacyLauncherSettings ParseSettings(string xml)
|
||||||
|
{
|
||||||
|
using var reader = XmlReader.Create(new StringReader(xml), XmlSettings); var root = XDocument.Load(reader).Root ?? throw new InvalidOperationException("LEGACY_SETTINGS_INVALID");
|
||||||
|
var path = root.Element("path") ?? throw new InvalidOperationException("LEGACY_SETTINGS_PATH_MISSING");
|
||||||
|
var patterns = root.Elements("data").Select(data =>
|
||||||
|
{
|
||||||
|
var pattern = data.Element("pattern") ?? throw new InvalidOperationException("LEGACY_PATTERN_MISSING");
|
||||||
|
string Value(string name) => pattern.Element(name)?.Value ?? throw new InvalidOperationException("LEGACY_PATTERN_FIELD_MISSING:" + name);
|
||||||
|
var plugins = data.Elements("plugin").Select((plugin, index) => new LegacyPluginDefinition(
|
||||||
|
plugin.Element("id")?.Value ?? throw new InvalidOperationException("LEGACY_PLUGIN_ID_MISSING"),
|
||||||
|
plugin.Element("renewal")?.Value ?? throw new InvalidOperationException("LEGACY_RENEWAL_MISSING"),
|
||||||
|
plugin.Element("catalog")?.Value ?? throw new InvalidOperationException("LEGACY_CATALOG_MISSING"),
|
||||||
|
plugin.Element("install")?.Value ?? throw new InvalidOperationException("LEGACY_INSTALL_MISSING"), index)).ToArray();
|
||||||
|
return new LegacyProductPattern(Value("name"), Value("filter"), Value("roster"), plugins);
|
||||||
|
}).ToArray();
|
||||||
|
return new(path.Element("help")?.Value ?? throw new InvalidOperationException("LEGACY_HELP_MISSING"), path.Element("care")?.Value ?? throw new InvalidOperationException("LEGACY_CARE_MISSING"), patterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyDownloadSelection ParseDownloadList(string xml)
|
||||||
|
{
|
||||||
|
using var reader = XmlReader.Create(new StringReader(xml), XmlSettings); var root = XDocument.Load(reader).Root;
|
||||||
|
if (root?.Name != "root") throw new InvalidOperationException("LEGACY_DOWNLOAD_LIST_INVALID");
|
||||||
|
var ids = root.Elements("id").Select(x => x.Value.Trim()).ToArray();
|
||||||
|
if (ids.Length == 0 || ids.Any(string.IsNullOrWhiteSpace) || ids.GroupBy(x => x, StringComparer.OrdinalIgnoreCase).Any(x => x.Count() > 1))
|
||||||
|
throw new InvalidOperationException("LEGACY_DOWNLOAD_SELECTION_INVALID");
|
||||||
|
return new(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<PackageRequirement> Join(LegacyProductPattern pattern, LegacyDownloadSelection selection, LegacyCompatibilityOverlay overlay)
|
||||||
|
{
|
||||||
|
var result = new List<PackageRequirement>();
|
||||||
|
foreach (var id in selection.PluginIds)
|
||||||
|
{
|
||||||
|
var definition = pattern.Plugins.Where(x => string.Equals(x.Id, id, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||||
|
if (definition.Length == 0) throw new InvalidOperationException("LEGACY_PLUGIN_ID_NOT_DEFINED");
|
||||||
|
if (definition.Length > 1) throw new InvalidOperationException("AMBIGUOUS_LEGACY_PLUGIN_DEFINITION");
|
||||||
|
var mapping = overlay.Plugins.Where(x => string.Equals(x.LegacyId, id, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||||
|
if (mapping.Length == 0) throw new InvalidOperationException("LEGACY_MAPPING_NOT_FOUND");
|
||||||
|
if (mapping.Length > 1) throw new InvalidOperationException("LEGACY_MAPPING_DUPLICATE");
|
||||||
|
result.Add(new(mapping[0].PackageId, overlay.Product, overlay.ProductYear, overlay.Architecture, mapping[0].Channel, mapping[0].Version, overlay.MappingId, overlay.AllowOfflineFallback));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,24 @@ public sealed class RosterAdaptersTests
|
|||||||
Assert.False(selected.Roster.Packages[1].Enabled);
|
Assert.False(selected.Roster.Packages[1].Enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LegacySettingsAndDownloadList_JoinOnlyThroughExplicitOverlay()
|
||||||
|
{
|
||||||
|
const string settings = "<root><path><help>h</help><care>c</care></path><data><pattern><name>Plant</name><filter>*.dwg</filter><roster>r</roster></pattern><plugin><id>legacy-a</id><renewal>x</renewal><catalog>cat</catalog><install>load</install></plugin></data></root>";
|
||||||
|
const string selection = "<root><id>legacy-a</id></root>";
|
||||||
|
var adapter = new LegacyConfigurationAdapter();
|
||||||
|
var parsed = adapter.ParseSettings(settings);
|
||||||
|
var requirements = adapter.Join(parsed.Patterns[0], adapter.ParseDownloadList(selection), new("map-a", "Plant3D", 2026, "x64", false, [new("legacy-a", "PHIM.A", "1.0.0", "pilot")]));
|
||||||
|
Assert.Single(requirements); Assert.Equal("PHIM.A", requirements[0].PackageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LegacyDownloadList_DoesNotInventPluginMetadata()
|
||||||
|
{
|
||||||
|
var selection = new LegacyConfigurationAdapter().ParseDownloadList("<root><id>legacy-a</id></root>");
|
||||||
|
Assert.Equal(["legacy-a"], selection.PluginIds);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ProjectRoster_HasPriorityOverLegacy()
|
public void ProjectRoster_HasPriorityOverLegacy()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user