feat: add Godot C# compatibility and shared codegen weaving
Validate ShrinkSDK Workspace / unity (push) Failing after 3m18s
Validate ShrinkSDK Workspace / unity (push) Failing after 3m18s
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.CodeGenFixture</AssemblyName>
|
||||
<ShrinkCodeGenEnabled>true</ShrinkCodeGenEnabled>
|
||||
<SignAssembly Condition="'$(FixtureSignAssembly)' == 'true'">true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile Condition="'$(FixtureSignAssembly)' == 'true'">$(FixtureStrongNameKeyFile)</AssemblyOriginatorKeyFile>
|
||||
<_ShrinkCodeGenTaskAssembly>$(MSBuildThisFileDirectory)..\..\CodeGen\ShrinkSDK.CodeGen.Task\bin\$(Configuration)\net8.0\ShrinkSDK.CodeGen.Task.dll</_ShrinkCodeGenTaskAssembly>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Runtime.Abstractions\ShrinkSDK.Runtime.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.EventBus\ShrinkSDK.EventBus.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Command\ShrinkSDK.Command.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Network\ShrinkSDK.Network.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Network.Integration.EventBus\ShrinkSDK.Network.Integration.EventBus.csproj" />
|
||||
<ProjectReference Include="..\..\CodeGen\ShrinkSDK.CodeGen.Task\ShrinkSDK.CodeGen.Task.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\CodeGen\ShrinkSDK.CodeGen.Task\buildTransitive\ShrinkSDK.CodeGen.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,79 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ShrinkCommand;
|
||||
using ShrinkEventBus;
|
||||
using ShrinkNetwork;
|
||||
using ShrinkNetwork.Integration;
|
||||
using ShrinkSDK.Runtime;
|
||||
|
||||
var assembly = typeof(Program).Assembly;
|
||||
var marker = assembly.GetCustomAttributes(typeof(ShrinkCodeGenWovenAttribute), false)
|
||||
.Cast<ShrinkCodeGenWovenAttribute>()
|
||||
.SingleOrDefault() ?? throw new InvalidOperationException("CodeGen marker is missing.");
|
||||
if (marker.WeaverVersion != "0.1.0" || !Guid.TryParse(marker.InputMvid, out _))
|
||||
throw new InvalidOperationException("CodeGen marker is invalid.");
|
||||
|
||||
if (!typeof(InstanceSubscriber).GetInterfaces().Contains(typeof(IShrinkGeneratedSubscriber)))
|
||||
throw new InvalidOperationException("Generated subscriber interface is missing.");
|
||||
|
||||
using var binding = EventBus.Attach(new InstanceSubscriber());
|
||||
EventBus.Post(new FixtureEvent());
|
||||
if (InstanceSubscriber.Calls != 1 || StaticSubscriber.Calls != 1)
|
||||
throw new InvalidOperationException($"Generated EventBus bindings failed: instance={InstanceSubscriber.Calls}, static={StaticSubscriber.Calls}.");
|
||||
|
||||
if (assembly.GetCustomAttributes(typeof(ShrinkCommandStaticRegistryAttribute), false).Length != 1)
|
||||
throw new InvalidOperationException("Command registry metadata is missing.");
|
||||
if (assembly.GetCustomAttributes(typeof(ShrinkNetworkMessageRegistryAttribute), false).Length != 1)
|
||||
throw new InvalidOperationException("Network message registry metadata is missing.");
|
||||
if (assembly.GetCustomAttributes(typeof(ShrinkNetworkStaticSubscriberRegistryAttribute), false).Length != 1)
|
||||
throw new InvalidOperationException("Network subscriber registry metadata is missing.");
|
||||
var bridgeRegistrations = (System.Collections.IEnumerable)(typeof(ShrinkNetworkEventRegistry)
|
||||
.GetMethod("Snapshot", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)!
|
||||
.Invoke(null, null) ?? throw new InvalidOperationException("Network EventBus registry snapshot failed."));
|
||||
if (!bridgeRegistrations.Cast<object>().Any(item => item.GetType().GetProperty("EventType")?.GetValue(item) as Type == typeof(FixtureNetworkEvent)))
|
||||
throw new InvalidOperationException("Generated Network/EventBus binding is missing.");
|
||||
|
||||
Console.WriteLine($"PASS CodeGen {marker.WeaverVersion}: EventBus + Command + Network + Network/EventBus registries");
|
||||
|
||||
public readonly struct FixtureEvent : IShrinkEvent { }
|
||||
|
||||
[ShrinkEventSubscriber]
|
||||
public sealed class InstanceSubscriber
|
||||
{
|
||||
public static int Calls;
|
||||
|
||||
[ShrinkSubscribe]
|
||||
private void OnEvent(FixtureEvent value) => Calls++;
|
||||
}
|
||||
|
||||
[ShrinkEventSubscriber]
|
||||
public static class StaticSubscriber
|
||||
{
|
||||
public static int Calls;
|
||||
|
||||
[ShrinkSubscribe]
|
||||
private static void OnEvent(FixtureEvent value) => Calls++;
|
||||
}
|
||||
|
||||
[ShrinkCommandSubscriber]
|
||||
public static class FixtureCommands
|
||||
{
|
||||
[ShrinkCommand("fixture/ping")]
|
||||
public static void Ping() { }
|
||||
}
|
||||
|
||||
[ShrinkNetworkMessage(41001, "fixture/ping")]
|
||||
public sealed class FixtureMessage : IShrinkNetworkMessage { }
|
||||
|
||||
[ShrinkNetworkEvent]
|
||||
[ShrinkNetworkMessage(41002, "fixture/event")]
|
||||
public sealed class FixtureNetworkEvent : IShrinkEvent, IShrinkNetworkMessage { }
|
||||
|
||||
[ShrinkNetworkSubscriber]
|
||||
public static class FixtureNetworkHandlers
|
||||
{
|
||||
[ShrinkNetworkSubscribe]
|
||||
public static void Handle(FixtureMessage message) { }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.CodeGenValidation</AssemblyName>
|
||||
<ShrinkCodeGenEnabled>false</ShrinkCodeGenEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\CodeGen\ShrinkSDK.CodeGen.Core\ShrinkSDK.CodeGen.Core.csproj" />
|
||||
<PackageReference Include="Mono.Cecil" Version="0.11.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,163 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Mono.Cecil;
|
||||
using ShrinkSDK.CodeGen;
|
||||
|
||||
if (args.Length == 2 && args[0] == "--marker")
|
||||
{
|
||||
using var exported = AssemblyDefinition.ReadAssembly(args[1]);
|
||||
var marker = exported.CustomAttributes.SingleOrDefault(attribute =>
|
||||
attribute.AttributeType.FullName == "ShrinkSDK.Runtime.ShrinkCodeGenWovenAttribute");
|
||||
Require(marker != null, "exported assembly has no ShrinkSDK CodeGen marker");
|
||||
Require(exported.MainModule.Types.Any(type => type.FullName ==
|
||||
"ShrinkEventBus.Generated.ShrinkGeneratedStaticBindings"),
|
||||
"exported assembly has no static EventBus bootstrap");
|
||||
Console.WriteLine($"PASS exported assembly woven by {marker!.ConstructorArguments[0].Value}");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((args.Length == 3 || args.Length == 4) && args[0] == "--resign")
|
||||
{
|
||||
var signedAssembly = Path.GetFullPath(args[1]);
|
||||
var keepOutput = args.Length == 4;
|
||||
var output = keepOutput
|
||||
? Path.GetFullPath(args[3])
|
||||
: Path.Combine(Path.GetTempPath(), "ShrinkSDK.CodeGen.Resigned." + Guid.NewGuid().ToString("N") + ".dll");
|
||||
var outputPdb = Path.ChangeExtension(output, ".pdb");
|
||||
try
|
||||
{
|
||||
var result = ShrinkAssemblyWeaver.Weave(signedAssembly, Path.ChangeExtension(signedAssembly, ".pdb"),
|
||||
BuildReferences(Path.GetDirectoryName(signedAssembly)!), output, outputPdb,
|
||||
ShrinkCodeGenPlatform.EngineNeutral, args[2]);
|
||||
Require(result.Succeeded && result.Changed,
|
||||
"signed assembly re-weave failed: " + string.Join(" | ", result.Diagnostics.Select(item => item.Message)));
|
||||
using var resigned = AssemblyDefinition.ReadAssembly(output);
|
||||
Require(resigned.Name.HasPublicKey, "re-signed output has no public key");
|
||||
Console.WriteLine("PASS signed assembly woven and re-signed with explicit key");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!keepOutput)
|
||||
{
|
||||
if (File.Exists(output)) File.Delete(output);
|
||||
if (File.Exists(outputPdb)) File.Delete(outputPdb);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Length != 1 || !File.Exists(args[0]))
|
||||
throw new ArgumentException("Pass the unwoven CodeGenFixture assembly path.");
|
||||
|
||||
var sourceAssembly = Path.GetFullPath(args[0]);
|
||||
var sourceDirectory = Path.GetDirectoryName(sourceAssembly)!;
|
||||
var sourcePdb = Path.ChangeExtension(sourceAssembly, ".pdb");
|
||||
var references = BuildReferences(sourceDirectory);
|
||||
var root = Path.Combine(Path.GetTempPath(), "ShrinkSDK.CodeGen.Validation", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(root);
|
||||
try
|
||||
{
|
||||
var woven = Path.Combine(root, "fixture.woven.dll");
|
||||
var wovenPdb = Path.Combine(root, "fixture.woven.pdb");
|
||||
var first = ShrinkAssemblyWeaver.Weave(sourceAssembly, sourcePdb, references, woven, wovenPdb);
|
||||
Require(first.Succeeded && first.Changed,
|
||||
"single weave did not change the assembly: " + string.Join(" | ", first.Diagnostics.Select(item => item.Message)));
|
||||
Require(first.InstanceSubscribers == 1 && first.StaticSubscribers == 1 && first.RegistryEntries == 5,
|
||||
$"unexpected generated counts: {first.InstanceSubscribers}/{first.StaticSubscribers}/{first.RegistryEntries}");
|
||||
VerifyStructure(woven);
|
||||
|
||||
var second = ShrinkAssemblyWeaver.Weave(woven, wovenPdb, references.Append(woven),
|
||||
Path.Combine(root, "twice.dll"), Path.Combine(root, "twice.pdb"));
|
||||
Require(second.Succeeded && !second.Changed, "repeated weave was not idempotent");
|
||||
|
||||
var corruptPdb = Path.Combine(root, "corrupt.pdb");
|
||||
File.WriteAllText(corruptPdb, "not a portable pdb");
|
||||
var corrupt = ShrinkAssemblyWeaver.Weave(sourceAssembly, corruptPdb, references,
|
||||
Path.Combine(root, "corrupt.dll"), Path.Combine(root, "corrupt.out.pdb"));
|
||||
Require(!corrupt.Succeeded && !File.Exists(Path.Combine(root, "corrupt.dll")),
|
||||
"damaged PDB was not rejected atomically");
|
||||
|
||||
var missing = ShrinkAssemblyWeaver.Weave(sourceAssembly, null, Array.Empty<string>(),
|
||||
Path.Combine(root, "missing.dll"), null);
|
||||
Require(!missing.Succeeded, "missing dependencies were not rejected");
|
||||
|
||||
var signedInput = Path.Combine(root, "signed.dll");
|
||||
using (var assembly = AssemblyDefinition.ReadAssembly(sourceAssembly))
|
||||
{
|
||||
assembly.Name.PublicKey = Enumerable.Range(0, 160).Select(value => (byte)(value + 1)).ToArray();
|
||||
assembly.Name.Attributes |= AssemblyAttributes.PublicKey;
|
||||
assembly.Write(signedInput);
|
||||
}
|
||||
var signed = ShrinkAssemblyWeaver.Weave(signedInput, null, references,
|
||||
Path.Combine(root, "signed.out.dll"), null);
|
||||
Require(!signed.Succeeded && signed.Diagnostics.Any(item => item.Message.Contains("Signed assemblies")),
|
||||
"signed assembly was not rejected");
|
||||
|
||||
var parallel = Enumerable.Range(0, 4).Select(index => Task.Run(() =>
|
||||
{
|
||||
var output = Path.Combine(root, $"parallel-{index}.dll");
|
||||
var outputPdb = Path.Combine(root, $"parallel-{index}.pdb");
|
||||
return ShrinkAssemblyWeaver.Weave(sourceAssembly, sourcePdb, references, output, outputPdb);
|
||||
})).ToArray();
|
||||
await Task.WhenAll(parallel);
|
||||
Require(parallel.All(task => task.Result.Succeeded && task.Result.Changed),
|
||||
"parallel weaving of independent assemblies failed");
|
||||
|
||||
Console.WriteLine("PASS Cecil structure + single/repeat/parallel weave + corrupt PDB/signed/missing dependency guards");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(root, true);
|
||||
}
|
||||
|
||||
static void VerifyStructure(string path)
|
||||
{
|
||||
using var assembly = AssemblyDefinition.ReadAssembly(path);
|
||||
var module = assembly.MainModule;
|
||||
var instance = module.Types.Single(type => type.Name == "InstanceSubscriber");
|
||||
Require(instance.Interfaces.Any(item => item.InterfaceType.FullName == "ShrinkEventBus.IShrinkGeneratedSubscriber"),
|
||||
"generated subscriber interface is missing");
|
||||
Require(instance.Methods.Any(method => method.Name == "ShrinkEventBus.IShrinkGeneratedSubscriber.AttachGenerated"),
|
||||
"AttachGenerated is missing");
|
||||
Require(module.Types.Any(type => type.FullName == "ShrinkEventBus.Generated.ShrinkGeneratedStaticBindings"),
|
||||
"static binding bootstrap is missing");
|
||||
Require(module.Types.Any(type => type.FullName ==
|
||||
"ShrinkNetwork.Integration.Generated.ShrinkGeneratedNetworkEventBindings"),
|
||||
"Network/EventBus generated bootstrap is missing");
|
||||
var moduleInitializer = module.Types.Single(type => type.Name == "<Module>").Methods.Single(method => method.Name == ".cctor");
|
||||
Require(moduleInitializer.Body.Instructions.Any(instruction => instruction.Operand is MethodReference method && method.Name == "Register"),
|
||||
"module initializer does not call static registration");
|
||||
var attributes = assembly.CustomAttributes.Select(attribute => attribute.AttributeType.FullName).ToArray();
|
||||
foreach (var expected in new[]
|
||||
{
|
||||
"ShrinkSDK.Runtime.ShrinkCodeGenWovenAttribute",
|
||||
"ShrinkCommand.ShrinkCommandStaticRegistryAttribute",
|
||||
"ShrinkNetwork.ShrinkNetworkMessageRegistryAttribute",
|
||||
"ShrinkNetwork.ShrinkNetworkStaticSubscriberRegistryAttribute"
|
||||
})
|
||||
Require(attributes.Contains(expected), $"assembly registry is missing: {expected}");
|
||||
}
|
||||
|
||||
static void Require(bool condition, string message)
|
||||
{
|
||||
if (!condition) throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
static string[] BuildReferences(string sourceDirectory)
|
||||
{
|
||||
var referencePackRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
||||
".nuget", "packages", "microsoft.netcore.app.ref");
|
||||
var referencePack = Directory.GetDirectories(referencePackRoot)
|
||||
.Select(path => Path.Combine(path, "ref", "net8.0"))
|
||||
.Where(Directory.Exists)
|
||||
.OrderByDescending(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.First();
|
||||
return Directory.GetFiles(sourceDirectory, "*.dll")
|
||||
.Concat(Directory.GetFiles(referencePack, "*.dll"))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.InstallerFixture</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Installer\ShrinkSDK.Godot.Installer.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,65 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using ShrinkSDK.Godot.Editor;
|
||||
using ShrinkSDK.Installer;
|
||||
|
||||
var root = Path.Combine(Path.GetTempPath(), "ShrinkSDK.InstallerFixture", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(root);
|
||||
try
|
||||
{
|
||||
var project = Path.Combine(root, "Fixture.csproj");
|
||||
File.WriteAllText(project, """
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup><TargetFramework>net8.0</TargetFramework><FixtureValue>keep</FixtureValue></PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Existing.Package" Version="1.2.3" />
|
||||
<PackageReference Include="Child.Version.Package"><Version>3.4.5</Version></PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
""");
|
||||
var config = Path.Combine(root, "NuGet.Config");
|
||||
File.WriteAllText(config, """
|
||||
<configuration><packageSources><add key="Existing" value="https://example.invalid/v3/index.json" /></packageSources></configuration>
|
||||
""");
|
||||
|
||||
ShrinkProjectPackageEditor.SetPackageReference(project, "ShrinkSDK.EventBus", "2.1.0");
|
||||
ShrinkProjectPackageEditor.SetPackageReference(project, "ShrinkSDK.EventBus", "2.1.0");
|
||||
var installed = XDocument.Load(project);
|
||||
Require(installed.Descendants("PackageReference").Count(element =>
|
||||
(string?)element.Attribute("Include") == "ShrinkSDK.EventBus") == 1, "package reference was duplicated");
|
||||
Require(installed.ToString().Contains("Existing.Package") && installed.ToString().Contains("FixtureValue"),
|
||||
"unrelated project content was changed");
|
||||
var installedVersions = ShrinkProjectPackageEditor.ReadPackageReferences(project);
|
||||
Require(installedVersions["ShrinkSDK.EventBus"] == "2.1.0", "installed version was not read correctly");
|
||||
Require(installedVersions["Child.Version.Package"] == "3.4.5", "child Version element was not read correctly");
|
||||
Require(ShrinkPackageVersion.Classify("2.2.0", "2.1.0") == ShrinkPackageVersionRelation.Newer,
|
||||
"newer installed version was classified as outdated");
|
||||
Require(ShrinkPackageVersion.Classify("2.1.0-preview.10", "2.1.0-preview.2") ==
|
||||
ShrinkPackageVersionRelation.Newer, "prerelease versions were not ordered semantically");
|
||||
|
||||
ShrinkProjectPackageEditor.SetPackageReference(project, "ShrinkSDK.EventBus", null);
|
||||
Require(!XDocument.Load(project).Descendants("PackageReference").Any(element =>
|
||||
(string?)element.Attribute("Include") == "ShrinkSDK.EventBus"), "package reference was not removed");
|
||||
|
||||
ShrinkProjectPackageEditor.EnsureShrinkFeed(config);
|
||||
ShrinkProjectPackageEditor.EnsureShrinkFeed(config);
|
||||
var sources = XDocument.Load(config).Descendants("add").ToArray();
|
||||
Require(sources.Count(element => (string?)element.Attribute("key") == "ShrinkSDK") == 1,
|
||||
"ShrinkSDK feed was duplicated");
|
||||
Require(sources.Any(element => (string?)element.Attribute("key") == "Existing"),
|
||||
"existing NuGet source was removed");
|
||||
Console.WriteLine("PASS Godot Installer atomic package/feed install-update-remove merge");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(root, true);
|
||||
}
|
||||
|
||||
static void Require(bool condition, string message)
|
||||
{
|
||||
if (!condition) throw new InvalidOperationException(message);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using ShrinkNetwork;
|
||||
|
||||
[ShrinkNetworkMessage(49999, "duplicate")]
|
||||
public sealed class DuplicateMessageA : IShrinkNetworkMessage { }
|
||||
|
||||
[ShrinkNetworkMessage(49999, "duplicate")]
|
||||
public sealed class DuplicateMessageB : IShrinkNetworkMessage { }
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.InvalidCodeGenFixture</AssemblyName>
|
||||
<ShrinkCodeGenEnabled>true</ShrinkCodeGenEnabled>
|
||||
<RunAnalyzers>false</RunAnalyzers>
|
||||
<_ShrinkCodeGenTaskAssembly>$(MSBuildThisFileDirectory)..\..\CodeGen\ShrinkSDK.CodeGen.Task\bin\$(Configuration)\net8.0\ShrinkSDK.CodeGen.Task.dll</_ShrinkCodeGenTaskAssembly>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Runtime.Abstractions\ShrinkSDK.Runtime.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Network\ShrinkSDK.Network.csproj" />
|
||||
<ProjectReference Include="..\..\CodeGen\ShrinkSDK.CodeGen.Task\ShrinkSDK.CodeGen.Task.csproj" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\CodeGen\ShrinkSDK.CodeGen.Task\buildTransitive\ShrinkSDK.CodeGen.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
using ShrinkCommand;
|
||||
using ShrinkEventBus;
|
||||
using ShrinkModFramework;
|
||||
|
||||
[ShrinkMod("fixture.mod", "Fixture Mod", "1.0.0")]
|
||||
public sealed class FixtureMod : ShrinkModBase, IShrinkModUnload
|
||||
{
|
||||
public bool Ready { get; private set; }
|
||||
public int UnloadCalls { get; private set; }
|
||||
public override void OnReady(ShrinkModContext context) => Ready = true;
|
||||
public void OnUnload(ShrinkModContext context) => UnloadCalls++;
|
||||
}
|
||||
|
||||
public readonly struct ModFixtureEvent : IShrinkEvent { }
|
||||
|
||||
[ShrinkEventSubscriber]
|
||||
public static class ModFixtureEvents
|
||||
{
|
||||
public static int Calls { get; private set; }
|
||||
[ShrinkSubscribe] private static void Handle(ModFixtureEvent value) => Calls++;
|
||||
}
|
||||
|
||||
[ShrinkCommandSubscriber]
|
||||
public static class ModFixtureCommands
|
||||
{
|
||||
[ShrinkCommand("mod-fixture/ping")] public static void Ping() { }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.ModFixture</AssemblyName>
|
||||
<ShrinkCodeGenEnabled>true</ShrinkCodeGenEnabled>
|
||||
<_ShrinkCodeGenTaskAssembly>$(MSBuildThisFileDirectory)..\..\CodeGen\ShrinkSDK.CodeGen.Task\bin\$(Configuration)\net8.0\ShrinkSDK.CodeGen.Task.dll</_ShrinkCodeGenTaskAssembly>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Runtime.Abstractions\ShrinkSDK.Runtime.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.ModFramework\ShrinkSDK.ModFramework.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.EventBus\ShrinkSDK.EventBus.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Command\ShrinkSDK.Command.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\CodeGen\ShrinkSDK.CodeGen.Task\buildTransitive\ShrinkSDK.CodeGen.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.ModHostFixture</AssemblyName>
|
||||
<ShrinkCodeGenEnabled>false</ShrinkCodeGenEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.ModFramework.Godot\ShrinkSDK.ModFramework.Godot.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.EventBus\ShrinkSDK.EventBus.csproj" />
|
||||
<ProjectReference Include="..\..\Packages\ShrinkSDK.Command\ShrinkSDK.Command.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ShrinkCommand;
|
||||
using ShrinkEventBus;
|
||||
using ShrinkModFramework.Godot;
|
||||
|
||||
if (args.Length != 1 || !File.Exists(args[0]))
|
||||
throw new ArgumentException("Pass the woven mod assembly path.");
|
||||
|
||||
using var loader = new ShrinkGodotModLoader();
|
||||
var instances = loader.Load(args[0]);
|
||||
if (instances.Count != 1) throw new InvalidOperationException("Mod entry was not discovered.");
|
||||
var mod = instances[0];
|
||||
var type = mod.GetType();
|
||||
if (type.GetProperty("Ready")?.GetValue(mod) is not true)
|
||||
throw new InvalidOperationException("Mod lifecycle did not reach OnReady.");
|
||||
var assembly = type.Assembly;
|
||||
if (assembly.GetCustomAttributes(typeof(ShrinkCommandStaticRegistryAttribute), false).Length != 1)
|
||||
throw new InvalidOperationException("Mod command registry metadata is missing.");
|
||||
var eventType = assembly.GetType("ModFixtureEvent") ?? throw new InvalidOperationException("Mod event is missing.");
|
||||
var post = typeof(EventBus).GetMethods(BindingFlags.Public | BindingFlags.Static)
|
||||
.Single(method => method.Name == "Post" && method.IsGenericMethodDefinition && method.GetParameters().Length == 1)
|
||||
.MakeGenericMethod(eventType);
|
||||
post.Invoke(null, new[] { Activator.CreateInstance(eventType) });
|
||||
var eventSubscriber = assembly.GetType("ModFixtureEvents") ?? throw new InvalidOperationException("Mod static subscriber is missing.");
|
||||
if ((int?)eventSubscriber.GetProperty("Calls", BindingFlags.Public | BindingFlags.Static)?.GetValue(null) != 1)
|
||||
throw new InvalidOperationException("Mod static EventBus binding did not run.");
|
||||
if (!loader.Unload(args[0])) throw new InvalidOperationException("Mod unload failed.");
|
||||
if ((int?)type.GetProperty("UnloadCalls")?.GetValue(mod) != 1)
|
||||
throw new InvalidOperationException("Mod OnUnload was not called.");
|
||||
if (loader.LoadedAssemblyPaths.Count != 0)
|
||||
throw new InvalidOperationException("Mod remained registered after unload.");
|
||||
Console.WriteLine("PASS external netstandard2.1 mod CodeGen + Godot AssemblyLoadContext lifecycle");
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>ShrinkSDK.NuGetConsumer</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ShrinkSDK.EventBus" Version="2.1.0" />
|
||||
<PackageReference Include="ShrinkSDK.Command" Version="0.3.0" />
|
||||
<PackageReference Include="ShrinkSDK.Network" Version="0.3.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,46 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ShrinkCommand;
|
||||
using ShrinkEventBus;
|
||||
using ShrinkNetwork;
|
||||
using ShrinkSDK.Runtime;
|
||||
|
||||
var assembly = typeof(Program).Assembly;
|
||||
var marker = assembly.GetCustomAttributes(typeof(ShrinkCodeGenWovenAttribute), false)
|
||||
.Cast<ShrinkCodeGenWovenAttribute>().SingleOrDefault()
|
||||
?? throw new InvalidOperationException("buildTransitive CodeGen did not run.");
|
||||
using var binding = EventBus.Attach(new NuGetSubscriber());
|
||||
EventBus.Post(new NuGetEvent());
|
||||
if (NuGetSubscriber.Calls != 1 || NuGetStaticSubscriber.Calls != 1)
|
||||
throw new InvalidOperationException("NuGet EventBus weaving failed.");
|
||||
if (assembly.GetCustomAttributes(typeof(ShrinkCommandStaticRegistryAttribute), false).Length != 1 ||
|
||||
assembly.GetCustomAttributes(typeof(ShrinkNetworkMessageRegistryAttribute), false).Length != 1)
|
||||
throw new InvalidOperationException("NuGet registries are missing.");
|
||||
Console.WriteLine($"PASS NuGet buildTransitive CodeGen {marker.WeaverVersion}");
|
||||
|
||||
public readonly struct NuGetEvent : IShrinkEvent { }
|
||||
|
||||
[ShrinkEventSubscriber]
|
||||
public sealed class NuGetSubscriber
|
||||
{
|
||||
public static int Calls;
|
||||
[ShrinkSubscribe] private void Handle(NuGetEvent value) => Calls++;
|
||||
}
|
||||
|
||||
[ShrinkEventSubscriber]
|
||||
public static class NuGetStaticSubscriber
|
||||
{
|
||||
public static int Calls;
|
||||
[ShrinkSubscribe] private static void Handle(NuGetEvent value) => Calls++;
|
||||
}
|
||||
|
||||
[ShrinkCommandSubscriber]
|
||||
public static class NuGetCommands
|
||||
{
|
||||
[ShrinkCommand("nuget/smoke")] public static void Smoke() { }
|
||||
}
|
||||
|
||||
[ShrinkNetworkMessage(43001, "nuget/smoke")]
|
||||
public sealed class NuGetMessage : IShrinkNetworkMessage { }
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<AssemblyName>ShrinkSDK.UnityAdapterCompile</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\Assets\Modules\ShrinkShared.CodeGen\Editor\Core\*.cs" />
|
||||
<Compile Include="..\..\..\Assets\Modules\ShrinkShared.CodeGen\Editor\UnityShrinkCodeGenAdapter.cs" />
|
||||
<Compile Include="..\..\..\Assets\Modules\ShrinkShared.CodeGen\Editor\ShrinkRegistryILPostProcessor.cs" />
|
||||
<Compile Include="..\..\..\Assets\Modules\ShrinkEventBus\CodeGen\Editor\EventBusILPostProcessor.cs" />
|
||||
<Reference Include="Unity.CompilationPipeline.Common">
|
||||
<HintPath>D:\UnityEditor\2022.3.62f3\Editor\Data\Managed\Unity.CompilationPipeline.Common.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Cecil">
|
||||
<HintPath>..\..\..\Library\PackageCache\com.unity.nuget.mono-cecil@1.11.4\Mono.Cecil.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user