44# against the full (direct + transitive) dependency tree of the host app.
55#
66# Uses a temporary project with the same PackageReferences as Desktop.csproj and
7- # Shared.props, then runs `dotnet list package --include-transitive` to resolve
8- # the complete dependency graph.
7+ # ModuleBase.csproj (with versions resolved from Directory.Packages.props), then
8+ # runs `dotnet list package --include-transitive` to resolve the complete
9+ # dependency graph.
910#
1011# Usage:
1112# ./scripts/sync-host-deps.sh # Check only (CI mode, exits 1 if out of sync)
@@ -22,20 +23,24 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2223REPO_ROOT=" $( cd " $SCRIPT_DIR /.." && pwd) "
2324
2425DESKTOP_CSPROJ=" $REPO_ROOT /Desktop/Desktop.csproj"
25- SHARED_PROPS=" $REPO_ROOT /Shared.props"
26+ BUILD_PROPS=" $REPO_ROOT /Directory.Build.props"
27+ PACKAGES_PROPS=" $REPO_ROOT /Directory.Packages.props"
2628TARGETS_FILE=" $REPO_ROOT /ModuleBase/build/OpenShock.Desktop.ModuleBase.targets"
2729MODULEBASE_CSPROJ=" $REPO_ROOT /ModuleBase/ModuleBase.csproj"
2830
29- for f in " $DESKTOP_CSPROJ " " $SHARED_PROPS " " $TARGETS_FILE " " $MODULEBASE_CSPROJ " ; do
31+ for f in " $DESKTOP_CSPROJ " " $BUILD_PROPS " " $PACKAGES_PROPS " " $TARGETS_FILE " " $MODULEBASE_CSPROJ " ; do
3032 if [[ ! -f " $f " ]]; then
3133 echo " ERROR: File not found: $f " >&2
3234 exit 1
3335 fi
3436done
3537
3638# Packages that don't produce runtime assemblies (build tools, analyzers, etc.)
39+ # or that are managed manually in the targets file (e.g. ModuleBase, which is
40+ # always host-provided regardless of version).
3741SKIP_PACKAGES=(
3842 " AspNetCore.SassCompiler"
43+ " OpenShock.Desktop.ModuleBase"
3944)
4045
4146is_skipped () {
@@ -50,11 +55,19 @@ is_skipped() {
5055 return 1
5156}
5257
53- # Extract PackageReference Include="name" Version="ver" and Update="name" Version="ver"
54- extract_package_refs () {
58+ # Build the central version map from Directory.Packages.props
59+ declare -A PACKAGE_VERSIONS
60+ while IFS=' =' read -r name version; do
61+ [[ -z " $name " ]] && continue
62+ PACKAGE_VERSIONS[" $name " ]=" $version "
63+ done < <( grep -Eo ' PackageVersion\s+Include="[^"]+"\s+Version="[^"]+"' " $PACKAGES_PROPS " 2> /dev/null | \
64+ sed -E ' s/PackageVersion\s+Include="([^"]+)"\s+Version="([^"]+)"/\1=\2/' || true)
65+
66+ # Extract PackageReference Include="name" (no Version, since CPM) from a project file
67+ extract_package_ref_names () {
5568 local file=" $1 "
56- grep -Eo ' PackageReference\s+(Include|Update)="[^"]+"\s+Version="[^"]+" ' " $file " 2> /dev/null | \
57- sed -E ' s/PackageReference\s+(Include|Update)="([^"]+)"\s+Version="([^"]+)" /\2=\3 /' || true
69+ grep -Eo ' PackageReference\s+(Include|Update)="[^"]+"' " $file " 2> /dev/null | \
70+ sed -E ' s/PackageReference\s+(Include|Update)="([^"]+)"/\2/' || true
5871}
5972
6073# Extract OpenShockHostAssembly Include="name" Version="ver"
@@ -63,28 +76,26 @@ extract_host_assemblies() {
6376 sed -E ' s/OpenShockHostAssembly\s+Include="([^"]+)"\s+Version="([^"]+)"/\1=\2/' || true
6477}
6578
66- # Get version from Shared.props
67- get_shared_version () {
68- grep -Eo ' <Version>[^<]+' " $SHARED_PROPS " | head -1 | sed ' s/<Version>//'
69- }
70-
71- # Collect direct PackageReferences from Desktop.csproj and Shared.props
79+ # Collect direct PackageReferences from Desktop.csproj and ModuleBase.csproj,
80+ # resolving versions from Directory.Packages.props.
7281declare -A DIRECT_REFS
7382
74- while IFS=' =' read -r name version; do
75- [[ -z " $name " ]] && continue
76- DIRECT_REFS[" $name " ]=" $version "
77- done < <( extract_package_refs " $SHARED_PROPS " )
78-
79- while IFS=' =' read -r name version; do
80- [[ -z " $name " ]] && continue
81- DIRECT_REFS[" $name " ]=" $version "
82- done < <( extract_package_refs " $DESKTOP_CSPROJ " )
83+ collect_refs () {
84+ local file=" $1 "
85+ local name
86+ while read -r name; do
87+ [[ -z " $name " ]] && continue
88+ local version=" ${PACKAGE_VERSIONS[$name]:- } "
89+ if [[ -z " $version " ]]; then
90+ echo " WARNING: No PackageVersion for '$name ' in Directory.Packages.props" >&2
91+ continue
92+ fi
93+ DIRECT_REFS[" $name " ]=" $version "
94+ done < <( extract_package_ref_names " $file " )
95+ }
8396
84- while IFS=' =' read -r name version; do
85- [[ -z " $name " ]] && continue
86- DIRECT_REFS[" $name " ]=" $version "
87- done < <( extract_package_refs " $MODULEBASE_CSPROJ " )
97+ collect_refs " $DESKTOP_CSPROJ "
98+ collect_refs " $MODULEBASE_CSPROJ "
8899
89100# Create a temporary project to resolve transitive dependencies.
90101# We can't run `dotnet list` on Desktop.csproj directly because it may
@@ -109,6 +120,7 @@ cat > "$TMPDIR/HostDeps.csproj" <<CSPROJ
109120 <PropertyGroup>
110121 <TargetFramework>net10.0</TargetFramework>
111122 <OutputType>Library</OutputType>
123+ <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
112124 </PropertyGroup>
113125 <ItemGroup>
114126$PKG_REFS </ItemGroup>
@@ -130,10 +142,6 @@ LIST_OUTPUT=$(dotnet list "$TMPDIR/HostDeps.csproj" package --include-transitive
130142# Parse the JSON output to build the full dependency map
131143declare -A HOST_DEPS
132144
133- # Add ModuleBase itself
134- MODULEBASE_VERSION=" $( get_shared_version) "
135- HOST_DEPS[" OpenShock.Desktop.ModuleBase" ]=" $MODULEBASE_VERSION "
136-
137145# Add platform-specific packages we skipped (they're still host-provided)
138146for name in " ${! DIRECT_REFS[@]} " ; do
139147 case " $name " in
0 commit comments