acdream/src/AcDream.App/Platform/GraphicalLegacyConfigurationMigrator.cs
Erik cb6502c8a5 feat(platform): Campaign LA LA0 — extract ApplicationPathSet to AcDream.Platform
The launcher (LA3/LA4) needs the XDG/Windows path contract
(ApplicationPathSet/IApplicationPathEnvironment) without pulling in any
gameplay assembly. Move it out of AcDream.Runtime into a new BCL-only
AcDream.Platform project so the launcher-side Launcher.Core project can
reference it directly per the campaign plan (docs/plans/2026-08-14-launcher-campaign.md,
LA0). Namespace renamed AcDream.Runtime.Platform -> AcDream.Platform;
code is otherwise byte-identical (no logic changes).

AcDream.Runtime now carries a ProjectReference to AcDream.Platform and
re-exports it transitively, so App and Headless keep resolving the type
without a direct reference and K0's Headless single-ProjectReference
guard (HeadlessAssemblyReferencesOnlyTheRuntimeProject) stands unchanged.
The sibling Runtime dependency-boundary guard
(RuntimeProjectDeclaresOnlyApprovedProjectDependencies) does assert
Runtime's own project-reference set, so it needed a deliberate,
documented addition of AcDream.Platform to its expected list.

Moved tests/AcDream.Runtime.Tests/Platform/ApplicationPathSetTests.cs to
a new tests/AcDream.Platform.Tests/ project (namespace
AcDream.Platform.Tests) referencing only AcDream.Platform. Registered
both new projects in AcDream.slnx.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:19:02 +02:00

50 lines
1.5 KiB
C#

using AcDream.Platform;
namespace AcDream.App.Platform;
internal static class GraphicalLegacyConfigurationMigrator
{
private static readonly string[] FileNames =
[
"settings.json",
"keybinds.json",
];
internal static IReadOnlyList<string> Migrate(
ApplicationPathSet paths)
{
ArgumentNullException.ThrowIfNull(paths);
if (paths.LegacyConfigDirectory is not { } legacyDirectory
|| PathsEqual(legacyDirectory, paths.ConfigDirectory))
{
return [];
}
List<string>? migrated = null;
foreach (string fileName in FileNames)
{
string source = Path.Combine(legacyDirectory, fileName);
string destination = Path.Combine(
paths.ConfigDirectory,
fileName);
if (!File.Exists(source) || File.Exists(destination))
continue;
Directory.CreateDirectory(paths.ConfigDirectory);
File.Copy(source, destination, overwrite: false);
(migrated ??= []).Add(destination);
}
return migrated ?? [];
}
private static bool PathsEqual(string left, string right) =>
string.Equals(
Path.TrimEndingDirectorySeparator(
Path.GetFullPath(left)),
Path.TrimEndingDirectorySeparator(
Path.GetFullPath(right)),
OperatingSystem.IsWindows()
? StringComparison.OrdinalIgnoreCase
: StringComparison.Ordinal);
}