From 90240d01fd130274bea83d60024ec4c5e6f950c6 Mon Sep 17 00:00:00 2001 From: Carol Wang Date: Wed, 27 Mar 2024 12:59:56 +0800 Subject: [PATCH] Multi target type reuse (#5300) * Support referenced assembly type reuse for multi-target project * Resolve reabse conflict. * rebase and fix test issue. * Apply workaround for reusing WindowsAppSDK pkg types in maui 7.0-xxx project * Rebase and resolve conflicts. --- .../src/Bootstrapper/SvcutilBootstrapper.cs | 25 ++- .../WcfCodeGenerationExtension.cs | 2 +- .../lib/src/Shared/FrameworkInfo.cs | 21 ++- .../lib/src/Shared/MSBuildProj.cs | 31 ++-- .../lib/src/Shared/TargetFrameworkHelper.cs | 11 -- .../ServiceReference/Reference.cs | 168 ++++++++++++++++++ .../dotnet-svcutil.params.json | 18 ++ .../TypeReuseClient/TypeReuseClient.csproj | 20 +++ .../MultiTargetTypeReuse/BinLib/BinLib.dll | Bin 0 -> 4096 bytes .../TypeReuseClient/Program.cs | 12 ++ .../TypeReuseClient/TypeReuseClient.csproj | 12 ++ .../tests/TestCases/wsdl/TypeReuseSvc.wsdl | 143 +++++++++++++++ src/dotnet-svcutil/lib/tests/src/FixupUtil.cs | 2 +- .../lib/tests/src/GlobalToolTests.cs | 30 ++++ 14 files changed, 448 insertions(+), 47 deletions(-) create mode 100644 src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/Reference.cs create mode 100644 src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/dotnet-svcutil.params.json create mode 100644 src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/TypeReuseClient.csproj create mode 100644 src/dotnet-svcutil/lib/tests/TestCases/MultiTargetTypeReuse/BinLib/BinLib.dll create mode 100644 src/dotnet-svcutil/lib/tests/TestCases/MultiTargetTypeReuse/TypeReuseClient/Program.cs create mode 100644 src/dotnet-svcutil/lib/tests/TestCases/MultiTargetTypeReuse/TypeReuseClient/TypeReuseClient.csproj create mode 100644 src/dotnet-svcutil/lib/tests/TestCases/wsdl/TypeReuseSvc.wsdl diff --git a/src/dotnet-svcutil/lib/src/Bootstrapper/SvcutilBootstrapper.cs b/src/dotnet-svcutil/lib/src/Bootstrapper/SvcutilBootstrapper.cs index e09a24b4289..49add0d7ae0 100644 --- a/src/dotnet-svcutil/lib/src/Bootstrapper/SvcutilBootstrapper.cs +++ b/src/dotnet-svcutil/lib/src/Bootstrapper/SvcutilBootstrapper.cs @@ -123,22 +123,17 @@ internal async Task GenerateProjectAsync(bool keepBootstrapperDir, ILogger logge this.MSBuildProj = await MSBuildProj.DotNetNewAsync(projectFullPath, logger, cancellationToken).ConfigureAwait(false); this.MSBuildProj.AddDependency(svcutilPkgRef, true); - // Comment out code below for reasons: 1. it never used for .net core later than V2.1 since when the approach is always use TF from the generated project. - // 2. with below code applied when target framework is netstandard2.0 client machine require netcoreapp2.0 (obsolete) for bootstrapper to work - // 3. keep it here for future reference in case when we need definite bootstrapper TF version - - // NOTE: If post v2.0 NetStandard ships a different version from NetCore the table below needs to be updated! - //var targetFramework = frameworkInfo.FullName; - //if (isSupportedTFM && frameworkInfo.IsKnownDnx) - //{ - // if (frameworkInfo.Name == FrameworkInfo.Netstandard) - // { - // targetFramework = FrameworkInfo.Netcoreapp + TargetFrameworkHelper.NetStandardToNetCoreVersionMap[frameworkInfo.Version]; - // } - // this.MSBuildProj.TargetFramework = targetFramework; - //} + var targetFramework = frameworkInfo.FullName; + if (isSupportedTFM && frameworkInfo.Name != FrameworkInfo.Netstandard && frameworkInfo.Version.CompareTo(new Version(6, 0)) >= 0) + { + this.MSBuildProj.TargetFramework = targetFramework; + if(targetFramework.ToLowerInvariant().Contains("net7.0-windows10")) + { + this.MSBuildProj.SetEnableMsixTooling(); + } + } // else - // The TFM is unknown: either, it was not provided or it is a version not yet known to the tool, + // The TFM is Netstandard or version lower than 6.0 or unknown: either, it was not provided or it is a version not yet known to the tool, // we will use the default TF from the generated project. } diff --git a/src/dotnet-svcutil/lib/src/CodeDomFixup/WcfCodeGenerationExtension.cs b/src/dotnet-svcutil/lib/src/CodeDomFixup/WcfCodeGenerationExtension.cs index ee3d9aa0cc9..44fcad88acf 100644 --- a/src/dotnet-svcutil/lib/src/CodeDomFixup/WcfCodeGenerationExtension.cs +++ b/src/dotnet-svcutil/lib/src/CodeDomFixup/WcfCodeGenerationExtension.cs @@ -62,7 +62,7 @@ public void WsdlImported(WsdlImporter importer, Collection endp foreach (var binding in bindings) { - if (binding is NetNamedPipeBinding && _options.Project != null && !_options.Project.TargetFrameworks.FirstOrDefault().ToLower().Contains("windows")) + if (binding is NetNamedPipeBinding && _options.Project != null && !_options.Project.TargetFrameworks.Any(t => t.ToLower().Contains("windows"))) { MetadataConversionError error = new MetadataConversionError(SR.WrnTargetFrameworkNotSupported_NetNamedPipe, isWarning: true); if (!importer.Errors.Contains(error)) diff --git a/src/dotnet-svcutil/lib/src/Shared/FrameworkInfo.cs b/src/dotnet-svcutil/lib/src/Shared/FrameworkInfo.cs index e1ec0bb0dfe..cbba8c2ffe4 100644 --- a/src/dotnet-svcutil/lib/src/Shared/FrameworkInfo.cs +++ b/src/dotnet-svcutil/lib/src/Shared/FrameworkInfo.cs @@ -40,6 +40,7 @@ public static FrameworkInfo Parse(string fullFrameworkName) // framework spec form: 'net5.0' // framework spec form: '.NETCoreApp,Version=v6.0' // framework spec form: '.NETFramework,Version=v4.8' + // framework spec form: 'net7.0-windows10.0.19041.0', 'net7.0-windows' for (int i = 0; i < fullFrameworkName.Length; i++) { char c = fullFrameworkName[i]; @@ -49,17 +50,25 @@ public static FrameworkInfo Parse(string fullFrameworkName) // Version ctr requires at least Major and Minor parts string versionString = fullFrameworkName.Substring(i); - if ((name == Netfx) && !versionString.Contains(".")) + if ((name == Netfx)) { // net452 - StringBuilder sb = new StringBuilder(versionString); - for (int j = 1; j < sb.Length; j += 2) + if(!versionString.Contains(".")) { - sb.Insert(j, '.'); + StringBuilder sb = new StringBuilder(versionString); + for (int j = 1; j < sb.Length; j += 2) + { + sb.Insert(j, '.'); + } + versionString = sb.ToString(); } - versionString = sb.ToString(); + // net7.0-windows10.0.19041.0 + if (versionString.Contains("-")) + { + versionString = versionString.Substring(0, versionString.IndexOf("-")); + } } - + version = new Version(versionString); break; } diff --git a/src/dotnet-svcutil/lib/src/Shared/MSBuildProj.cs b/src/dotnet-svcutil/lib/src/Shared/MSBuildProj.cs index 2dd33e44e8a..ad8f1ef6047 100644 --- a/src/dotnet-svcutil/lib/src/Shared/MSBuildProj.cs +++ b/src/dotnet-svcutil/lib/src/Shared/MSBuildProj.cs @@ -221,14 +221,9 @@ public static async Task ParseAsync(string projectText, string proj if (targetFrameworksElements.Count() > 0) { var targetFrameworks = targetFrameworksElements.Last().Value; - if (targetFrameworks.ToString().StartsWith("$")) - { - targetFrameworks = GetValueFromDirBuildProps(targetFrameworks, msbuildProj.DirectoryPath); - } - foreach (var targetFx in targetFrameworks.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim())) { - if (!string.IsNullOrWhiteSpace(targetFx)) + if (!string.IsNullOrEmpty(targetFx) && !targetFx.ToString().StartsWith("$")) { msbuildProj._targetFrameworks.Add(targetFx); } @@ -591,6 +586,14 @@ public bool AddDependency(ProjectDependency dependency, bool copyInternalAssets return addDependency; } + public void SetEnableMsixTooling() + { + // workaround for https://github.com/microsoft/WindowsAppSDK/issues/3548: dotnet build fails when WindowsAppSDK is referenced in console application. + // affects MAUI project targeting net7.0-windows10.0xxx, not reproduce in net8.0-window10.0xxx + // ref: https://github.com/dotnet/maui/issues/5886 + SetPropertyValue("EnableMsixTooling", "true"); + } + // Sets the property value in a PropertyGroup. Returns true if the value was changed, and false if it was already set to that value. private bool SetPropertyValue(string propertyName, string value) { @@ -759,7 +762,7 @@ public async Task> ResolveProjectReferencesAsync( using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, "Resolving project references ...").ConfigureAwait(false)) { - if (_targetFrameworks.Count == 1 && TargetFrameworkHelper.IsSupportedFramework(this.TargetFramework, out var frameworkInfo) && frameworkInfo.IsDnx) + if (_targetFrameworks.Count >= 1 && TargetFrameworkHelper.IsSupportedFramework(this.TargetFramework, out var frameworkInfo) && frameworkInfo.IsDnx) { await this.RestoreAsync(logger, cancellationToken).ConfigureAwait(false); @@ -794,15 +797,17 @@ await AsyncHelper.RunAsync(async () => try { var assetsFile = new FileInfo(Path.Combine(this.DirectoryPath, "obj", "project.assets.json")).FullName; - if (File.Exists(assetsFile)) + if (File.Exists(assetsFile) && !(this.TargetFramework.Contains("-") && !this.TargetFramework.ToLower().Contains("windows"))) { LockFile lockFile = LockFileUtilities.GetLockFile(assetsFile, logger as NuGet.Common.ILogger); - if (lockFile != null) { - if (lockFile.Targets.Count == 1) + LockFileTarget target = lockFile.Targets.Count == 1 ? lockFile.Targets[0] : lockFile.Targets.FirstOrDefault(t => + t.Name.StartsWith(this.TargetFramework, StringComparison.InvariantCultureIgnoreCase) //this.TargetFramework:net7.0-windows, targets:net7.0-windows7.0 + || this.TargetFramework.StartsWith(t.Name, StringComparison.InvariantCultureIgnoreCase));//this.TargetFramework:net7.0-windows10.0.19041.0, targets:net7.0-windows10.0.19041 + if (target != null) { - foreach (var lib in lockFile.Targets[0].Libraries) + foreach (var lib in target.Libraries) { bool isPackage = StringComparer.OrdinalIgnoreCase.Compare(lib.Type, "package") == 0; @@ -970,7 +975,7 @@ public async Task>> ResolveProperyValue if (propertyTable.Count() != propertyNames.Count()) { - propertyTable = await _propertyResolver.EvaluateProjectPropertiesAsync(this.FullPath, this.TargetFrameworks.FirstOrDefault(), propertyNames, this.GlobalProperties, logger, cancellationToken).ConfigureAwait(false); + propertyTable = await _propertyResolver.EvaluateProjectPropertiesAsync(this.FullPath, this.TargetFramework, propertyNames, this.GlobalProperties, logger, cancellationToken).ConfigureAwait(false); foreach (var entry in propertyTable) { @@ -1000,7 +1005,7 @@ private async Task ResolveDepsFilePathFromBuildConfigAsync(string output { var depsFiles = Directory.GetFiles(binFolder, "*", SearchOption.AllDirectories) .Where(d => Path.GetFileName(d).Equals(fileName, RuntimeEnvironmentHelper.FileStringComparison)) - .Where(f => PathHelper.GetFolderName(Path.GetDirectoryName(f)) == this.TargetFrameworks.FirstOrDefault()) + .Where(f => PathHelper.GetFolderName(Path.GetDirectoryName(f)) == this.TargetFramework || Directory.GetParent(Directory.GetParent(f).FullName).Name == this.TargetFramework) .Select(f => new FileInfo(f)) .OrderByDescending(f => f.CreationTimeUtc); diff --git a/src/dotnet-svcutil/lib/src/Shared/TargetFrameworkHelper.cs b/src/dotnet-svcutil/lib/src/Shared/TargetFrameworkHelper.cs index 7649d96f6ec..d3aeb1ba44a 100644 --- a/src/dotnet-svcutil/lib/src/Shared/TargetFrameworkHelper.cs +++ b/src/dotnet-svcutil/lib/src/Shared/TargetFrameworkHelper.cs @@ -150,11 +150,6 @@ public static string GetBestFitTargetFramework(IEnumerable targetFramewo } } - if (fxInfo != null) - { - return fxInfo.FullName; - } - return targetFramework; } @@ -212,12 +207,6 @@ public static bool IsSupportedFramework(string fullFrameworkName, out FrameworkI { bool isSupported = false; - var tfx = fullFrameworkName.Split('-'); - if (tfx.Length > 1) - { - fullFrameworkName = tfx[0]; - } - if (FrameworkInfo.TryParse(fullFrameworkName, out frameworkInfo)) { isSupported = (frameworkInfo.Name == FrameworkInfo.Netstandard && frameworkInfo.Version >= MinSupportedNetStandardVersion) || diff --git a/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/Reference.cs b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/Reference.cs new file mode 100644 index 00000000000..5d52a31783f --- /dev/null +++ b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/Reference.cs @@ -0,0 +1,168 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ServiceReference +{ + using System.Runtime.Serialization; + + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")] + [System.Runtime.Serialization.DataContractAttribute(Name="TypeReuseCompositeType", Namespace="http://schemas.datacontract.org/2004/07/TypesLib")] + public partial class TypeReuseCompositeType : object + { + + private bool BoolValueField; + + private string StringValueField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public bool BoolValue + { + get + { + return this.BoolValueField; + } + set + { + this.BoolValueField = value; + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public string StringValue + { + get + { + return this.StringValueField; + } + set + { + this.StringValueField = value; + } + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")] + [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference.ITypeReuseSvc")] + public interface ITypeReuseSvc + { + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITypeReuseSvc/GetData", ReplyAction="http://tempuri.org/ITypeReuseSvc/GetDataResponse")] + System.Threading.Tasks.Task GetDataAsync(int value); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITypeReuseSvc/GetDataUsingDataContract", ReplyAction="http://tempuri.org/ITypeReuseSvc/GetDataUsingDataContractResponse")] + System.Threading.Tasks.Task GetDataUsingDataContractAsync(ServiceReference.TypeReuseCompositeType composite); + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")] + public interface ITypeReuseSvcChannel : ServiceReference.ITypeReuseSvc, System.ServiceModel.IClientChannel + { + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")] + public partial class TypeReuseSvcClient : System.ServiceModel.ClientBase, ServiceReference.ITypeReuseSvc + { + + /// + /// Implement this partial method to configure the service endpoint. + /// + /// The endpoint to configure + /// The client credentials + static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials); + + public TypeReuseSvcClient() : + base(TypeReuseSvcClient.GetDefaultBinding(), TypeReuseSvcClient.GetDefaultEndpointAddress()) + { + this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_ITypeReuseSvc.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public TypeReuseSvcClient(EndpointConfiguration endpointConfiguration) : + base(TypeReuseSvcClient.GetBindingForEndpoint(endpointConfiguration), TypeReuseSvcClient.GetEndpointAddress(endpointConfiguration)) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public TypeReuseSvcClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : + base(TypeReuseSvcClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress)) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public TypeReuseSvcClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : + base(TypeReuseSvcClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress) + { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public TypeReuseSvcClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) + { + } + + public System.Threading.Tasks.Task GetDataAsync(int value) + { + return base.Channel.GetDataAsync(value); + } + + public System.Threading.Tasks.Task GetDataUsingDataContractAsync(ServiceReference.TypeReuseCompositeType composite) + { + return base.Channel.GetDataUsingDataContractAsync(composite); + } + + public virtual System.Threading.Tasks.Task OpenAsync() + { + return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action(((System.ServiceModel.ICommunicationObject)(this)).EndOpen)); + } + + private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration) + { + if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ITypeReuseSvc)) + { + System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding(); + result.MaxBufferSize = int.MaxValue; + result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max; + result.MaxReceivedMessageSize = int.MaxValue; + result.AllowCookies = true; + return result; + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration) + { + if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_ITypeReuseSvc)) + { + return new System.ServiceModel.EndpointAddress("http://localhost:51074/TypeReuseSvc.svc"); + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.Channels.Binding GetDefaultBinding() + { + return TypeReuseSvcClient.GetBindingForEndpoint(EndpointConfiguration.BasicHttpBinding_ITypeReuseSvc); + } + + private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress() + { + return TypeReuseSvcClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_ITypeReuseSvc); + } + + public enum EndpointConfiguration + { + + BasicHttpBinding_ITypeReuseSvc, + } + } +} \ No newline at end of file diff --git a/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/dotnet-svcutil.params.json b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/dotnet-svcutil.params.json new file mode 100644 index 00000000000..db493e18ee4 --- /dev/null +++ b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/ServiceReference/dotnet-svcutil.params.json @@ -0,0 +1,18 @@ +{ + "providerId": "Microsoft.Tools.ServiceModel.Svcutil", + "version": "99.99.99", + "options": { + "inputs": [ + "$testCasesPath$/wsdl/TypeReuseSvc.wsdl" + ], + "namespaceMappings": [ + "*, ServiceReference" + ], + "outputFile": "Reference.cs", + "references": [ + "$TEMP$MultiTargetTypeReuse//TypeReuseClient//bin//Debug//net6.0//BinLib.dll" + ], + "targetFramework": "N.N", + "typeReuseMode": "All" + } +} \ No newline at end of file diff --git a/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/TypeReuseClient.csproj b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/TypeReuseClient.csproj new file mode 100644 index 00000000000..57fd002c016 --- /dev/null +++ b/src/dotnet-svcutil/lib/tests/Baselines/MultiTargetTypeReuse/TypeReuseClient/TypeReuseClient.csproj @@ -0,0 +1,20 @@ + + + + Exe + net6.0;net7.0 + + + + ../BinLib/BinLib.dll + + + + + + + + + + + \ No newline at end of file diff --git a/src/dotnet-svcutil/lib/tests/TestCases/MultiTargetTypeReuse/BinLib/BinLib.dll b/src/dotnet-svcutil/lib/tests/TestCases/MultiTargetTypeReuse/BinLib/BinLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..e03abb10acb4f492f9fbdba34d33ac72a8857738 GIT binary patch literal 4096 zcmd^CU2GIp6h3#`ZcBmE1|bkk9cTqCy0)}bkstfB1uFfcyA*^b?d*L1^SIatf z+R-ywQnxJI(-Km1a+YRTT68d`W$cuUEMH#T7=#|`A?g!lv^&>!zOdSlv_V@cnu)3) z3H#DZn=oq_9T-HliVpdCvw-tga26PHhB6vI$EN&OoCB6cfF8shWTFGhaU&MOIMFi5 zvKxuw3w4j;H9!4=Nfr2g1qO4(lhYpN%auSH2G<(o4N8GVG#+tWCkamF)&YVGt;Q&U z4rCv3q-n#DbER<%j#YzE0v$wMC9ERz+*bhS7NQC=H7tRi3l{zds1KcnYkAX#P}ysW z*cjTpLS@`UU9nfXL=c(toN9|SM_QX(TekB;SQ~g5@@_aoG>!QJ(=pF6thCD(RTX~u z4F_Yi3^YI1hP?-SqnMure~atkE%ze>HtNps_e4WaKA34{G992A~ zdB9iAOcVVj{5ecJ#9$~)A1FLQJ3}kThH02)=#B`}+oBQLDuur!rhiuWgpyoT^ifd> z`I!&_?RU2iimI$+ES;)$|N-Eww1TUExlJdlf#Q@T&^zz+pO}@aw><=q*JX3Tu?4 z?`VC1C+P=7b|Hz-QhFYECA|o|jt&7gU}HvT3w;FKN>_k)(C5J2bQ5^LlE;8MRJ3k7 ziZ~%uMD(rLqNp-(A-vb+XA2#IQUSjbs&N6ojy4Arrk(wEDrd^w)MZ$GMuK*Z=w?pt zo*WzN(vy?eUV98_rpS_>>*-cXcTyCUiCj7@oi4{d>FNnn#ys7V)NN<7hAExB(vl7Y zsZJ03Gm(SJ_h8e7vXUr8Rj2F9Ov22^4X@NAt~+Vz?ZNj`p0u6G#rAu!{D^d1!?qSH zd#wrE$><)Gy7^G6ZrhqL(mCWmFGy7P^nT{zl?m?aIgR4pPGI>al7#{m1{y&m1!g@K-ASSTcgNb zRX0zsoW1qj-2$Ko&jvqeukShkCYhD~l%!B(Ezy6y<{}8{gM=);SY`wwfUjS^r5`&MXdZ2ps z0S}az)Nx*9X*d>*C426CmAgK(@6ucET)X>j(-$10=cUnjJ}ZZ1&XpyUpZ=(wI6kVf zA1!(BQQ@esk7QE`itX#%x~-jp;O7g$QNZ*c`@YYf`}4P{+D{L@mkAD0&go62HKrCr z;jr~JW8JnBHO+qAuqfjuZAVJAT?4<_rx9jhsf%O&uM$3Mh}ICDogdaewee^d$=QzY z4u?C4W=cN5Gody}M<_;Pz&$h!suwq{0r0)Rd;D7$eOCVaKcy#a;k*7ayczhqQxaCm z_`Da0s*{5_2JQ_KF)f-PTj?8>R~%X$QWtuiJlNUbeE6iC?->F)d9X4dPd^~iJ!~RD z&2zstN`S`QjVdAUM!XDV)f#zJq=Su5nH&2xjO9cQjko$!>cg`CWi%u3@&C + + + Exe + net6.0;net7.0 + + + + ..\BinLib\BinLib.dll + + + \ No newline at end of file diff --git a/src/dotnet-svcutil/lib/tests/TestCases/wsdl/TypeReuseSvc.wsdl b/src/dotnet-svcutil/lib/tests/TestCases/wsdl/TypeReuseSvc.wsdl new file mode 100644 index 00000000000..9753c6dbd31 --- /dev/null +++ b/src/dotnet-svcutil/lib/tests/TestCases/wsdl/TypeReuseSvc.wsdl @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/dotnet-svcutil/lib/tests/src/FixupUtil.cs b/src/dotnet-svcutil/lib/tests/src/FixupUtil.cs index 0884996051b..8c49bb06ed4 100644 --- a/src/dotnet-svcutil/lib/tests/src/FixupUtil.cs +++ b/src/dotnet-svcutil/lib/tests/src/FixupUtil.cs @@ -46,7 +46,7 @@ public void Init(string resultsPath, string testCasesPath, string projectPath, s new ReplaceInfo(@"targetFramework:\[netcoreapp\d+\.\d+\]", "targetFramework:[N.N]") { UseRegex = true }, new ReplaceInfo(@"""targetFramework"": ""netcoreapp\d+\.\d+""", "\"targetFramework\": \"N.N\"") { UseRegex = true }, //new new ReplaceInfo(@"netcoreapp\d+\.\d+", "N.N") { UseRegex = true }, //new - new ReplaceInfo(@"""targetFramework"": ""net\d+\.\d+""", "\"targetFramework\": \"N.N\"") { UseRegex = true }, //new + new ReplaceInfo(@"""targetFramework"": ""net\d+\.\d+(-?)\w*""", "\"targetFramework\": \"N.N\"") { UseRegex = true }, //new new ReplaceInfo(@"net\d+\.\d+", "N.N") { UseRegex = true }, //new new ReplaceInfo(@"", @"") { UseRegex = true } //new }; diff --git a/src/dotnet-svcutil/lib/tests/src/GlobalToolTests.cs b/src/dotnet-svcutil/lib/tests/src/GlobalToolTests.cs index 0f618e4eaf2..1ab8ac3b30d 100644 --- a/src/dotnet-svcutil/lib/tests/src/GlobalToolTests.cs +++ b/src/dotnet-svcutil/lib/tests/src/GlobalToolTests.cs @@ -138,6 +138,36 @@ public async Task MultiTargetCloseAsyncGenerationAsync(string testCaseName) TestGlobalSvcutil(options, expectSuccess: true); } + [Trait("Category", "BVT")] + [Fact] + public async Task MultiTargetTypeReuse() + { + this_TestCaseName = "MultiTargetTypeReuse"; + TestFixture(); + string testClientFolder = "TypeReuseClient"; + this_TestCaseBaselinesDir = Path.Combine(this_TestGroupBaselinesDir, testClientFolder); + Directory.CreateDirectory(this_TestCaseBaselinesDir); + + this_TestGroupOutputDir = Path.Combine(Path.GetTempPath(), this_TestCaseName); + this_TestCaseLogFile = Path.Combine(this_TestGroupOutputDir, $"{this_TestCaseName}.log"); + this_TestCaseOutputDir = Path.Combine(this_TestGroupOutputDir, testClientFolder); + FileUtil.TryDeleteDirectory(this_TestCaseOutputDir); + Directory.CreateDirectory(this_TestCaseOutputDir); + FileUtil.CopyDirectory(Path.Combine(g_TestCasesDir, this_TestCaseName), this_TestGroupOutputDir, true); + this_TestCaseProject = await MSBuildProj.FromPathAsync(Path.Combine(this_TestCaseOutputDir, $"{testClientFolder}.csproj"), null, CancellationToken.None); + ProcessRunner.ProcessResult ret = await this_TestCaseProject.BuildAsync(true, this_TestCaseLogger, CancellationToken.None); + Assert.True(ret.ExitCode == 0, ret.OutputText); + + this_FixupUtil = new FixupUtil(); + this_FixupUtil.Init(g_TestResultsDir, g_TestCasesDir, this_TestCaseOutputDir, g_ServiceUrl, g_ServiceId, g_RepositoryRoot); + + var uri = Path.Combine(g_TestCasesDir, "wsdl", "TypeReuseSvc.wsdl"); + var outDir = Path.Combine(this_TestCaseOutputDir, "ServiceReference"); + var options = $"{uri} -nl --outputDir {outDir}"; + + TestGlobalSvcutil(options, expectSuccess: true); + } + [Trait("Category", "BVT")] [Theory] [InlineData("net6.0", "-elm")]