#!/usr/bin/env python3 """Compile diagnostic adapters against the immutable original publication; never build product code.""" import argparse import hashlib import json from pathlib import Path import subprocess import xml.etree.ElementTree as ET parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--host', type=Path, required=True) parser.add_argument('--client', type=Path, required=True) parser.add_argument('--assertions', type=Path, required=True, help='Directory containing Shouldly.dll; only assertion dependencies are selected') parser.add_argument('--output', type=Path, required=True) parser.add_argument('--inventory', action='store_true') args = parser.parse_args() root = args.output.resolve(); root.mkdir(parents=True, exist_ok=False) source = Path(__file__).resolve().parent references = {} for directory in [args.host, args.client]: for dll in sorted(directory.resolve(strict=True).glob('*.dll')): references.setdefault(dll.name, dll) for name in ['Shouldly.dll', 'DiffEngine.dll', 'EmptyFiles.Xml.dll']: path = args.assertions.resolve(strict=True) / name if path.exists(): references.setdefault(name, path) project = ET.Element('Project', Sdk='Microsoft.NET.Sdk') properties = ET.SubElement(project, 'PropertyGroup') for key,value in {'OutputType':'Exe','TargetFramework':'net10.0','Nullable':'enable','ImplicitUsings':'enable', 'TreatWarningsAsErrors':'true','EnableDefaultCompileItems':'false'}.items(): ET.SubElement(properties,key).text=value items = ET.SubElement(project,'ItemGroup') ET.SubElement(items,'FrameworkReference',Include='Microsoft.AspNetCore.App') for name,path in references.items(): reference=ET.SubElement(items,'Reference',Include=path.stem); ET.SubElement(reference,'HintPath').text=str(path) files = ['Inventory.cs'] if args.inventory else ['Program.cs','BaselineRig.cs','BaselineMetrics.cs','CanonicalOperations.cs','SemanticRetention.cs'] for name in files: ET.SubElement(items,'Compile',Include=str(source/name)) path=root/'adapter.csproj'; ET.indent(project); ET.ElementTree(project).write(path,encoding='unicode') manifest={'diagnosticOnly':True,'productRebuilt':False,'references':{name:hashlib.sha256(p.read_bytes()).hexdigest() for name,p in references.items()}, 'sources':{name:hashlib.sha256((source/name).read_bytes()).hexdigest() for name in files}} (root/'provenance.json').write_text(json.dumps(manifest,indent=2)+'\n') with (root/'build.log').open('w') as log: result=subprocess.run(['dotnet','build',str(path),'-c','Release','-m:2'],stdout=log,stderr=subprocess.STDOUT) raise SystemExit(result.returncode)