novolis-msbuild / design.md
Design
MSBuild props and targets
dotnetmsbuildnovolis
Problem
Cross-repo libraries need one committed declaration that works for:
- Local multi-repo iteration — compile against sibling source when the project is checked out
- CI / single-repo consumers — restore from NuGet when the sibling project is absent
Novolis historically keeps committed PackageReference only and optionally rewrites to ProjectReference in ProjectReference mode. LibraryReference inverts that: the committed item is the dependency; expansion chooses project vs package at evaluation time (required for NuGet restore; a Target-added ProjectReference fails with NETSDK1004).
Resolution
LibraryReference (PackageId, optional Version, optional ProjectPath)
→ stamp ProjectPath from LibraryProjectMap when missing
→ if ProjectPath exists and is not self → ProjectReference (+ forwarded metadata)
→ else → PackageReference (Version or LibraryReferenceDefaultVersion)
CPM: also PackageVersion when no central row exists yetNo filesystem crawl. Paths come from explicit metadata or LibraryProjectMap (same reliability model as the generated NovolisPackageProject map).
Packaging
Props/targets-only NuGet package (IncludeBuildOutput=false, DevelopmentDependency=true). Auto-imported from build/ and buildTransitive/ when referenced.
Non-goals (this repo)
- Migrating every existing Novolis
PackageReferencetoLibraryReference(governance already imports these targets for any project that declares the item) - Inventing transitive ProjectReferences for NuGet dependency graphs