From 1eb3176326e6816d6011f7ab6ebda535a0dafbf2 Mon Sep 17 00:00:00 2001 From: Forgind Date: Tue, 14 Dec 2021 18:36:32 -0800 Subject: [PATCH 01/27] Hacky, untested binding redirect validation --- eng/ValidatePackageVersions.sh | 33 +++++++++++++++++++++++++++++ eng/cibuild_bootstrapped_msbuild.sh | 1 + 2 files changed, 34 insertions(+) create mode 100644 eng/ValidatePackageVersions.sh diff --git a/eng/ValidatePackageVersions.sh b/eng/ValidatePackageVersions.sh new file mode 100644 index 00000000000..aad78ccfb87 --- /dev/null +++ b/eng/ValidatePackageVersions.sh @@ -0,0 +1,33 @@ +#! /bin/bash + +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$ScriptRoot/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + +RepoRoot="$ScriptRoot/.." +Packages="$RepoRoot/eng/Packages.props" +AppConfig="$RepoRoot/src/MSBuild/app.config" + +NextHasVersion="f" +while IFS='' read -r line; do +if [ $line =~ PackageReference Update=[^\ ]* Version=[^>]*>$ ]; then +PackageName=$line | cut -d'"' -f 2 +PackageVersion=$line | cut -d'"' -f 4 +while IFS='' read -r line2; do +if [ NextHasVersion = "t" ]; then +NextHasVersion="f" +AppVersion=$line2 | cut -d'"' -f 4 +# Check match between PackageVersion and AppVersion +fi +if [ $line2 =~ assemblyIdentity ]; then +if [ $PackageName = $line2 | cut -d'"' -f 2 ]; then +NextHasVersion="t" +fi +fi +done < $AppConfig +fi +done < $Packages diff --git a/eng/cibuild_bootstrapped_msbuild.sh b/eng/cibuild_bootstrapped_msbuild.sh index e5425507f47..447f5301b25 100755 --- a/eng/cibuild_bootstrapped_msbuild.sh +++ b/eng/cibuild_bootstrapped_msbuild.sh @@ -99,3 +99,4 @@ export DOTNET_HOST_PATH="$_InitializeDotNetCli/dotnet" # - Do run tests # - Don't try to create a bootstrap deployment . "$ScriptRoot/common/build.sh" --restore --build --test --ci --nodereuse false --configuration $configuration /p:CreateBootstrap=false $properties $extra_properties +. "$ScriptRoot/ValidatePackageVersion.sh" From ef865399469d25d735c4393a75aeaa72e6f06ab0 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 11:09:16 -0800 Subject: [PATCH 02/27] Revert "Hacky, untested binding redirect validation" This reverts commit 1eb3176326e6816d6011f7ab6ebda535a0dafbf2. --- eng/ValidatePackageVersions.sh | 33 ----------------------------- eng/cibuild_bootstrapped_msbuild.sh | 1 - 2 files changed, 34 deletions(-) delete mode 100644 eng/ValidatePackageVersions.sh diff --git a/eng/ValidatePackageVersions.sh b/eng/ValidatePackageVersions.sh deleted file mode 100644 index aad78ccfb87..00000000000 --- a/eng/ValidatePackageVersions.sh +++ /dev/null @@ -1,33 +0,0 @@ -#! /bin/bash - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$ScriptRoot/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -RepoRoot="$ScriptRoot/.." -Packages="$RepoRoot/eng/Packages.props" -AppConfig="$RepoRoot/src/MSBuild/app.config" - -NextHasVersion="f" -while IFS='' read -r line; do -if [ $line =~ PackageReference Update=[^\ ]* Version=[^>]*>$ ]; then -PackageName=$line | cut -d'"' -f 2 -PackageVersion=$line | cut -d'"' -f 4 -while IFS='' read -r line2; do -if [ NextHasVersion = "t" ]; then -NextHasVersion="f" -AppVersion=$line2 | cut -d'"' -f 4 -# Check match between PackageVersion and AppVersion -fi -if [ $line2 =~ assemblyIdentity ]; then -if [ $PackageName = $line2 | cut -d'"' -f 2 ]; then -NextHasVersion="t" -fi -fi -done < $AppConfig -fi -done < $Packages diff --git a/eng/cibuild_bootstrapped_msbuild.sh b/eng/cibuild_bootstrapped_msbuild.sh index 447f5301b25..e5425507f47 100755 --- a/eng/cibuild_bootstrapped_msbuild.sh +++ b/eng/cibuild_bootstrapped_msbuild.sh @@ -99,4 +99,3 @@ export DOTNET_HOST_PATH="$_InitializeDotNetCli/dotnet" # - Do run tests # - Don't try to create a bootstrap deployment . "$ScriptRoot/common/build.sh" --restore --build --test --ci --nodereuse false --configuration $configuration /p:CreateBootstrap=false $properties $extra_properties -. "$ScriptRoot/ValidatePackageVersion.sh" From 11d1b98e05822c184e86ab49046500ab576682e5 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 12:29:38 -0800 Subject: [PATCH 03/27] Use task to validate packages --- src/MSBuild/MSBuild.csproj | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 99a71a59e11..d162f3ca91e 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -330,4 +330,87 @@ + + + + + + + + + + + + + + + + + + + From ac034574af6557266203f0f9213f14cbf8e4cb20 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 12:49:37 -0800 Subject: [PATCH 04/27] Add Source="Foo.cs" --- src/MSBuild/MSBuild.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index d162f3ca91e..498de38d7c7 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -340,8 +340,8 @@ - - + Date: Wed, 15 Dec 2021 13:04:53 -0800 Subject: [PATCH 05/27] Move code into separate task --- src/MSBuild/MSBuild.csproj | 70 +------------------ ...alidateMSBuildPackageDependencyVersions.cs | 62 ++++++++++++++++ 2 files changed, 65 insertions(+), 67 deletions(-) create mode 100644 src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 498de38d7c7..91f09eeeaf1 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -340,77 +340,13 @@ - - + - + - diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs new file mode 100644 index 00000000000..170a7be1b3b --- /dev/null +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -0,0 +1,62 @@ +XmlDocument doc = new XmlDocument(); +doc.Load(AppConfig); +foreach (var topLevelElement in doc.ChildNodes) +{ + if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var configurationElement in topLevelXmlElement.ChildNodes) + { + if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var runtimeElement in configurationXmlElement.ChildNodes) + { + if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var assemblyBindingElement in runtimeXmlElement.ChildNodes) + { + if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", System.StringComparison.OrdinalIgnoreCase)) + { + string name = string.Empty; + string version = string.Empty; + foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) + { + if (dependentAssembly is XmlElement dependentAssemblyXmlElement) + { + if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var assemblyIdentityAttribute in dependentAssemblyXmlElement.Attributes) + { + if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", System.StringComparison.OrdinalIgnoreCase)) + { + name = assemblyIdentityAttributeXmlElement.Value; + } + } + } + else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) + { + if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + { + version = bindingRedirectAttributeXmlElement.Value; + } + } + } + } + } + if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) + { + string path = Path.Combine(AssemblyPath, name + ".dll"); + if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) + { + Log.LogError("Binding redirect redirects to a different version than MSBuild ships."); + } + } + } + } + } + } + } + } + } +} From 08bd7b50342b46e809dc27eb8cd5cbaf41952922 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 14:18:45 -0800 Subject: [PATCH 06/27] Make into full class --- src/MSBuild/MSBuild.csproj | 3 +- ...alidateMSBuildPackageDependencyVersions.cs | 86 ++++++++++++------- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 91f09eeeaf1..9541239a554 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -336,11 +336,12 @@ + - + diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 170a7be1b3b..b1b7b88a53c 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,62 +1,84 @@ -XmlDocument doc = new XmlDocument(); -doc.Load(AppConfig); -foreach (var topLevelElement in doc.ChildNodes) +using Microsoft.Build.Utilities; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Remoting.Messaging; +using System.Threading.Tasks; +using System.Xml; +namespace MSBuild { - if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", System.StringComparison.OrdinalIgnoreCase)) + public class ValidateMSBuildPackageDependencyVersions : Task { - foreach (var configurationElement in topLevelXmlElement.ChildNodes) + [RequiredAttribute] + public string AppConfig { get; set; } + [RequiredAttribute] + public string AssemblyPath { get; set; } + + public override bool Execute() { - if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", System.StringComparison.OrdinalIgnoreCase)) + XmlDocument doc = new XmlDocument(); + doc.Load(AppConfig); + foreach (var topLevelElement in doc.ChildNodes) { - foreach (var runtimeElement in configurationXmlElement.ChildNodes) + if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", System.StringComparison.OrdinalIgnoreCase)) { - if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", System.StringComparison.OrdinalIgnoreCase)) + foreach (var configurationElement in topLevelXmlElement.ChildNodes) { - foreach (var assemblyBindingElement in runtimeXmlElement.ChildNodes) + if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", System.StringComparison.OrdinalIgnoreCase)) { - if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", System.StringComparison.OrdinalIgnoreCase)) + foreach (var runtimeElement in configurationXmlElement.ChildNodes) { - string name = string.Empty; - string version = string.Empty; - foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) + if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", System.StringComparison.OrdinalIgnoreCase)) { - if (dependentAssembly is XmlElement dependentAssemblyXmlElement) + foreach (var assemblyBindingElement in runtimeXmlElement.ChildNodes) { - if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", System.StringComparison.OrdinalIgnoreCase)) + if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", System.StringComparison.OrdinalIgnoreCase)) { - foreach (var assemblyIdentityAttribute in dependentAssemblyXmlElement.Attributes) + string name = string.Empty; + string version = string.Empty; + foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) { - if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", System.StringComparison.OrdinalIgnoreCase)) + if (dependentAssembly is XmlElement dependentAssemblyXmlElement) { - name = assemblyIdentityAttributeXmlElement.Value; + if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var assemblyIdentityAttribute in dependentAssemblyXmlElement.Attributes) + { + if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", System.StringComparison.OrdinalIgnoreCase)) + { + name = assemblyIdentityAttributeXmlElement.Value; + } + } + } + else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", System.StringComparison.OrdinalIgnoreCase)) + { + foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) + { + if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + { + version = bindingRedirectAttributeXmlElement.Value; + } + } + } } } - } - else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", System.StringComparison.OrdinalIgnoreCase)) - { - foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) + if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) { - if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + string path = Path.Combine(AssemblyPath, name + ".dll"); + if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) { - version = bindingRedirectAttributeXmlElement.Value; + Log.LogError("Binding redirect redirects to a different version than MSBuild ships."); } } } } } - if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) - { - string path = Path.Combine(AssemblyPath, name + ".dll"); - if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) - { - Log.LogError("Binding redirect redirects to a different version than MSBuild ships."); - } - } } } } } } + return !Log.HasLoggedErrors; } } } From 39731bc3ba729eb7e31518b60d3d46de33622440 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 14:39:27 -0800 Subject: [PATCH 07/27] Fix up task --- src/MSBuild/MSBuild.csproj | 12 +----------- .../ValidateMSBuildPackageDependencyVersions.cs | 10 ++++------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 9541239a554..7e450ebf59e 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -331,18 +331,8 @@ - - - - - - - - - - - + diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index b1b7b88a53c..f05986f7532 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,17 +1,15 @@ +using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using System.IO; using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.Remoting.Messaging; -using System.Threading.Tasks; using System.Xml; namespace MSBuild { public class ValidateMSBuildPackageDependencyVersions : Task { - [RequiredAttribute] + [Required] public string AppConfig { get; set; } - [RequiredAttribute] + [Required] public string AssemblyPath { get; set; } public override bool Execute() @@ -67,7 +65,7 @@ public override bool Execute() string path = Path.Combine(AssemblyPath, name + ".dll"); if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) { - Log.LogError("Binding redirect redirects to a different version than MSBuild ships."); + Log.LogError($"Binding redirect for '{name} redirects to a different version ({version}) than MSBuild ships."); } } } From 29e7068a5574277d464d7c29ce55663af4a7b6cd Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 14:39:38 -0800 Subject: [PATCH 08/27] =?UTF-8?q?Fix=20app.config=20=F0=9F=99=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MSBuild/app.amd64.config | 2 +- src/MSBuild/app.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MSBuild/app.amd64.config b/src/MSBuild/app.amd64.config index c44189ed7f9..517c74df63f 100644 --- a/src/MSBuild/app.amd64.config +++ b/src/MSBuild/app.amd64.config @@ -54,7 +54,7 @@ - + diff --git a/src/MSBuild/app.config b/src/MSBuild/app.config index 96ee3eb038b..f22bacc449e 100644 --- a/src/MSBuild/app.config +++ b/src/MSBuild/app.config @@ -45,7 +45,7 @@ - + From 45d54d4fd8fb8275705df373f852afb1a5f05c55 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 15:15:39 -0800 Subject: [PATCH 09/27] Opt System.ValueTuple out --- .../ValidateMSBuildPackageDependencyVersions.cs | 12 +++++++++--- src/MSBuild/app.amd64.config | 2 +- src/MSBuild/app.config | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index f05986f7532..823592db259 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,5 +1,6 @@ using Microsoft.Build.Framework; using Microsoft.Build.Utilities; +using System; using System.IO; using System.Reflection; using System.Xml; @@ -34,6 +35,7 @@ public override bool Execute() { string name = string.Empty; string version = string.Empty; + bool check = true; foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) { if (dependentAssembly is XmlElement dependentAssemblyXmlElement) @@ -52,15 +54,19 @@ public override bool Execute() { foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) { - if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + if (bindingRedirectAttribute is XmlAttribute bindingRedirectVersion && bindingRedirectVersion.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) { - version = bindingRedirectAttributeXmlElement.Value; + version = bindingRedirectVersion.Value; + } + else if (bindingRedirectAttribute is XmlAttribute notToCheck && notToCheck.Name.Equals("notToBeChecked", System.StringComparison.OrdinalIgnoreCase)) + { + check = !notToCheck.Value.Equals("true", System.StringComparison.OrdinalIgnoreCase); } } } } } - if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) + if (check && !string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) { string path = Path.Combine(AssemblyPath, name + ".dll"); if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) diff --git a/src/MSBuild/app.amd64.config b/src/MSBuild/app.amd64.config index 517c74df63f..95a07e4c238 100644 --- a/src/MSBuild/app.amd64.config +++ b/src/MSBuild/app.amd64.config @@ -111,7 +111,7 @@ - + diff --git a/src/MSBuild/app.config b/src/MSBuild/app.config index f22bacc449e..83f40b73d94 100644 --- a/src/MSBuild/app.config +++ b/src/MSBuild/app.config @@ -101,7 +101,7 @@ - + From d0b8b5b782b8f8f7aa6bc79253ebbe8491fc8b49 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 15:19:44 -0800 Subject: [PATCH 10/27] Revert "Opt System.ValueTuple out" This reverts commit 45d54d4fd8fb8275705df373f852afb1a5f05c55. --- .../ValidateMSBuildPackageDependencyVersions.cs | 12 +++--------- src/MSBuild/app.amd64.config | 2 +- src/MSBuild/app.config | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 823592db259..f05986f7532 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,6 +1,5 @@ using Microsoft.Build.Framework; using Microsoft.Build.Utilities; -using System; using System.IO; using System.Reflection; using System.Xml; @@ -35,7 +34,6 @@ public override bool Execute() { string name = string.Empty; string version = string.Empty; - bool check = true; foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) { if (dependentAssembly is XmlElement dependentAssemblyXmlElement) @@ -54,19 +52,15 @@ public override bool Execute() { foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) { - if (bindingRedirectAttribute is XmlAttribute bindingRedirectVersion && bindingRedirectVersion.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) { - version = bindingRedirectVersion.Value; - } - else if (bindingRedirectAttribute is XmlAttribute notToCheck && notToCheck.Name.Equals("notToBeChecked", System.StringComparison.OrdinalIgnoreCase)) - { - check = !notToCheck.Value.Equals("true", System.StringComparison.OrdinalIgnoreCase); + version = bindingRedirectAttributeXmlElement.Value; } } } } } - if (check && !string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) + if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) { string path = Path.Combine(AssemblyPath, name + ".dll"); if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) diff --git a/src/MSBuild/app.amd64.config b/src/MSBuild/app.amd64.config index 95a07e4c238..517c74df63f 100644 --- a/src/MSBuild/app.amd64.config +++ b/src/MSBuild/app.amd64.config @@ -111,7 +111,7 @@ - + diff --git a/src/MSBuild/app.config b/src/MSBuild/app.config index 83f40b73d94..f22bacc449e 100644 --- a/src/MSBuild/app.config +++ b/src/MSBuild/app.config @@ -101,7 +101,7 @@ - + From a389c1aa7b11015bb9eab9cff798ac0b18d372df Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 15:22:38 -0800 Subject: [PATCH 11/27] Specifically opt out S.ValueTuple --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index f05986f7532..7cef9303fa2 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -63,9 +63,13 @@ public override bool Execute() if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) { string path = Path.Combine(AssemblyPath, name + ".dll"); - if (File.Exists(path) && !version.Equals(Assembly.LoadFile(path).GetName().Version.ToString())) + string assemblyVersion = Assembly.LoadFile(path).GetName().Version.ToString(); + if (File.Exists(path) && !version.Equals(assemblyVersion)) { - Log.LogError($"Binding redirect for '{name} redirects to a different version ({version}) than MSBuild ships."); + if (!(name.Equals("System.ValueTuple", System.StringComparer.OrdinalIgnoreCase) && version.Equals("4.0.0.0") && assemblyVersion.Equals("4.0.3.0"))) + { + Log.LogError($"Binding redirect for '{name} redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); + } } } } From 747aa8773334fdf63005e6c5503560164649e9fa Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 15:23:53 -0800 Subject: [PATCH 12/27] Missed a quote --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 7cef9303fa2..6a9f2e9db83 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -68,7 +68,7 @@ public override bool Execute() { if (!(name.Equals("System.ValueTuple", System.StringComparer.OrdinalIgnoreCase) && version.Equals("4.0.0.0") && assemblyVersion.Equals("4.0.3.0"))) { - Log.LogError($"Binding redirect for '{name} redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); + Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); } } } From 354316d94df50760d5c2e05de94da00bc1180a4b Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 16:00:56 -0800 Subject: [PATCH 13/27] Use String.Equals? --- ...alidateMSBuildPackageDependencyVersions.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 6a9f2e9db83..895117f933b 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,5 +1,6 @@ using Microsoft.Build.Framework; using Microsoft.Build.Utilities; +using System; using System.IO; using System.Reflection; using System.Xml; @@ -18,19 +19,19 @@ public override bool Execute() doc.Load(AppConfig); foreach (var topLevelElement in doc.ChildNodes) { - if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", System.StringComparison.OrdinalIgnoreCase)) + if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", StringComparison.OrdinalIgnoreCase)) { foreach (var configurationElement in topLevelXmlElement.ChildNodes) { - if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", System.StringComparison.OrdinalIgnoreCase)) + if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", StringComparison.OrdinalIgnoreCase)) { foreach (var runtimeElement in configurationXmlElement.ChildNodes) { - if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", System.StringComparison.OrdinalIgnoreCase)) + if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", StringComparison.OrdinalIgnoreCase)) { foreach (var assemblyBindingElement in runtimeXmlElement.ChildNodes) { - if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", System.StringComparison.OrdinalIgnoreCase)) + if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", StringComparison.OrdinalIgnoreCase)) { string name = string.Empty; string version = string.Empty; @@ -38,21 +39,21 @@ public override bool Execute() { if (dependentAssembly is XmlElement dependentAssemblyXmlElement) { - if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", System.StringComparison.OrdinalIgnoreCase)) + if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", StringComparison.OrdinalIgnoreCase)) { foreach (var assemblyIdentityAttribute in dependentAssemblyXmlElement.Attributes) { - if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", System.StringComparison.OrdinalIgnoreCase)) + if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", StringComparison.OrdinalIgnoreCase)) { name = assemblyIdentityAttributeXmlElement.Value; } } } - else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", System.StringComparison.OrdinalIgnoreCase)) + else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", StringComparison.OrdinalIgnoreCase)) { foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) { - if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", System.StringComparison.OrdinalIgnoreCase)) + if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", StringComparison.OrdinalIgnoreCase)) { version = bindingRedirectAttributeXmlElement.Value; } @@ -66,7 +67,7 @@ public override bool Execute() string assemblyVersion = Assembly.LoadFile(path).GetName().Version.ToString(); if (File.Exists(path) && !version.Equals(assemblyVersion)) { - if (!(name.Equals("System.ValueTuple", System.StringComparer.OrdinalIgnoreCase) && version.Equals("4.0.0.0") && assemblyVersion.Equals("4.0.3.0"))) + if (!(String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0"))) { Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); } From 5f77395e0f2cc9a8a7e4e6f127108350048147f2 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 15 Dec 2021 16:22:56 -0800 Subject: [PATCH 14/27] Move file existence check earlier --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 895117f933b..e5b5fae6837 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -64,8 +64,8 @@ public override bool Execute() if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) { string path = Path.Combine(AssemblyPath, name + ".dll"); - string assemblyVersion = Assembly.LoadFile(path).GetName().Version.ToString(); - if (File.Exists(path) && !version.Equals(assemblyVersion)) + string assemblyVersion = File.Exists(path) ? Assembly.LoadFile(path).GetName().Version.ToString() : version; + if (!version.Equals(assemblyVersion)) { if (!(String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0"))) { From f2c30e59d0b15c6c567fa7715ba2fdb240042dc0 Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 12:24:38 -0800 Subject: [PATCH 15/27] Somewhat cleaner version --- src/MSBuild/MSBuild.csproj | 2 +- ...alidateMSBuildPackageDependencyVersions.cs | 87 ++++++++----------- 2 files changed, 36 insertions(+), 53 deletions(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 7e450ebf59e..1c3842942f3 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -336,7 +336,7 @@ - + diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index e5b5fae6837..255bd2fa53a 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -2,6 +2,7 @@ using Microsoft.Build.Utilities; using System; using System.IO; +using System.Linq; using System.Reflection; using System.Xml; namespace MSBuild @@ -13,68 +14,50 @@ public class ValidateMSBuildPackageDependencyVersions : Task [Required] public string AssemblyPath { get; set; } + private string[] assembliesToIgnore = { "Microsoft.Build.Conversion.Core", "Microsoft.NET.StringTools.net35", "Microsoft.Build.Engine", "Microsoft.Activities.Build", "XamlBuildTask" }; + public override bool Execute() { XmlDocument doc = new XmlDocument(); doc.Load(AppConfig); - foreach (var topLevelElement in doc.ChildNodes) + var runtime = doc.SelectSingleNode("configuration").SelectSingleNode("runtime"); + foreach (var node in runtime.ChildNodes) { - if (topLevelElement is XmlElement topLevelXmlElement && topLevelXmlElement.Name.Equals("configuration", StringComparison.OrdinalIgnoreCase)) + if (node is XmlElement assemblyBinding && assemblyBinding.Name.Equals("assemblyBinding")) { - foreach (var configurationElement in topLevelXmlElement.ChildNodes) + foreach (var assemblyBindingElement in assemblyBinding.ChildNodes) { - if (configurationElement is XmlElement configurationXmlElement && configurationXmlElement.Name.Equals("runtime", StringComparison.OrdinalIgnoreCase)) + string name = string.Empty; + string version = string.Empty; + if (assemblyBindingElement is not XmlElement dependentAssemblyElement) + { + continue; + } + foreach (var dependentAssembly in dependentAssemblyElement.ChildNodes) + { + if (dependentAssembly is XmlElement dependentAssemblyXmlElement) + { + if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", StringComparison.OrdinalIgnoreCase)) + { + name = dependentAssemblyXmlElement.GetAttribute("name"); + } + else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", StringComparison.OrdinalIgnoreCase)) + { + version = dependentAssemblyXmlElement.GetAttribute("newVersion"); + } + } + } + if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version) && !assembliesToIgnore.Contains(name, StringComparer.OrdinalIgnoreCase)) { - foreach (var runtimeElement in configurationXmlElement.ChildNodes) + string path = Path.Combine(AssemblyPath, name + ".dll"); + string assemblyVersion = AssemblyName.GetAssemblyName(path).Version.ToString(); + if (!version.Equals(assemblyVersion)) { - if (runtimeElement is XmlElement runtimeXmlElement && runtimeXmlElement.Name.Equals("assemblyBinding", StringComparison.OrdinalIgnoreCase)) + // It is unusual to want to redirect down, but in this case it's ok: 4.0.3.0 forwards to 4.0.0.0 in the GAC, so this just removes the need to redistribute a file + // and makes that resolution faster. Still verify that the versions are exactly as in this comment, as that may change. + if (!(String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0"))) { - foreach (var assemblyBindingElement in runtimeXmlElement.ChildNodes) - { - if (assemblyBindingElement is XmlElement assemblyBindingXmlElement && assemblyBindingXmlElement.Name.Equals("dependentAssembly", StringComparison.OrdinalIgnoreCase)) - { - string name = string.Empty; - string version = string.Empty; - foreach (var dependentAssembly in assemblyBindingXmlElement.ChildNodes) - { - if (dependentAssembly is XmlElement dependentAssemblyXmlElement) - { - if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", StringComparison.OrdinalIgnoreCase)) - { - foreach (var assemblyIdentityAttribute in dependentAssemblyXmlElement.Attributes) - { - if (assemblyIdentityAttribute is XmlAttribute assemblyIdentityAttributeXmlElement && assemblyIdentityAttributeXmlElement.Name.Equals("name", StringComparison.OrdinalIgnoreCase)) - { - name = assemblyIdentityAttributeXmlElement.Value; - } - } - } - else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", StringComparison.OrdinalIgnoreCase)) - { - foreach (var bindingRedirectAttribute in dependentAssemblyXmlElement.Attributes) - { - if (bindingRedirectAttribute is XmlAttribute bindingRedirectAttributeXmlElement && bindingRedirectAttributeXmlElement.Name.Equals("newVersion", StringComparison.OrdinalIgnoreCase)) - { - version = bindingRedirectAttributeXmlElement.Value; - } - } - } - } - } - if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version)) - { - string path = Path.Combine(AssemblyPath, name + ".dll"); - string assemblyVersion = File.Exists(path) ? Assembly.LoadFile(path).GetName().Version.ToString() : version; - if (!version.Equals(assemblyVersion)) - { - if (!(String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0"))) - { - Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); - } - } - } - } - } + Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); } } } From 60274a289721662e45356ea4cb5c47d4b0116b26 Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 12:27:47 -0800 Subject: [PATCH 16/27] Add explicit check for System.ValueTuple --- .../ValidateMSBuildPackageDependencyVersions.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 255bd2fa53a..85c45c8f4c2 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -21,6 +21,7 @@ public override bool Execute() XmlDocument doc = new XmlDocument(); doc.Load(AppConfig); var runtime = doc.SelectSingleNode("configuration").SelectSingleNode("runtime"); + bool foundSystemValueTuple = false; foreach (var node in runtime.ChildNodes) { if (node is XmlElement assemblyBinding && assemblyBinding.Name.Equals("assemblyBinding")) @@ -55,7 +56,11 @@ public override bool Execute() { // It is unusual to want to redirect down, but in this case it's ok: 4.0.3.0 forwards to 4.0.0.0 in the GAC, so this just removes the need to redistribute a file // and makes that resolution faster. Still verify that the versions are exactly as in this comment, as that may change. - if (!(String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0"))) + if (String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0")) + { + foundSystemValueTuple = true; + } + else { Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); } @@ -64,6 +69,10 @@ public override bool Execute() } } } + if (!foundSystemValueTuple) + { + Log.LogError("Binding redirect for 'System.ValueTuple' missing."); + } return !Log.HasLoggedErrors; } } From c5583f7e2fa60f0e6eb6a5528b2fbab7c63e1080 Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 12:28:45 -0800 Subject: [PATCH 17/27] Add copyright header --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 85c45c8f4c2..385ba351b35 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using System; From 1e4a18ed54de222b03d4e4bd6ed5468c8b2c8f4f Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 14:12:27 -0800 Subject: [PATCH 18/27] Learn to use namespaces in XML --- ...alidateMSBuildPackageDependencyVersions.cs | 53 ++++++------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 385ba351b35..60d8f6a206d 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -23,51 +23,28 @@ public override bool Execute() { XmlDocument doc = new XmlDocument(); doc.Load(AppConfig); - var runtime = doc.SelectSingleNode("configuration").SelectSingleNode("runtime"); + XmlNamespaceManager namespaceManager = new(doc.NameTable); + namespaceManager.AddNamespace("asm", "urn:schemas-microsoft-com:asm.v1"); bool foundSystemValueTuple = false; - foreach (var node in runtime.ChildNodes) + foreach (XmlElement dependentAssemblyElement in doc.DocumentElement.SelectNodes("/configuration/runtime/asm:assemblyBinding/asm:dependentAssembly[asm:assemblyIdentity][asm:bindingRedirect]", namespaceManager)) { - if (node is XmlElement assemblyBinding && assemblyBinding.Name.Equals("assemblyBinding")) + string name = (dependentAssemblyElement.SelectSingleNode("asm:assemblyIdentity", namespaceManager) as XmlElement).GetAttribute("name"); + string version = (dependentAssemblyElement.SelectSingleNode("asm:bindingRedirect", namespaceManager) as XmlElement).GetAttribute("newVersion"); + if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version) && !assembliesToIgnore.Contains(name, StringComparer.OrdinalIgnoreCase)) { - foreach (var assemblyBindingElement in assemblyBinding.ChildNodes) + string path = Path.Combine(AssemblyPath, name + ".dll"); + string assemblyVersion = AssemblyName.GetAssemblyName(path).Version.ToString(); + if (!version.Equals(assemblyVersion)) { - string name = string.Empty; - string version = string.Empty; - if (assemblyBindingElement is not XmlElement dependentAssemblyElement) + // It is unusual to want to redirect down, but in this case it's ok: 4.0.3.0 forwards to 4.0.0.0 in the GAC, so this just removes the need to redistribute a file + // and makes that resolution faster. Still verify that the versions are exactly as in this comment, as that may change. + if (String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0")) { - continue; + foundSystemValueTuple = true; } - foreach (var dependentAssembly in dependentAssemblyElement.ChildNodes) + else { - if (dependentAssembly is XmlElement dependentAssemblyXmlElement) - { - if (dependentAssemblyXmlElement.Name.Equals("assemblyIdentity", StringComparison.OrdinalIgnoreCase)) - { - name = dependentAssemblyXmlElement.GetAttribute("name"); - } - else if (dependentAssemblyXmlElement.Name.Equals("bindingRedirect", StringComparison.OrdinalIgnoreCase)) - { - version = dependentAssemblyXmlElement.GetAttribute("newVersion"); - } - } - } - if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(version) && !assembliesToIgnore.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - string path = Path.Combine(AssemblyPath, name + ".dll"); - string assemblyVersion = AssemblyName.GetAssemblyName(path).Version.ToString(); - if (!version.Equals(assemblyVersion)) - { - // It is unusual to want to redirect down, but in this case it's ok: 4.0.3.0 forwards to 4.0.0.0 in the GAC, so this just removes the need to redistribute a file - // and makes that resolution faster. Still verify that the versions are exactly as in this comment, as that may change. - if (String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0")) - { - foundSystemValueTuple = true; - } - else - { - Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); - } - } + Log.LogError($"Binding redirect for '{name}' redirects to a different version ({version}) than MSBuild ships ({assemblyVersion})."); } } } From b75a202db6dbf30b9184675f664afcbc112ed57b Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 16:51:12 -0800 Subject: [PATCH 19/27] Update src/MSBuild/MSBuild.csproj Co-authored-by: Rainer Sigwald --- src/MSBuild/MSBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 1c3842942f3..7bd20bf6aba 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -336,7 +336,7 @@ - + From cbb140d81ea32ce2be5ab1b7a99bde55eda46e5f Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 16:51:19 -0800 Subject: [PATCH 20/27] Update src/MSBuild/MSBuild.csproj Co-authored-by: Rainer Sigwald --- src/MSBuild/MSBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 7bd20bf6aba..a25d19298d8 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -337,7 +337,7 @@ - + From 70555c74aca2e4b40184de6b179378a74c4be045 Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 17:34:59 -0800 Subject: [PATCH 21/27] Update src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs Co-authored-by: Rainer Sigwald --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 60d8f6a206d..3e36150328d 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -36,8 +36,10 @@ public override bool Execute() string assemblyVersion = AssemblyName.GetAssemblyName(path).Version.ToString(); if (!version.Equals(assemblyVersion)) { - // It is unusual to want to redirect down, but in this case it's ok: 4.0.3.0 forwards to 4.0.0.0 in the GAC, so this just removes the need to redistribute a file - // and makes that resolution faster. Still verify that the versions are exactly as in this comment, as that may change. + // Ensure that the binding redirect is to the GAC version, but + // we still ship the version we explicitly reference to let + // API consumers bind to it at runtime. + // See https://github.com/dotnet/msbuild/issues/6976. if (String.Equals(name, "System.ValueTuple", StringComparison.OrdinalIgnoreCase) && String.Equals(version, "4.0.0.0") && String.Equals(assemblyVersion, "4.0.3.0")) { foundSystemValueTuple = true; From 42a582fef6266169f209c0df7aa4cce298f5f735 Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 16 Dec 2021 17:35:31 -0800 Subject: [PATCH 22/27] Add comment for ignored assemblies --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 60d8f6a206d..34f96b18b97 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -17,6 +17,8 @@ public class ValidateMSBuildPackageDependencyVersions : Task [Required] public string AssemblyPath { get; set; } + // Microsoft.Build.Conversion.Core and Microsoft.Build.Engine are deprecated. We don't ship them, but they're still used in VS for now. We should ensure they're the right version if present. + // Microsoft.NET.StringTools uses API not available in net35, but since we need it to work for TaskHosts as well, there are simpler versions implemented for that. Ensure it's the right version. private string[] assembliesToIgnore = { "Microsoft.Build.Conversion.Core", "Microsoft.NET.StringTools.net35", "Microsoft.Build.Engine", "Microsoft.Activities.Build", "XamlBuildTask" }; public override bool Execute() From abf550f2bc4586717049d60400980baaa764db14 Mon Sep 17 00:00:00 2001 From: Forgind Date: Fri, 17 Dec 2021 10:13:00 -0800 Subject: [PATCH 23/27] Revert "Update src/MSBuild/MSBuild.csproj" This reverts commit cbb140d81ea32ce2be5ab1b7a99bde55eda46e5f. --- src/MSBuild/MSBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index a25d19298d8..7bd20bf6aba 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -337,7 +337,7 @@ - + From 90997125c9386d1eb751f992a7440b9a634b4848 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 5 Jan 2022 09:24:37 -0800 Subject: [PATCH 24/27] Revert "Update src/MSBuild/MSBuild.csproj" This reverts commit b75a202db6dbf30b9184675f664afcbc112ed57b. --- src/MSBuild/MSBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 7bd20bf6aba..1c3842942f3 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -336,7 +336,7 @@ - + From 0be049f733f0f6a7524756e85d50e8d099f4eb72 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 5 Jan 2022 09:41:54 -0800 Subject: [PATCH 25/27] Stop batching --- src/MSBuild/MSBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 1c3842942f3..803083dd1fc 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -337,7 +337,7 @@ - + From fe5159a0adeff109b2bdc7d593a5ddd146b92f10 Mon Sep 17 00:00:00 2001 From: Forgind Date: Wed, 5 Jan 2022 09:55:31 -0800 Subject: [PATCH 26/27] Update comment --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index cdab495c6d0..25f83b5711d 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -19,6 +19,7 @@ public class ValidateMSBuildPackageDependencyVersions : Task // Microsoft.Build.Conversion.Core and Microsoft.Build.Engine are deprecated. We don't ship them, but they're still used in VS for now. We should ensure they're the right version if present. // Microsoft.NET.StringTools uses API not available in net35, but since we need it to work for TaskHosts as well, there are simpler versions implemented for that. Ensure it's the right version. + // Microsoft.Activities.Build and XamlBuildTask are loaded within an AppDomain in the XamlBuildTask after having been loaded from the GAC elsewhere. See https://github.com/dotnet/msbuild/pull/856 private string[] assembliesToIgnore = { "Microsoft.Build.Conversion.Core", "Microsoft.NET.StringTools.net35", "Microsoft.Build.Engine", "Microsoft.Activities.Build", "XamlBuildTask" }; public override bool Execute() From a4f3b4c63c1e0f12cebbd444dc4f576f0d1cfc4e Mon Sep 17 00:00:00 2001 From: Forgind Date: Thu, 6 Jan 2022 11:25:14 -0800 Subject: [PATCH 27/27] Fix comment --- src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs index 25f83b5711d..6834799b28b 100644 --- a/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs +++ b/src/MSBuild/ValidateMSBuildPackageDependencyVersions.cs @@ -17,7 +17,7 @@ public class ValidateMSBuildPackageDependencyVersions : Task [Required] public string AssemblyPath { get; set; } - // Microsoft.Build.Conversion.Core and Microsoft.Build.Engine are deprecated. We don't ship them, but they're still used in VS for now. We should ensure they're the right version if present. + // Microsoft.Build.Conversion.Core and Microsoft.Build.Engine are deprecated, but they're still used in VS for now. This project doesn't directly reference them, so they don't appear in its output directory. // Microsoft.NET.StringTools uses API not available in net35, but since we need it to work for TaskHosts as well, there are simpler versions implemented for that. Ensure it's the right version. // Microsoft.Activities.Build and XamlBuildTask are loaded within an AppDomain in the XamlBuildTask after having been loaded from the GAC elsewhere. See https://github.com/dotnet/msbuild/pull/856 private string[] assembliesToIgnore = { "Microsoft.Build.Conversion.Core", "Microsoft.NET.StringTools.net35", "Microsoft.Build.Engine", "Microsoft.Activities.Build", "XamlBuildTask" };