Check the CultMath release gate against the type-definition table
scripts/check-cultmath-types.cs reads the assembly with System.Reflection.Metadata and reports which named types are not public top-level CultMath types. The old NUL-delimited string search passed an appended string or a member named like the type, and failed a real type whose name is tail-shared in the string heap. Prerelease and range versions now get a clear message instead of a raw System.Version error. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
26a4f4240b
commit
fee55e89c5
2 changed files with 44 additions and 8 deletions
|
|
@ -58,15 +58,20 @@ if ($LASTEXITCODE -ne 0) {
|
|||
# dependency, so a cultlib release must not run ahead of the CultMath package it names.
|
||||
# (1) The declared dependency version must not exceed the CultMath package's own version.
|
||||
# (2) The CultMath.dll that package tracks must define every type CultMathResolver formats.
|
||||
# Type names come from the resolver source (its Shape<T> entries) and are looked up as
|
||||
# NUL-delimited names in the assembly's metadata string heap, which is a name check, not a
|
||||
# signature check; Windows PowerShell cannot load a netstandard2.1 assembly to reflect on it.
|
||||
# The names come from the resolver source (its Shape<T> entries); scripts\check-cultmath-types.cs
|
||||
# looks them up in the assembly's type-definition table, which Windows PowerShell cannot load
|
||||
# the assembly to do. It checks type names, not signatures.
|
||||
$cultMathPackageRoot = Join-Path $repoRoot "packages\cultmath\unity\org.gamecult.cultmath"
|
||||
$cultMathDeclared = (Get-Content -LiteralPath (Join-Path $templateRoot "package.json") -Raw | ConvertFrom-Json).dependencies.'org.gamecult.cultmath'
|
||||
$cultMathAvailable = (Get-Content -LiteralPath (Join-Path $cultMathPackageRoot "package.json") -Raw | ConvertFrom-Json).version
|
||||
if ([string]::IsNullOrWhiteSpace($cultMathDeclared)) {
|
||||
throw "package.json must declare org.gamecult.cultmath, which supplies CultMath.dll."
|
||||
}
|
||||
foreach ($declared in @(@("org.gamecult.cultlib's org.gamecult.cultmath dependency", $cultMathDeclared), @("the CultMath package version", $cultMathAvailable))) {
|
||||
if ($declared[1] -notmatch '^\d+\.\d+\.\d+$') {
|
||||
throw "$($declared[0]) is '$($declared[1])'. The release gate compares exact release versions (major.minor.patch); prerelease and range versions are not supported."
|
||||
}
|
||||
}
|
||||
if ([version]$cultMathDeclared -gt [version]$cultMathAvailable) {
|
||||
throw "Release order: org.gamecult.cultlib depends on org.gamecult.cultmath $cultMathDeclared, but the CultMath package is at $cultMathAvailable. Release CultMath first."
|
||||
}
|
||||
|
|
@ -75,11 +80,12 @@ $resolverTypes = @([regex]::Matches($resolverSource, '\bShape<(?!T>)(\w+)>\(') |
|
|||
if ($resolverTypes.Count -eq 0) {
|
||||
throw "Found no CultMath types in CultMathResolver.cs; the release gate cannot check the CultMath package."
|
||||
}
|
||||
$cultMathBytes = [IO.File]::ReadAllBytes((Join-Path $cultMathPackageRoot "Runtime\Plugins\CultMath.dll"))
|
||||
$cultMathText = [Text.Encoding]::GetEncoding(28591).GetString($cultMathBytes)
|
||||
$missingTypes = @($resolverTypes | Where-Object { -not $cultMathText.Contains("`0$_`0") })
|
||||
if ($missingTypes.Count -gt 0) {
|
||||
throw "The CultMath.dll in org.gamecult.cultmath $cultMathAvailable lacks types CultMathResolver formats: $($missingTypes -join ', '). Release CultMath first."
|
||||
$missingTypes = & dotnet run (Join-Path $PSScriptRoot "check-cultmath-types.cs") -- (Join-Path $cultMathPackageRoot "Runtime\Plugins\CultMath.dll") @resolverTypes
|
||||
if ($LASTEXITCODE -eq 1) {
|
||||
throw "The CultMath.dll in org.gamecult.cultmath $cultMathAvailable lacks types CultMathResolver formats: $missingTypes. Release CultMath first."
|
||||
}
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "scripts\check-cultmath-types.cs failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
# The tracked DLLs and pdbs are committed beside their source, so none may name a commit or a worktree:
|
||||
# Source Link writes the commit SHA into the pdb, the informational version carries it too, and each DLL
|
||||
|
|
|
|||
30
scripts/check-cultmath-types.cs
Normal file
30
scripts/check-cultmath-types.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Release gate helper for build-unity-package.ps1: reads an assembly's type-definition table and
|
||||
// reports which of the named CultMath types it does not define as a public top-level type.
|
||||
// Usage: dotnet run scripts/check-cultmath-types.cs -- <assembly.dll> <TypeName>...
|
||||
// Exit 0 when every type is defined, 1 when any is missing, 2 on bad usage.
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
if (args.Length < 2)
|
||||
{
|
||||
Console.Error.WriteLine("usage: check-cultmath-types <assembly.dll> <TypeName>...");
|
||||
return 2;
|
||||
}
|
||||
|
||||
using var stream = File.OpenRead(args[0]);
|
||||
using var pe = new PEReader(stream);
|
||||
var metadata = pe.GetMetadataReader();
|
||||
var defined = new HashSet<string>();
|
||||
foreach (var handle in metadata.TypeDefinitions)
|
||||
{
|
||||
var type = metadata.GetTypeDefinition(handle);
|
||||
if (!type.GetDeclaringType().IsNil) continue;
|
||||
if ((type.Attributes & TypeAttributes.VisibilityMask) != TypeAttributes.Public) continue;
|
||||
if (metadata.GetString(type.Namespace) == "CultMath") defined.Add(metadata.GetString(type.Name));
|
||||
}
|
||||
|
||||
var missing = args.Skip(1).Where(name => !defined.Contains(name)).ToArray();
|
||||
if (missing.Length == 0) return 0;
|
||||
Console.WriteLine(string.Join(", ", missing));
|
||||
return 1;
|
||||
Loading…
Reference in a new issue