From 8fe6f66b1fb0e81c6fad632e4f22710c0aee4c22 Mon Sep 17 00:00:00 2001 From: Carsten Igel <1760987+carstencodes@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:35:05 +0100 Subject: [PATCH] feat: Remove BuildTask implementations (#305) * feat: Remove BuildTask implementations - Ensure that dscom tlbembed task can be used via CLI (Changes introduced by @bclothier) - Let dscom build assembly be present, even though unused - Remove implementation of tasks - Removed obsolete tests Closes #280 * docs: Removed tool based switch, as native task is dropped * chore: More Debug output --------- Co-authored-by: Carsten Igel --- .github/workflows/code-style.yaml | 5 +- README.md | 19 - src/dscom.build/DefaultBuildContext.cs | 385 -------- src/dscom.build/FileSystemChecks.cs | 161 ---- src/dscom.build/IBuildContext.cs | 66 -- src/dscom.build/LoggingTypeLibExporterSink.cs | 69 -- src/dscom.build/System.Net.Http.cs | 17 - src/dscom.build/TlbEmbed.cs | 115 +-- src/dscom.build/TlbExport.cs | 170 +--- ...me.InteropServices.BuildTasks.Task.targets | 64 -- ...e.InteropServices.BuildTasks.Tools.targets | 36 + ...E.Runtime.InteropServices.BuildTasks.props | 2 - ...Runtime.InteropServices.BuildTasks.targets | 5 +- src/dscom.test/tests/BuildTaskTest.cs | 820 ------------------ 14 files changed, 47 insertions(+), 1887 deletions(-) delete mode 100644 src/dscom.build/DefaultBuildContext.cs delete mode 100644 src/dscom.build/FileSystemChecks.cs delete mode 100644 src/dscom.build/IBuildContext.cs delete mode 100644 src/dscom.build/LoggingTypeLibExporterSink.cs delete mode 100644 src/dscom.build/System.Net.Http.cs delete mode 100644 src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Task.targets delete mode 100644 src/dscom.test/tests/BuildTaskTest.cs diff --git a/.github/workflows/code-style.yaml b/.github/workflows/code-style.yaml index 72f956eb..d7ae2de1 100644 --- a/.github/workflows/code-style.yaml +++ b/.github/workflows/code-style.yaml @@ -22,7 +22,10 @@ jobs: run: dotnet restore - name: Check dotnet version - run: dotnet --version + run: | + dotnet --version + dotnet --list-runtimes + dotnet --list-sdks continue-on-error: false - name: Check code format (editorconfig) diff --git a/README.md b/README.md index 1ba185e1..4765cc00 100644 --- a/README.md +++ b/README.md @@ -272,24 +272,6 @@ The result should be a line as follows in your `.csproj` file: **Note**: The extra attribute `NoWarn="NU1701"` is only required, if neither `.NET 4.8` nor `.NET 6.0` are targeted, since dotnet pack will currently not create a .NETStandard 2.0 compliant NuGet Package. -#### Using the native build task - -The native build task is automatically selected, if a .NET 4.8 or .NET 6.0 assembly for Windows is being build using an x64 platform. - -#### Using the CLI based task - -The CLI task is automatically selected, if a .NET Standard 2.0 assembly is being build. It is also chosen if the target platform is set to x86. - -#### Enforcing the usage of the CLI - -It might be necessary to select the CLI based task. To do so, add the following property to your `.csproj` file: - -```XML -<_DsComForceToolUsage>true -``` - -This will enforce the usage of the DsCom as a command-line tool. Please note, that verbose logging will no longer be working. - #### Enforcing to stop the build, if an error occurs The build tasks puts a warning to the build log, if the desired type library has not been created, even if the backend has reported a success. @@ -309,7 +291,6 @@ The build task can be parameterized with the following [properties](https://lear | **Name** | **Description** | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------- | | _DsComTlbExt | Extension of the resulting type library.
Default Value: `.tlb` | -| _DsComForceToolUsage | Use DsCom Exe files to create the TLB
Default value: `false` | | DsComTypeLibraryUniqueId | Overwrite the library UUID
Default Value: Empty Guid | | DsComOverideLibraryName | Overwrite the IDL name of the library.
Default Value: Empty string | | DsComRegisterTypeLibrariesAfterBuild | Use regasm call after the build to register type library after the build
Default value: `false` | diff --git a/src/dscom.build/DefaultBuildContext.cs b/src/dscom.build/DefaultBuildContext.cs deleted file mode 100644 index 3e2b3d98..00000000 --- a/src/dscom.build/DefaultBuildContext.cs +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Carsten Igel and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Reflection; -#if NET5_0_OR_GREATER -using System.Runtime.Loader; -#endif -using System.Security; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -using COMException = System.Runtime.InteropServices.COMException; -using SystemInteropServices = System.Runtime.InteropServices; - -namespace dSPACE.Runtime.InteropServices.BuildTasks; - -/// -/// Default implementation of the interface -/// using as implementation for conversion -/// and as implementation for -/// event handling. -/// -internal sealed class DefaultBuildContext : IBuildContext -{ - /// - public bool IsRunningOnWindows => SystemInteropServices.RuntimeInformation.IsOSPlatform(SystemInteropServices.OSPlatform.Windows); - -#if NET5_0_OR_GREATER - /// - public string RuntimeDescription => $"{SystemInteropServices.RuntimeInformation.OSDescription} {SystemInteropServices.RuntimeInformation.OSArchitecture} ({SystemInteropServices.RuntimeInformation.ProcessArchitecture} [{SystemInteropServices.RuntimeInformation.RuntimeIdentifier} - {SystemInteropServices.RuntimeInformation.FrameworkDescription}])"; -#else - /// - public string RuntimeDescription => $"{SystemInteropServices.RuntimeInformation.OSDescription} {SystemInteropServices.RuntimeInformation.OSArchitecture} ({SystemInteropServices.RuntimeInformation.ProcessArchitecture} [{SystemInteropServices.RuntimeInformation.FrameworkDescription}])"; -#endif - - /// - public bool EnsureFileExists(string? fileNameAndPath) - { - return File.Exists(fileNameAndPath); - } - - /// - public bool EnsureDirectoryExists(string? directoryPath) - { - return Directory.Exists(directoryPath); - } - - /// - public bool ConvertAssemblyToTypeLib(TypeLibConverterSettings settings, TaskLoggingHelper log) - { - // Load assembly from file. -#if NET5_0_OR_GREATER - var loadContext = CreateLoadContext(settings, log); - var assembly = LoadAssembly(settings, loadContext, log); -#else - log.LogWarning("Unloading assemblies is only supported with .NET 5 or later. Please remove all remaining MsBuild processes before rebuild."); - var assembly = LoadAssembly(settings, log); -#endif - - if (assembly is null) - { - log.LogWarning("Failed to load assembly {0}. Task failed.", settings.Assembly); - return false; - } - - try - { - // Create type library converter. - var converter = new TypeLibConverter(); - - // Choose appropriate name resolver based on inputs with the Com Alias as the fallback. - var nameResolver = settings.Names.Length != 0 - ? NameResolver.Create(settings.Names) - : NameResolver.Create(assembly); - - // Create event handler. - var sink = new LoggingTypeLibExporterSink(log, nameResolver); - - // create conversion. - var tlb = converter.ConvertAssemblyToTypeLib(assembly, settings, sink); - if (tlb == null) - { - log.LogError("The following type library could not be created successfully: {0}. Reason: Operation was not successful.", settings.Out); - } - else - { - log.LogMessage(MessageImportance.High, "Finished generation of the following type library: {0}", settings.Out); - } - - if (!File.Exists(settings.Out)) - { - log.LogWarning( - null, - "DSCOM001", - null, - null, - 0, - 0, - 0, - 0, - "Could not find the type library at the following location: {0}", settings.Out); - } - - return tlb != null; - } - catch (COMException e) - { - log.LogErrorFromException(e, false, true, settings.Assembly); - return false; - } -#if NET5_0_OR_GREATER - finally - { - try - { - loadContext.Unload(); - } - catch (InvalidOperationException) - { - log.LogWarning("Failed to unload the assembly load context."); - } - } -#endif - } - - public bool EmbedTypeLib(TypeLibEmbedderSettings settings, TaskLoggingHelper log) - { - try - { - var result = TypeLibEmbedder.EmbedTypeLib(settings); - if (!result) - { - log.LogError("Could not embed type library {0} into assembly {1}", settings.SourceTypeLibrary, settings.TargetAssembly); - return false; - } - - return true; - } - catch (Exception ex) - { - log.LogErrorFromException(ex); - return false; - } - } - -#if NET5_0_OR_GREATER - /// - /// Creates an instance of that will - /// take care of the loading and unloading the target assemblies and - /// can be unloaded afterwards. - /// - /// The type library settings. - /// An that can be unloaded. - private static AssemblyLoadContext CreateLoadContext(TypeLibConverterSettings settings, TaskLoggingHelper log) - { - var loadContext = new AssemblyLoadContext($"msbuild-load-ctx-{Guid.NewGuid()}", true); - loadContext.Resolving += (ctx, name) => - { - if (TryResolveAssemblyFromSettings(name.Name ?? string.Empty, settings, log, out var assemblyPath)) - { - return ctx.LoadFromAssemblyPath(assemblyPath); - } - - log.LogWarning("Failed to resolve {0} from the following files: {1}", name.Name, string.Join(", ", settings.ASMPath)); - - return default; - }; - - return loadContext; - } - - /// - /// Tries to load the assembly specified in the using the specified - /// . If the assembly cannot be loaded, the result will be null. - /// - /// The settings. - /// The assembly load context. - /// The log to write messages to. - /// The assembly loaded. - private static Assembly? LoadAssembly(TypeLibConverterSettings settings, AssemblyLoadContext loadContext, TaskLoggingHelper log) - { - Assembly assembly; - try - { - assembly = loadContext.LoadFromAssemblyPath(settings.Assembly); - } - catch (Exception e) when - (e is ArgumentNullException - or FileNotFoundException - or FileLoadException - or BadImageFormatException - or SecurityException - or ArgumentException - or PathTooLongException) - { - log.LogErrorFromException(e, true, true, settings.Assembly); - try - { - loadContext.Unload(); - } - catch (InvalidOperationException) - { - log.LogWarning("Failed to unload the following assembly: {0}.", settings.Assembly); - } - - return default; - } - - return assembly; - } -#else - /// - /// Tries to load the assembly specified in the using the current - /// . If the assembly cannot be loaded, the result will be null. - /// - /// The settings. - /// The log to write messages to. - /// The assembly loaded. - private static Assembly? LoadAssembly(TypeLibConverterSettings settings, TaskLoggingHelper log) - { - try - { - var content = File.ReadAllBytes(settings.Assembly); - var appDomain = AppDomain.CurrentDomain; - var resolveHandler = CreateResolveHandler(settings, log); - try - { - appDomain.AssemblyResolve += resolveHandler; - return appDomain.Load(content); - } - finally - { - appDomain.AssemblyResolve -= resolveHandler; - } - } - catch (Exception e) when - (e is ArgumentNullException - or PathTooLongException - or DirectoryNotFoundException - or IOException - or UnauthorizedAccessException - or FileNotFoundException - or NotSupportedException - or SecurityException) - { - log.LogErrorFromException(e, true, true, settings.Assembly); - return default; - } - } - - /// - /// Creates an that tries to look up a dependent assembly. - /// - /// The conversion settings. - /// The task logging helper. - /// A new resolve event handler instance. - private static ResolveEventHandler CreateResolveHandler(TypeLibConverterSettings settings, TaskLoggingHelper log) - { - Assembly? AssemblyResolveClosure(object? sender, ResolveEventArgs args) - { - if (TryResolveAssemblyFromSettings(args.Name ?? string.Empty, settings, log, out var assemblyPath)) - { - return AppDomain.CurrentDomain.Load(assemblyPath); - } - - log.LogWarning("Failed to resolve assembly: {0}", args.Name); - return default; - } - - return AssemblyResolveClosure; - } -#endif - - /// - /// Tries to resolve the managed assembly with the specified from the . - /// If this method returns true, the resolved file path will be written to . - /// - /// The name of the assembly file to load (without extension). - /// The settings for type conversions. - /// The logging helper. - /// Path to resolved file. - /// true, if the assembly could be resolved; false otherwise. - private static bool TryResolveAssemblyFromSettings(string assemblyFileName, TypeLibConverterSettings settings, TaskLoggingHelper log, out string assemblyPath) - { - var validAssemblyExtensions = new string[] { ".dll", ".exe" }; - if (TryResolveAssemblyFromReferencedFiles(assemblyFileName, settings, log, validAssemblyExtensions, out assemblyPath) - || TryResolveAssemblyFromAdjacentFiles(assemblyFileName, settings, log, validAssemblyExtensions, out assemblyPath)) - { - return true; - } - - log.LogWarning("Failed to resolve {0} from the following files: {1}", assemblyFileName, string.Join(", ", settings.ASMPath)); - assemblyPath = string.Empty; - return false; - } - - /// - /// Tries to resolve the managed assembly with the specified from the - /// using the property to identify the assembly. - /// If this method returns true, the resolved file path will be written to . - /// - /// The name of the assembly file to load (without extension). - /// The settings for type conversions. - /// The logging helper. - /// Any extension that might be considered as valid assembly extension. - /// Path to resolved file. - /// true, if the assembly could be resolved; false otherwise. - private static bool TryResolveAssemblyFromReferencedFiles(string assemblyFileName, TypeLibConverterSettings settings, TaskLoggingHelper log, string[] validAssemblyExtensions, out string assemblyPath) - { - log.LogMessage(MessageImportance.Low, "Trying to resolve assembly {0} from referenced files.", assemblyFileName); - foreach (var path in settings.ASMPath) - { - var currentAssemblyFileName = Path.GetFileName(path) ?? string.Empty; - log.LogMessage(MessageImportance.Low, "Current file is {0}. Maybe it matches.", path); - foreach (var extension in validAssemblyExtensions) - { - var possibleFileName = assemblyFileName + extension; - log.LogMessage(MessageImportance.Low, "Trying to resolve assembly {0} as {1}.", assemblyFileName, possibleFileName); - if (StringComparer.InvariantCultureIgnoreCase.Equals(possibleFileName, currentAssemblyFileName) - && File.Exists(path)) - { - log.LogMessage(MessageImportance.Low, "Assembly resolved as {0}.", path); - assemblyPath = path; - return true; - } - } - } - - assemblyPath = string.Empty; - return false; - } - - /// - /// Tries to resolve the managed assembly with the specified from the - /// using the property to look up directories that might contain the file. - /// If this method returns true, the resolved file path will be written to . - /// - /// The name of the assembly file to load (without extension). - /// The settings for type conversions. - /// The logging helper. - /// Any extension that might be considered as valid assembly extension. - /// Path to resolved file. - /// true, if the assembly could be resolved; false otherwise. - private static bool TryResolveAssemblyFromAdjacentFiles(string assemblyFileName, TypeLibConverterSettings settings, TaskLoggingHelper log, string[] validAssemblyExtensions, out string assemblyPath) - { - log.LogMessage(MessageImportance.Low, "Trying to resolve assembly {0} from adjacent files.", assemblyFileName); - foreach (var path in settings.ASMPath) - { - var currentAssemblyFileName = Path.GetFileName(path) ?? string.Empty; - var assemblyDirectoryName = Path.GetDirectoryName(path) ?? string.Empty; - if (string.IsNullOrWhiteSpace(assemblyDirectoryName)) - { - continue; - } - - log.LogMessage(MessageImportance.Low, "Current directory to look at is {0}. Maybe it matches.", assemblyDirectoryName); - foreach (var extension in validAssemblyExtensions) - { - var possibleFileName = assemblyFileName + extension; - var possibleAssemblyFilePath = Path.Combine(assemblyDirectoryName, possibleFileName); - log.LogMessage(MessageImportance.Low, "Trying to resolve assembly {0} as {1}.", assemblyFileName, possibleAssemblyFilePath); - if (File.Exists(possibleAssemblyFilePath)) - { - log.LogMessage(MessageImportance.Low, "Assembly resolved as {0}.", possibleAssemblyFilePath); - assemblyPath = possibleAssemblyFilePath; - return true; - } - } - } - - assemblyPath = string.Empty; - return false; - } -} diff --git a/src/dscom.build/FileSystemChecks.cs b/src/dscom.build/FileSystemChecks.cs deleted file mode 100644 index 4fb16e57..00000000 --- a/src/dscom.build/FileSystemChecks.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Carsten Igel and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Microsoft.Build.Utilities; - -namespace dSPACE.Runtime.InteropServices.BuildTasks; - -/// -/// Implementation of file system contracts and the corresponding checks using the logging mechanisms of MsBuild. -/// -internal sealed class FileSystemChecks -{ - /// - /// The logging mechanism from the task. - /// - private readonly TaskLoggingHelper _log; - - /// - /// The build context. - /// - private readonly IBuildContext _context; - - /// - /// Creates a new instance of the class - /// using the supplied to write messages to. - /// - /// The log to apply. - /// The context to apply. - internal FileSystemChecks(TaskLoggingHelper log, IBuildContext context) - { - _log = log; - _context = context; - } - - /// - /// Verifies, that the specified is a valid file. - /// If a non-existing file shall be treated as an error, the corresponding parameter - /// must be set to true and the check will fail. The result of the check will be stored in the - /// parameter. - /// - /// The files to check. - /// If set to true, the check will fail, if the file does not exist. - /// The result of any previous check. If true is supplied, - /// the result can remain true. Otherwise the result will always be false, even, if the check succeeds. - internal void VerifyFilePresent(string fileSystemReference, bool treatAsError, ref bool checkResult) - { - checkResult = checkResult && LogCheckIfFileSystemEntryIsMissing( - _context.EnsureFileExists, - fileSystemReference, - treatAsError, - "The following file is required, but does not exist: {0}", - fileSystemReference); - } - - /// - /// Verifies, that the specified are valid files. - /// If a non-existing file shall be treated as an error, the corresponding parameter - /// must be set to true and the check will fail. The result of the check will be stored in the - /// parameter. - /// - /// The files to check. - /// If set to true, the check will fail, if at least one file does not exist. - /// The result of any previous check. If true is supplied, - /// the result can remain true. Otherwise the result will always be false, even, if the check succeeds. - internal void VerifyFilesPresent(IReadOnlyCollection fileSystemReferences, bool treatAsError, ref bool checkResult) - { - foreach (var possibleFileSystemEntry in fileSystemReferences) - { - VerifyFilePresent(possibleFileSystemEntry, treatAsError, ref checkResult); - } - } - - /// - /// Verifies, that the specified is a valid directory. - /// If a non-existing file shall be treated as an error, the corresponding parameter - /// must be set to true and the check will fail. The result of the check will be stored in the - /// parameter. - /// - /// The directory to check. - /// If set to true, the check will fail, if the directory does not exist. - /// The result of any previous check. If true is supplied, - /// the result can remain true. Otherwise the result will always be false, even, if the check succeeds. - internal void VerifyDirectoryPresent(string fileSystemReference, bool treatAsError, ref bool checkResult) - { - checkResult = checkResult && LogCheckIfFileSystemEntryIsMissing( - _context.EnsureDirectoryExists, - fileSystemReference, - treatAsError, - "The following file is required, but does not exist: {0}", - fileSystemReference); - } - - /// - /// Verifies, that the specified are valid directories. - /// If a non-existing file shall be treated as an error, the corresponding parameter - /// must be set to true and the check will fail. The result of the check will be stored in the - /// parameter. - /// - /// The directories to check. - /// If set to true, the check will fail, if at least one directory does not exist. - /// The result of any previous check. If true is supplied, - /// the result can remain true. Otherwise the result will always be false, even, if the check succeeds. - internal void VerifyDirectoriesPresent(IReadOnlyCollection fileSystemReferences, bool treatAsError, ref bool checkResult) - { - foreach (var possibleFileSystemEntry in fileSystemReferences) - { - VerifyDirectoryPresent(possibleFileSystemEntry, treatAsError, ref checkResult); - } - } - - - /// - /// Performs the specified method using the . - /// If the check fails, the specified will be issued to the log. - /// If no error is issued, the method will return true. - /// - /// The check to apply. - /// The file system entry to check. - /// If set to true, the will be issued as error; else a warning shall be submitted. - /// The message to log. - /// Formatting arguments for the . - /// true, if the check is issued no error; false otherwise. - private bool LogCheckIfFileSystemEntryIsMissing(Func performCheck, string fileSystemEntry, bool treatAsError, string message, params object[] args) - { - var flag = performCheck(fileSystemEntry); - if (!flag) - { - WriteMessageToLog(treatAsError, message, args); - } - - return !treatAsError || flag; - } - - /// - /// Writes a message to the log referenced by this instance. - /// - /// If set to true, the message will be treated as an error. A warning will be issued otherwise. - /// The message to supply. - /// The arguments to format the message. - private void WriteMessageToLog(bool treatAsError, string message, params object[] args) - { - Action logger = _log.LogWarning; - if (treatAsError) - { - logger = _log.LogError; - } - - logger(message, args); - } -} diff --git a/src/dscom.build/IBuildContext.cs b/src/dscom.build/IBuildContext.cs deleted file mode 100644 index e12855b2..00000000 --- a/src/dscom.build/IBuildContext.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Carsten Igel and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Microsoft.Build.Utilities; - -namespace dSPACE.Runtime.InteropServices.BuildTasks; - -/// -/// Interface representing the execution and build context. -/// This interface is used to separate task execution from -/// tlb conversion. -/// Hence implementations will perform any TLB conversion. -/// -public interface IBuildContext -{ - /// - /// Gets a value indicating whether the current run-time is windows-based or not. - /// - bool IsRunningOnWindows { get; } - - /// - /// Gets a verbatim description of the current run-time. - /// - string RuntimeDescription { get; } - - /// - /// When implemented it will return, whether the specified - /// points to a valid file or not. - /// - /// The name and path of the file. - /// true, if the file exists; false otherwise. - bool EnsureFileExists(string? fileNameAndPath); - - /// - /// When implemented it will return, whether the specified - /// points to a valid directory or not. - /// - /// The name and path of the directory. - /// true, if the directory exists; false otherwise. - bool EnsureDirectoryExists(string? directoryPath); - - /// - /// When implemented in a derived class, the conversion will take place - /// trying to load the assembly specified in the - /// of the specified object and convert it to the type library specified in - /// the of the same parameter. - /// Errors, warnings and conversion messages will be written to the build . - /// - /// The conversion settings to apply to the built-in converter. - /// The log to write error messages to. - /// true, if the conversion has taken place successfully; false otherwise. - bool ConvertAssemblyToTypeLib(TypeLibConverterSettings settings, TaskLoggingHelper log); - - bool EmbedTypeLib(TypeLibEmbedderSettings settings, TaskLoggingHelper log); -} diff --git a/src/dscom.build/LoggingTypeLibExporterSink.cs b/src/dscom.build/LoggingTypeLibExporterSink.cs deleted file mode 100644 index ed740d50..00000000 --- a/src/dscom.build/LoggingTypeLibExporterSink.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Carsten Igel and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Reflection; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace dSPACE.Runtime.InteropServices.BuildTasks; - -/// -/// Implementation of the a -/// forwarding all messages to the MsBuild log. -/// -internal sealed class LoggingTypeLibExporterSink : ITypeLibExporterNotifySink, ITypeLibExporterNameProvider -{ - /// - /// The logging sink. - /// - private readonly TaskLoggingHelper _log; - - private readonly INameResolver _nameResolver; - - /// - /// Creates a new instance of the - /// using the specified as logging target. - /// - /// The log to write to. - internal LoggingTypeLibExporterSink(TaskLoggingHelper log, INameResolver nameResolver) - { - _log = log; - _nameResolver = nameResolver; - } - - public INameResolver GetNameResolver() - { - return _nameResolver; - } - - /// - void ITypeLibExporterNotifySink.ReportEvent(ExporterEventKind eventKind, int eventCode, string eventMsg) - { - var importance = eventKind switch - { - ExporterEventKind.NOTIF_TYPECONVERTED => MessageImportance.Low, - ExporterEventKind.NOTIF_CONVERTWARNING => MessageImportance.Normal, - ExporterEventKind.ERROR_REFTOINVALIDASSEMBLY => MessageImportance.High, - _ => MessageImportance.High, - }; - - _log.LogMessage(importance, "Received {0} event. Event Code is {1}: {2}", Enum.GetName(typeof(ExporterEventKind), eventKind), eventCode, eventMsg); - } - - /// - object? ITypeLibExporterNotifySink.ResolveRef(Assembly assembly) - { - return default; - } -} diff --git a/src/dscom.build/System.Net.Http.cs b/src/dscom.build/System.Net.Http.cs deleted file mode 100644 index 411feef8..00000000 --- a/src/dscom.build/System.Net.Http.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Mark Lechtermann, Matthias Nissen and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// To fix GlobalUsings.g.cs issues - -namespace System.Net.Http; diff --git a/src/dscom.build/TlbEmbed.cs b/src/dscom.build/TlbEmbed.cs index 33cd231c..93ba24c5 100644 --- a/src/dscom.build/TlbEmbed.cs +++ b/src/dscom.build/TlbEmbed.cs @@ -12,12 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NET5_0_OR_GREATER -using System.Runtime.Loader; -#else -using System.Reflection; -#endif - using Microsoft.Build.Framework; namespace dSPACE.Runtime.InteropServices.BuildTasks; @@ -27,26 +21,11 @@ namespace dSPACE.Runtime.InteropServices.BuildTasks; /// public sealed class TlbEmbed : Microsoft.Build.Utilities.Task { - /// - /// The build context applied to this instance. - /// - private readonly IBuildContext _context; - - /// - /// Creates a new instance of the - /// embedder class using the specified build context. - /// - /// The build context to apply. - public TlbEmbed(IBuildContext context) - { - _context = context; - } - /// /// Creates a new instance of the /// class using the default build context. /// - public TlbEmbed() : this(new DefaultBuildContext()) + public TlbEmbed() { } @@ -69,95 +48,7 @@ public TlbEmbed() : this(new DefaultBuildContext()) /// public override bool Execute() { - var targetAssemblyFile = GetTargetRuntimeAssembly(); - - // if the assembly is found next to this assembly - if (File.Exists(targetAssemblyFile)) - { -#if NET5_0_OR_GREATER - // Load the assembly from a context - var loadContext = new AssemblyLoadContext($"msbuild-preload-ctx-{Guid.NewGuid()}", true); - - try - { - _ = loadContext.LoadFromAssemblyPath(targetAssemblyFile); - - // Execute the task with the resolved assembly. - return ExecuteTask(); - } - finally - { - // unload the assembly - loadContext.Unload(); - } -#else - _ = Assembly.LoadFrom(targetAssemblyFile); - - return ExecuteTask(); -#endif - } - else - { - // Make .NET Runtime resolve the file itself - return ExecuteTask(); - } - } - - /// - /// Performs the real task execution with the maybe temporarily loaded - /// Interop Assembly. - /// - /// The result of the task. - private bool ExecuteTask() - { - if (!_context.IsRunningOnWindows) - { - var verbatimDescription = _context.RuntimeDescription; - Log.LogError("This task can only be executed on Microsoft Windows (TM) based operating systems. This platform does not support the creation of this task: {0}", verbatimDescription); - return false; - } - - // Perform file system checks. - var checks = new FileSystemChecks(Log, _context); - - var result = true; - checks.VerifyFilePresent(TargetAssemblyFile, true, ref result); - checks.VerifyFilePresent(SourceTlbFile, true, ref result); - - var settings = new TypeLibEmbedderSettings - { - SourceTypeLibrary = SourceTlbFile, - TargetAssembly = TargetAssemblyFile - }; - - // run conversion, if result has been successful. - result = result && _context.EmbedTypeLib(settings, Log); - - // report success or failure. - return result && !Log.HasLoggedErrors; - } - - /// - /// Gets the path to the path to the dSPACE.Runtime.InteropServices.dll - /// next to this assembly. - /// - /// The assembly file path. - private static string GetTargetRuntimeAssembly() - { - var assemblyPath = typeof(TlbExport).Assembly.Location; - var extension = Path.GetExtension(assemblyPath); - var fileBaseName = typeof(TlbExport).Namespace; - fileBaseName = Path.GetFileNameWithoutExtension(fileBaseName); - var fileName = fileBaseName + extension; - var assemblyDir = Path.GetDirectoryName(assemblyPath); - - var targetAssemblyFile = fileName; - - if (!string.IsNullOrWhiteSpace(assemblyDir)) - { - targetAssemblyFile = Path.Combine(assemblyDir, fileName); - } - - return targetAssemblyFile; + /* This task remains for historical reasons */ + throw new NotSupportedException(); } } diff --git a/src/dscom.build/TlbExport.cs b/src/dscom.build/TlbExport.cs index c171904d..d40db584 100644 --- a/src/dscom.build/TlbExport.cs +++ b/src/dscom.build/TlbExport.cs @@ -12,12 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NET5_0_OR_GREATER -using System.Runtime.Loader; -#else -using System.Reflection; -#endif - using Microsoft.Build.Framework; namespace dSPACE.Runtime.InteropServices.BuildTasks; @@ -27,26 +21,11 @@ namespace dSPACE.Runtime.InteropServices.BuildTasks; /// public sealed class TlbExport : Microsoft.Build.Utilities.Task { - /// - /// The build context applied to this instance. - /// - private readonly IBuildContext _context; - - /// - /// Creates a new instance of the - /// export class using the specified build context. - /// - /// The build context to apply. - public TlbExport(IBuildContext context) - { - _context = context; - } - /// /// Creates a new instance of the /// class using the default build context. /// - public TlbExport() : this(new DefaultBuildContext()) + public TlbExport() { } @@ -103,150 +82,7 @@ public TlbExport() : this(new DefaultBuildContext()) /// public override bool Execute() { - var targetAssemblyFile = GetTargetRuntimeAssembly(); - - // if the assembly is found next to this assembly - if (File.Exists(targetAssemblyFile)) - { -#if NET5_0_OR_GREATER - // Load the assembly from a context - var loadContext = new AssemblyLoadContext($"msbuild-preload-ctx-{Guid.NewGuid()}", true); - - try - { - _ = loadContext.LoadFromAssemblyPath(targetAssemblyFile); - - // Execute the task with the resolved assembly. - return ExecuteTask(); - } - finally - { - // unload the assembly - loadContext.Unload(); - } -#else - _ = Assembly.LoadFrom(targetAssemblyFile); - - return ExecuteTask(); -#endif - } - else - { - // Make .NET Runtime resolve the file itself - return ExecuteTask(); - } - } - - /// - /// Performs the real task execution with the maybe temporarily loaded - /// Interop Assembly. - /// - /// The result of the task. - private bool ExecuteTask() - { - if (!_context.IsRunningOnWindows) - { - var verbatimDescription = _context.RuntimeDescription; - Log.LogError("This task can only be executed on Microsoft Windows (TM) based operating systems. This platform does not support the creation of this task: {0}", verbatimDescription); - return false; - } - - if (!Guid.TryParse(TlbOverriddenId, out var tlbOverriddenId)) - { - Log.LogError("Cannot convert {0} to a valid Guid", TlbOverriddenId); - return false; - } - - // Create type library converter settings from task parameters - var settings = new TypeLibConverterSettings() - { - Out = TargetFile, - Assembly = SourceAssemblyFile, - OverrideTlbId = tlbOverriddenId, - TLBReference = ConvertTaskItemToFsPath(TypeLibraryReferences, false), - TLBRefpath = ConvertTaskItemToFsPath(TypeLibraryReferencePaths, false), - ASMPath = ConvertTaskItemToFsPath(AssemblyPaths, true), - OverrideName = TlbOverriddenName - }; - - // Issue a warning, if the type library is about to be overridden. - if (settings.OverrideTlbId != Guid.Empty) - { - Log.LogMessage(MessageImportance.High, "The default unique id of the resulting type library will be overridden with the following value: {0}", settings.OverrideTlbId); - } - - // Perform file system checks. - var checks = new FileSystemChecks(Log, _context); - - var result = true; - checks.VerifyFilePresent(settings.Assembly, true, ref result); - checks.VerifyFilesPresent(settings.TLBReference, false, ref result); - checks.VerifyDirectoriesPresent(settings.TLBRefpath, false, ref result); - checks.VerifyFilesPresent(settings.ASMPath, false, ref result); - - settings.Names = Names ?? Array.Empty(); - - // run conversion, if result has been successful. - result = result && _context.ConvertAssemblyToTypeLib(settings, Log); - - // report success or failure. - return result && !Log.HasLoggedErrors; - } - - /// - /// Takes the of the specified - /// and interprets them as file system entry and hence a file or directory path. - /// - /// The items to interpret a file system entries. - /// If set to true, the can - /// contain the Metadata value 'HintPath'. Hence the data will be scanned for this. - /// If not, it is assumed, that the property - /// contains the file system path. - /// The converted item-spec values. - private static string[] ConvertTaskItemToFsPath(IReadOnlyCollection items, bool canContainHintPaths) - { - const string HintPath = nameof(HintPath); - - var itemsWithHintPath = Enumerable.Empty(); - if (canContainHintPaths) - { - itemsWithHintPath = items - .Where(item => item != null) - .Where(item => !string.IsNullOrWhiteSpace(item.GetMetadata(HintPath))); - } - - var remainingItems = items.Except(itemsWithHintPath); - - return itemsWithHintPath - .Select(item => item.GetMetadata(HintPath)) - .Union(remainingItems.Where(item => item != null) - .Select(item => item.ItemSpec)).ToArray(); + /* This task remains for historical reasons */ + throw new NotSupportedException(); } - - - /// - /// Gets the path to the path to the dSPACE.Runtime.InteropServices.dll - /// next to this assembly. - /// - /// The assembly file path. - private static string GetTargetRuntimeAssembly() - { - var assemblyPath = typeof(TlbExport).Assembly.Location; - var extension = Path.GetExtension(assemblyPath); - var fileBaseName = typeof(TlbExport).Namespace; - fileBaseName = Path.GetFileNameWithoutExtension(fileBaseName); - var fileName = fileBaseName + extension; - var assemblyDir = Path.GetDirectoryName(assemblyPath); - - var targetAssemblyFile = fileName; - - if (!string.IsNullOrWhiteSpace(assemblyDir)) - { - targetAssemblyFile = Path.Combine(assemblyDir, fileName); - } - - return targetAssemblyFile; - } - - } diff --git a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Task.targets b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Task.targets deleted file mode 100644 index 4de3f686..00000000 --- a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Task.targets +++ /dev/null @@ -1,64 +0,0 @@ - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - <_DsComTargetFramework>net6.0 - <_DsComTargetFramework Condition="'$(TargetFramework)' == 'net48'">$(TargetFramework) - - <_DsComTaskAssemblyFile>$(MsBuildThisFileDirectory)_dscom\$(_DsComTargetFramework)\dSPACE.Runtime.InteropServices.BuildTasks.dll - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets index 7fdfb25d..f2dcb9ff 100644 --- a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets +++ b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets @@ -70,6 +70,10 @@ + + + + + + <_DsComArguments>tlbembed + <_DsComArguments> $(_DsComArguments) "$(_DsComExportTypeLibraryTargetFile)" + <_DsComArguments> $(_DsComArguments) "$(_DsComExportTypeLibraryAssemblyFile)" + <_DsComWorkingDir>$(OutDir) + <_DsComWorkingDir Condition="$(_DsComWorkingDir) == ''">$(OutputPath) + + + + + + + + + + + diff --git a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.props b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.props index 0cfad48c..bf51ee98 100644 --- a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.props +++ b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.props @@ -22,8 +22,6 @@ <_DsComTlbExt>.tlb - - <_DsComForceToolUsage>true diff --git a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.targets b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.targets index e870cb89..c9916fa2 100644 --- a/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.targets +++ b/src/dscom.build/dSPACE.Runtime.InteropServices.BuildTasks.targets @@ -20,10 +20,7 @@ - <_DsComExporterTargetsFile>$(MsBuildThisFileDirectory)dSPACE.Runtime.InteropServices.BuildTasks.Task.targets - <_DsComExporterTargetsFile Condition="'$(TargetFramework)' == 'netstandard2.0' OR ('$(TargetFrameworks)' != '' AND $(TargetFrameworks.Contains('netstandard2.0'))) OR 'Platform' == 'x86' OR ('Platform' == 'AnyCPU' AND '$(SolutionPlatform)' == 'x86')">$(MsBuildThisFileDirectory)dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets - <_DsComExporterTargetsFile Condition="'$(NETCoreSdkRuntimeIdentifier)' == 'win-x86'">$(MsBuildThisFileDirectory)dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets - <_DsComExporterTargetsFile Condition="'$(_DsComForceToolUsage)' == 'true'">$(MsBuildThisFileDirectory)dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets + <_DsComExporterTargetsFile>$(MsBuildThisFileDirectory)dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets diff --git a/src/dscom.test/tests/BuildTaskTest.cs b/src/dscom.test/tests/BuildTaskTest.cs deleted file mode 100644 index de7def3b..00000000 --- a/src/dscom.test/tests/BuildTaskTest.cs +++ /dev/null @@ -1,820 +0,0 @@ -// Copyright 2022 dSPACE GmbH, Mark Lechtermann, Matthias Nissen and Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Collections; -using dSPACE.Runtime.InteropServices.BuildTasks; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -using Moq; - -namespace dSPACE.Runtime.InteropServices.Tests; - -public class BuildTaskTest : BaseTest -{ - private sealed class BuildContextStub : IBuildContext - { - public ISet ExistingFiles = new HashSet(StringComparer.InvariantCultureIgnoreCase); - - public ISet ExistingDirectories = new HashSet(StringComparer.InvariantCultureIgnoreCase); - - public bool ShouldSucceed { get; set; } = true; - - public bool IsRunningOnWindows { get; set; } = true; - - public string RuntimeDescription { get; set; } = "x-unit runner"; - - public bool ConvertAssemblyToTypeLib(TypeLibConverterSettings settings, TaskLoggingHelper log) - { - return ShouldSucceed; - } - - public bool EmbedTypeLib(TypeLibEmbedderSettings settings, TaskLoggingHelper log) - { - return ShouldSucceed; - } - - public bool EnsureFileExists(string? fileNameAndPath) - { - return !ExistingFiles.Any() || ExistingFiles.Contains(fileNameAndPath ?? string.Empty); - } - - public bool EnsureDirectoryExists(string? directoryNameAndPath) - { - return !ExistingDirectories.Any() || ExistingDirectories.Contains(directoryNameAndPath ?? string.Empty); - } - } - - private sealed class BuildEngineStub : IBuildEngine - { - public bool ContinueOnError => true; - - public int LineNumberOfTaskNode => 1; - - public int ColumnNumberOfTaskNode => 1; - - public string ProjectFileOfTaskNode => "demo.test.csproj"; - - public int NumberOfCustomLogEvents { get; private set; } - - public int NumberOfMessageLogEvents { get; private set; } - - public int NumberOfWarningLogEvents { get; private set; } - - public int NumberOfErrorLogEvents { get; private set; } - - public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) - { - return true; - } - - public void LogCustomEvent(CustomBuildEventArgs e) - { - NumberOfCustomLogEvents++; - } - - public void LogErrorEvent(BuildErrorEventArgs e) - { - NumberOfErrorLogEvents++; - } - - public void LogMessageEvent(BuildMessageEventArgs e) - { - NumberOfMessageLogEvents++; - } - - public void LogWarningEvent(BuildWarningEventArgs e) - { - NumberOfWarningLogEvents++; - } - } - - private static ITaskItem GetTaskItem(string itemSpec, string? path = null, bool useHintPath = false) - { - var taskItemMock = new Mock(MockBehavior.Loose); - - taskItemMock.SetupGet(inst => inst.ItemSpec).Returns(itemSpec); - - if (useHintPath) - { - const string HintPath = nameof(HintPath); - - var hintPath = path ?? itemSpec; - - taskItemMock.Setup(inst => inst.GetMetadata(It.IsNotIn(new string[] { HintPath }, StringComparer.InvariantCulture))).Returns(string.Empty); - taskItemMock.Setup(inst => inst.GetMetadata(It.Is(HintPath, StringComparer.InvariantCulture))).Returns(hintPath); - - taskItemMock.SetupGet(inst => inst.MetadataCount).Returns(1); - taskItemMock.SetupGet(inst => inst.MetadataNames).Returns(new string[] { HintPath }); - } - else - { - taskItemMock.Setup(inst => inst.GetMetadata(It.IsAny())).Returns(string.Empty); - - taskItemMock.SetupGet(inst => inst.MetadataCount).Returns(0); - taskItemMock.SetupGet(inst => inst.MetadataNames).Returns(Array.Empty()); - } - - return taskItemMock.Object; - } - - private static BuildContextStub GetBuildContext() - { - return new BuildContextStub(); - } - - private static TlbExport GetBuildTask(out BuildContextStub context, bool shouldSucceed = true) - { - context = GetBuildContext(); - context.ShouldSucceed = shouldSucceed; - var classUnderTest = new TlbExport(context) - { - BuildEngine = new BuildEngineStub() - }; - return classUnderTest; - } - - private static TlbEmbed GetEmbedTask(out BuildContextStub context, bool shouldSucceed = true) - { - context = GetBuildContext(); - context.ShouldSucceed = shouldSucceed; - var classUnderTest = new TlbEmbed(context) - { - BuildEngine = new BuildEngineStub() - }; - return classUnderTest; - } - - [Fact] - public void TestDefaultSettingsSuccessful() - { - var task = GetBuildTask(out _); - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestDefaultSettingsFailingOnNonWindows() - { - var task = GetBuildTask(out var context); - context.IsRunningOnWindows = false; - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeTrue(); - } - - [Fact] - public void TestDefaultSettingsFailsOnTransformationError() - { - var task = GetBuildTask(out _, false); - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestGuidIsEmpty() - { - var task = GetBuildTask(out _); - task.TlbOverriddenId = string.Empty; - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeTrue(); - } - - [Theory] - [InlineData("03bc128f-0e54-44f0-9c3e-3fa1ed1.ceeb1")] - [InlineData("03bc128g0e5444f09c3e3fa1ed1ceeb1")] - [InlineData("03bc128f-0e54-44f0-9c3e-3fa1ed1ceeb1-abcd")] - [InlineData("dcba-03bc128f-0e54-44f0-9c3e-3fa1ed1ceeb1")] - public void TestGuidIsMalformed(string malformedGuid) - { - var task = GetBuildTask(out _); - task.TlbOverriddenId = malformedGuid; - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeTrue(); - } - - [Theory] - [InlineData("03bc128f-0e54-44f0-9c3e-3fa1ed1ceeb1")] - [InlineData("03bc128f0e5444f09c3e3fa1ed1ceeb1")] - [InlineData("00000000-0000-0000-0000-000000000000")] - public void TestGuidIsCorrect(string guid) - { - var task = GetBuildTask(out _); - task.TlbOverriddenId = guid; - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestAssemblyFileCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestAssemblyFileCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath + ".notExisting"); - - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeTrue(); - } - - [Fact] - public void TestAssemblyFileReferencesItemSpecCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(filePath); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(0, "No warning should be present"); - } - - [Fact] - public void TestAssemblyFileReferencesItemSpecCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(filePath); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestAssemblyFileReferencesHintPathCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(fileName, filePath, true); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(0, "No warning should be present"); - } - - [Fact] - public void TestAssemblyFileReferencesHintPathCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(fileName, filePath, true); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestAssemblyFileReferencesHybridCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var arg = (i % 2 == 0) ? ((ValueTuple)(fileName, filePath)) : ((ValueTuple)(filePath, null)); - var (fn, fp) = arg; - var taskItem = GetTaskItem(fn, fp!, i % 2 == 0); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(0, "No warning should be present"); - } - - [Fact] - public void TestAssemblyFileReferencesHybridCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"ReferencedAssembly{i}.dll"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var arg = (i % 2 == 0) ? ((ValueTuple)(fileName, filePath)) : ((ValueTuple)(filePath, null)); - var (fn, fp) = arg; - var taskItem = GetTaskItem(fn, fp!, i % 2 == 0); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.AssemblyPaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencesItemSpecCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(filePath); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(0, "No warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencesItemSpecCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(filePath); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencesHintPathCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(fileName, filePath, true); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(5, "Five warnings should be present, since TLBs cannot be referenced using HintPath"); - } - - [Fact] - public void TestypeLibraryReferencesHintPathCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var taskItem = GetTaskItem(fileName, filePath, true); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestypeLibraryReferencesHybridCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var arg = (i % 2 == 0) ? ((ValueTuple)(fileName, filePath)) : ((ValueTuple)(filePath, null)); - var (fn, fp) = arg; - var taskItem = GetTaskItem(fn, fp!, i % 2 == 0); - taskItems.Add(taskItem); - context.ExistingFiles.Add(filePath); - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(2, "Five warnings should be present, since TLBs cannot be referenced using HintPath"); - } - - [Fact] - public void TestTypeLibraryReferencesHybridCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var fileName = $"TypeLibrary{i}.tlb"; - var filePath = Path.Combine(Path.GetTempPath(), fileName); - var arg = (i % 2 == 0) ? ((ValueTuple)(fileName, filePath)) : ((ValueTuple)(filePath, null)); - var (fn, fp) = arg; - var taskItem = GetTaskItem(fn, fp!, i % 2 == 0); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingFiles.Add(filePath); - } - } - - task.TypeLibraryReferences = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencePathsItemSpecCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var taskItem = GetTaskItem(dirPath); - taskItems.Add(taskItem); - context.ExistingDirectories.Add(dirPath); - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(0, "No warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencePathsItemSpecCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var taskItem = GetTaskItem(dirPath); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingDirectories.Add(dirPath); - } - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestTypeLibraryReferencePathsHintPathCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var taskItem = GetTaskItem(dirName, dirPath, true); - taskItems.Add(taskItem); - context.ExistingDirectories.Add(dirPath); - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(5, "Five warnings should be present, since TLBs cannot be referenced using HintPath"); - } - - [Fact] - public void TestypeLibraryReferencePathsHintPathCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var taskItem = GetTaskItem(dirName, dirPath, true); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingDirectories.Add(dirPath); - } - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestypeLibraryReferencePathsHybridCheckSuccess() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var arg = (i % 2 == 0) ? ((ValueTuple)(dirName, dirPath)) : ((ValueTuple)(dirPath, null)); - var (dn, dp) = arg; - var taskItem = GetTaskItem(dn, dp!, i % 2 == 0); - taskItems.Add(taskItem); - context.ExistingDirectories.Add(dirPath); - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().NumberOfWarningLogEvents.Should().Be(2, "Five warnings should be present, since TLBs cannot be referenced using HintPath"); - } - - [Fact] - public void TestTypeLibraryReferencePathsHybridCheckFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - var notFoundByRandom = new Random().Next(5) + 1; - - var taskItems = new List(); - for (var i = 1; i <= 5; i++) - { - var dirName = $"TypeLibrarySearchFolder{i}"; - var dirPath = Path.Combine(Path.GetTempPath(), dirName); - var arg = (i % 2 == 0) ? ((ValueTuple)(dirName, dirPath)) : ((ValueTuple)(dirPath, null)); - var (dn, dp) = arg; - var taskItem = GetTaskItem(dn, dp!, i % 2 == 0); - taskItems.Add(taskItem); - if (i != notFoundByRandom) - { - context.ExistingDirectories.Add(dirPath); - } - } - - task.TypeLibraryReferencePaths = taskItems.ToArray(); - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - task.BuildEngine.As().Should().NotBe(0, "At least one warning should be present"); - } - - [Fact] - public void TestBuildIsSuccessful() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - context.ShouldSucceed = true; - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestBuildIsSuccessFail() - { - var task = GetBuildTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - task.SourceAssemblyFile = assemblyFilePath; - context.ExistingFiles.Add(assemblyFilePath); - - context.ShouldSucceed = false; - - task.Execute().Should().BeFalse(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - - [Fact] - public void TestEmbedIsSuccessful() - { - var task = GetEmbedTask(out var context); - var assemblyFileName = "MyAssemblyFile.dll"; - var tlbFileName = "MyAssemblyFile.tlb"; - - var assemblyFilePath = Path.Combine(Path.GetTempPath(), assemblyFileName); - var tlbFilePath = Path.Combine(Path.GetTempPath(), tlbFileName); - task.TargetAssemblyFile = assemblyFilePath; - task.SourceTlbFile = tlbFilePath; - context.ExistingFiles.Add(assemblyFilePath); - context.ExistingFiles.Add(tlbFilePath); - - context.ShouldSucceed = true; - - task.Execute().Should().BeTrue(); - task.Log.HasLoggedErrors.Should().BeFalse(); - } - -} -