diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 6c9fa4b2e0a..fef2a910123 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -31,6 +31,7 @@ $(XunitOptions) -notrait category=mono-windows-failing $(XunitOptions) -notrait category=nonnetcoreapptests + $(XunitOptions) -notrait category=nonnetfxtests $(XunitOptions) -notrait category=failing diff --git a/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs b/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs index 17e0785b405..30ce4b486ad 100644 --- a/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs +++ b/src/Tasks.UnitTests/ResourceHandling/GenerateResource_Tests.cs @@ -1713,11 +1713,7 @@ public void DuplicateResourceNames() /// /// Non-string resource with text output /// -#if RUNTIME_TYPE_NETCORE - [Fact (Skip = "https://github.com/Microsoft/msbuild/issues/308")] -#else [Fact] -#endif public void UnsupportedTextType() { string bitmap = Utilities.CreateWorldsSmallestBitmap(); @@ -1776,11 +1772,8 @@ public void InvalidStateFile() /// /// Cause failures in ResourceReader /// -#if RUNTIME_TYPE_NETCORE - [Fact (Skip = "https://github.com/Microsoft/msbuild/issues/308")] -#else [Fact] -#endif + [SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp, ".NET Core MSBuild doesn't try to read binary input resources")] public void FailedResourceReader() { GenerateResource t = Utilities.CreateTask(_output); @@ -1807,6 +1800,28 @@ public void FailedResourceReader() File.Delete(item.ItemSpec); } + [Theory] + [InlineData(".resources")] + [InlineData(".dll")] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "This error is .NET Core only")] + public void ResourceReaderRejectsNonCoreCompatFormats(string inputExtension) + { + using var env = TestEnvironment.Create(_output); + + GenerateResource t = Utilities.CreateTask(_output); + t.StateFile = new TaskItem(env.GetTempFile(".cache").Path); + + // file contents aren't required since the extension is checked first + var resourcesFile = env.CreateFile(inputExtension).Path; + + t.Sources = new ITaskItem[] { new TaskItem(resourcesFile) }; + t.OutputResources = new ITaskItem[] { new TaskItem(env.GetTempFile(".resources").Path) }; + + t.Execute().ShouldBeFalse(); + + Utilities.AssertLogContains(t, "MSB3824"); + } + /// /// Invalid STR Class name /// @@ -1844,11 +1859,9 @@ public void FailedSTRProperty() /// /// Reference passed in that can't be loaded should error /// -#if RUNTIME_TYPE_NETCORE - [Fact (Skip = "https://github.com/Microsoft/msbuild/issues/308")] -#else [Fact] -#endif + [SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp, + reason: ".NET Core MSBuild doesn't load refs so it pushes this failure to runtime")] public void InvalidReference() { string txtFile = null; @@ -3700,7 +3713,7 @@ public static string GetTestResXContent(bool useType, string linkedBitmap, strin /// Indicates whether to include an enum to test type-specific resource encoding with assembly references /// The name of a linked-in bitmap. use 'null' for no bitmap. /// The name of the resx file - public static string WriteTestResX(bool useType, string linkedBitmap, string extraToken, string resxFileToWrite = null) + public static string WriteTestResX(bool useType, string linkedBitmap, string extraToken, string resxFileToWrite = null, TestEnvironment env = null) { return WriteTestResX(useType, linkedBitmap, extraToken, useInvalidType: false, resxFileToWrite:resxFileToWrite); } @@ -3711,16 +3724,26 @@ public static string WriteTestResX(bool useType, string linkedBitmap, string ext /// Indicates whether to include an enum to test type-specific resource encoding with assembly references /// The name of a linked-in bitmap. use 'null' for no bitmap. /// The name of the resx file - public static string WriteTestResX(bool useType, string linkedBitmap, string extraToken, bool useInvalidType, string resxFileToWrite = null) + public static string WriteTestResX(bool useType, string linkedBitmap, string extraToken, bool useInvalidType, string resxFileToWrite = null, TestEnvironment env = null) { string resgenFile = resxFileToWrite; - if (string.IsNullOrEmpty(resgenFile)) + + string contents = GetTestResXContent(useType, linkedBitmap, extraToken, useInvalidType); + + if (env == null) + { + if (string.IsNullOrEmpty(resgenFile)) + { + resgenFile = GetTempFileName(".resx"); + } + + File.WriteAllText(resgenFile, contents); + } + else { - resgenFile = GetTempFileName(".resx"); - File.Delete(resgenFile); + resgenFile = env.CreateFile(".resx", contents).Path; } - File.WriteAllText(resgenFile, GetTestResXContent(useType, linkedBitmap, extraToken, useInvalidType)); return resgenFile; } diff --git a/src/Tasks/GenerateResource.cs b/src/Tasks/GenerateResource.cs index 8d8b8a27bd3..7d5f428fedb 100644 --- a/src/Tasks/GenerateResource.cs +++ b/src/Tasks/GenerateResource.cs @@ -2603,6 +2603,12 @@ private bool ProcessFile(string inFile, string outFileOrDir) { ReadResources(inFile, _useSourcePath, outFileOrDir); } + catch (InputFormatNotSupportedException) + { + _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), 0, 0, 0, 0, + "GenerateResource.CoreSupportsLimitedScenarios"); + return false; + } catch (MSBuildResXException msbuildResXException) { _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), 0, 0, 0, 0, @@ -2988,7 +2994,7 @@ private void ReadResources(String filename, bool shouldUseSourcePath, String out #if FEATURE_ASSEMBLY_LOADFROM ReadAssemblyResources(filename, outFileOrDir); #else - _logger.LogError("Reading resources from Assembly not supported on .NET Core MSBuild"); + throw new InputFormatNotSupportedException("Reading resources from Assembly not supported on .NET Core MSBuild"); #endif } else @@ -3046,10 +3052,10 @@ private void ReadResources(String filename, bool shouldUseSourcePath, String out case Format.Binary: #if FEATURE_RESX_RESOURCE_READER ReadResources(reader, new ResourceReader(filename), filename); // closes reader for us + break; #else - _logger.LogError("ResGen.exe not supported on .NET Core MSBuild"); + throw new InputFormatNotSupportedException("Reading resources from binary .resources not supported on .NET Core MSBuild"); #endif - break; default: // We should never get here, we've already checked the format @@ -3387,8 +3393,13 @@ private bool HaveSystemResourcesExtensionsReference PopulateAssemblyNames(); - foreach (var assemblyName in _assemblyNames) + foreach (AssemblyNameExtension assemblyName in _assemblyNames) { + if (assemblyName == null) + { + continue; + } + if (string.Equals(assemblyName.Name, "System.Resources.Extensions", StringComparison.OrdinalIgnoreCase)) { _haveSystemResourcesExtensionsReference = true; @@ -3761,14 +3772,16 @@ private void WriteTextResources(ReaderInfo reader, String fileName) { using (StreamWriter writer = FileUtilities.OpenWrite(fileName, false, Encoding.UTF8)) { - foreach (LiveObjectResource entry in reader.resources) + foreach (IResource resource in reader.resources) { - String key = entry.Name; - Object v = entry.Value; + LiveObjectResource entry = resource as LiveObjectResource; + + String key = entry?.Name; + Object v = entry?.Value; String value = v as String; if (value == null) { - _logger.LogErrorWithCodeFromResources(null, fileName, 0, 0, 0, 0, "GenerateResource.OnlyStringsSupported", key, v.GetType().FullName); + _logger.LogErrorWithCodeFromResources(null, fileName, 0, 0, 0, 0, "GenerateResource.OnlyStringsSupported", key, v?.GetType().FullName); } else { diff --git a/src/Tasks/ResourceHandling/InputFormatNotSupportedException.cs b/src/Tasks/ResourceHandling/InputFormatNotSupportedException.cs new file mode 100644 index 00000000000..10eded9046f --- /dev/null +++ b/src/Tasks/ResourceHandling/InputFormatNotSupportedException.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.Build.Tasks.ResourceHandling +{ + [Serializable] + internal class InputFormatNotSupportedException : Exception + { + public InputFormatNotSupportedException() + { + } + + public InputFormatNotSupportedException(string message) : base(message) + { + } + + public InputFormatNotSupportedException(string message, Exception innerException) : base(message, innerException) + { + } + + protected InputFormatNotSupportedException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/src/Tasks/Resources/Strings.resx b/src/Tasks/Resources/Strings.resx index 406643b78ab..e1cdcf34fae 100644 --- a/src/Tasks/Resources/Strings.resx +++ b/src/Tasks/Resources/Strings.resx @@ -1130,6 +1130,10 @@ MSB3823: Non-string resources require the property GenerateResourceUsePreserializedResources to be set to true. {StrBegin="MSB3823: "} + + MSB3824: In order to build with .NET Core, resource inputs must be in .txt or .resx format. + {StrBegin="MSB3824: "} +