From 68fa6537305beda5cb059c898349f37bda285ca7 Mon Sep 17 00:00:00 2001
From: Tom Deseyn <tom.deseyn@gmail.com>
Date: Thu, 1 Feb 2024 09:23:16 +0100
Subject: [PATCH 1/1] Exec: stop setting a locale on Unix.

This backports a fix that is part of Microsoft's upcoming
8.0.2xx SDK to the 8.0.1xx SDK that we package.

This fix stops MSBuild Exec from printing warnings and/or
failing in bash envionments where the glibc en_US locale
is not available (which is common in container images).

The backport includes the changewave opt-out that allows
users to revert back to the previous behavior by setting
the MSBUILDDISABLEFEATURESFROMVERSION envvar to the
version where the feature is introduced ("17.10").
---
 src/msbuild/src/Framework/ChangeWaves.cs      |  3 +-
 src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs | 36 +++++++++++++++++++
 src/msbuild/src/Tasks/Exec.cs                 |  7 +++-
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/src/msbuild/src/Framework/ChangeWaves.cs b/src/msbuild/src/Framework/ChangeWaves.cs
index 0050723798..1f925324ac 100644
--- a/src/msbuild/src/Framework/ChangeWaves.cs
+++ b/src/msbuild/src/Framework/ChangeWaves.cs
@@ -27,7 +27,8 @@ namespace Microsoft.Build.Framework
         internal static readonly Version Wave17_4 = new Version(17, 4);
         internal static readonly Version Wave17_6 = new Version(17, 6);
         internal static readonly Version Wave17_8 = new Version(17, 8);
-        internal static readonly Version[] AllWaves = { Wave17_4, Wave17_6, Wave17_8 };
+        internal static readonly Version Wave17_10 = new Version(17, 10);
+        internal static readonly Version[] AllWaves = { Wave17_4, Wave17_6, Wave17_8, Wave17_10 };
 
         /// <summary>
         /// Special value indicating that all features behind all Change Waves should be enabled.
diff --git a/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs b/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs
index cb468a6cce..c0598e4978 100644
--- a/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs
+++ b/src/msbuild/src/Tasks.UnitTests/Exec_Tests.cs
@@ -69,6 +69,42 @@ namespace Microsoft.Build.UnitTests
             }
         }
 
+        [UnixOnlyTheory]
+        [InlineData(true)]
+        [InlineData(false)]
+        public void ExecSetsLocaleOnUnix(bool enableChangeWave)
+        {
+            using (var env = TestEnvironment.Create())
+            {
+                env.SetEnvironmentVariable("LANG", null);
+                env.SetEnvironmentVariable("LC_ALL", null);
+
+                if (enableChangeWave)
+                {
+                    ChangeWaves.ResetStateForTests();
+                    // Important: use the version here
+                    env.SetEnvironmentVariable("MSBUILDDISABLEFEATURESFROMVERSION", ChangeWaves.Wave17_10.ToString());
+                    BuildEnvironmentHelper.ResetInstance_ForUnitTestsOnly();
+                }
+
+                Exec exec = PrepareExec("echo LANG=$LANG; echo LC_ALL=$LC_ALL;");
+                bool result = exec.Execute();
+                Assert.True(result);
+
+                MockEngine engine = (MockEngine)exec.BuildEngine;
+                if (enableChangeWave)
+                {
+                    engine.AssertLogContains("LANG=en_US.UTF-8");
+                    engine.AssertLogContains("LC_ALL=en_US.UTF-8");
+                }
+                else
+                {
+                    engine.AssertLogDoesntContain("LANG=en_US.UTF-8");
+                    engine.AssertLogDoesntContain("LC_ALL=en_US.UTF-8");
+                }
+            }
+        }
+
         /// <summary>
         /// Ensures that calling the Exec task does not leave any extra TEMP files
         /// lying around.
diff --git a/src/msbuild/src/Tasks/Exec.cs b/src/msbuild/src/Tasks/Exec.cs
index dbf4be1fc5..9faaa68887 100644
--- a/src/msbuild/src/Tasks/Exec.cs
+++ b/src/msbuild/src/Tasks/Exec.cs
@@ -591,7 +591,12 @@ namespace Microsoft.Build.Tasks
             {
                 commandLine.AppendSwitch("-c");
                 commandLine.AppendTextUnquoted(" \"");
-                commandLine.AppendTextUnquoted("export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; . ");
+                bool setLocale = !ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_10);
+                if (setLocale)
+                {
+                    commandLine.AppendTextUnquoted("export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; ");
+                }
+                commandLine.AppendTextUnquoted(". ");
                 commandLine.AppendFileNameIfNotNull(batchFileForCommandLine);
                 commandLine.AppendTextUnquoted("\"");
             }
-- 
2.43.0