Skip to content

Commit

Permalink
Adding dotnet-svcutil (dotnet#4231)
Browse files Browse the repository at this point in the history
Adding dotnet-svcutil to the dotnet/wcf repository and open sourcing it.

Co-authored-by: Stephen Bonikowsky <stebon@microsoft.com>
Co-authored-by: Matt Connew <mconnew@microsoft.com>
  • Loading branch information
3 people authored May 7, 2020
1 parent 91b1b05 commit 42b5572
Show file tree
Hide file tree
Showing 1,697 changed files with 639,447 additions and 1 deletion.
35 changes: 35 additions & 0 deletions dotnet-svcutil.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28728.38
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-svcutil-lib", "src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj", "{C4975980-74BF-4F85-81E4-A45115A28150}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-svcutil", "src\dotnet-svcutil\src\dotnet-svcutil.csproj", "{E4006BB6-E8C1-44AA-B7BE-16D1CEB05EDE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4006BB6-E8C1-44AA-B7BE-16D1CEB05EDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E4006BB6-E8C1-44AA-B7BE-16D1CEB05EDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4006BB6-E8C1-44AA-B7BE-16D1CEB05EDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4006BB6-E8C1-44AA-B7BE-16D1CEB05EDE}.Release|Any CPU.Build.0 = Release|Any CPU
{C4975980-74BF-4F85-81E4-A45115A28150}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4975980-74BF-4F85-81E4-A45115A28150}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4975980-74BF-4F85-81E4-A45115A28150}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4975980-74BF-4F85-81E4-A45115A28150}.Release|Any CPU.Build.0 = Release|Any CPU
{FE6BA252-6D80-4A08-9DC8-C6E065F320C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE6BA252-6D80-4A08-9DC8-C6E065F320C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE6BA252-6D80-4A08-9DC8-C6E065F320C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE6BA252-6D80-4A08-9DC8-C6E065F320C7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D844EF31-9453-42C0-B4C2-73171D972180}
EndGlobalSection
EndGlobal
3 changes: 2 additions & 1 deletion eng/FacadeAssemblies.targets
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
</ItemGroup>
</Target>

<PropertyGroup>
<!-- This property will break if we're packing a global tool, so skip it in that case. -->
<PropertyGroup Condition="'$(PackAsTool)' != 'true'">
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificBuildOutput);AddReferenceAssemblyToPackage</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

Expand Down
7 changes: 7 additions & 0 deletions eng/Signing.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<ItemGroup>
<!-- This is a third party library that is included in dotnet-svcutil.
We need to sign it with a 3rd party certificate even if it's already signed. -->
<FileSignInfo Include="Newtonsoft.Json.dll" CertificateName="3PartySHA2" />
</ItemGroup>
</Project>
14 changes: 14 additions & 0 deletions src/dotnet-svcutil/build.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@echo off

setlocal

pushd %~dp0\..\..\

:buildsln
set buildtool=eng\common\cibuild.cmd -preparemachine -configuration Release -projects dotnet-svcutil.sln /p:Test=false /p:Sign=false
echo %buildtool%
call %buildtool%

:End
popd
endlocal
228 changes: 228 additions & 0 deletions src/dotnet-svcutil/lib/src/AppInsightsTelemetryClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Tools.ServiceModel.Svcutil
{
// Provides the TelemetryClient instance for logging telemetry using AppInsights.
internal class AppInsightsTelemetryClient
{
private const string instrumentationKey = "97d0a8a2-1954-4c71-b95d-89df9627dccb";
internal const string OptOutVariable = "DOTNET_SVCUTIL_TELEMETRY_OPTOUT";
private const string eventNamePrefix = "VS/dotnetSvcutil/";
private const string testModeVariable = "DOTNET_SVCUTIL_TEST_MODE";

private static bool? s_isUserOptedIn = null;
public static bool IsUserOptedIn
{
get
{
if (!s_isUserOptedIn.HasValue)
{
string optOut = Environment.GetEnvironmentVariable(OptOutVariable);
if (string.IsNullOrEmpty(optOut))
{
s_isUserOptedIn = true;
}
else
{
// We parse the same values here as the dotnet SDK's opt out.
switch (optOut.ToLowerInvariant())
{
case "true":
case "1":
case "yes":
s_isUserOptedIn = false;
break;
case "false":
case "0":
case "no":
default:
s_isUserOptedIn = true;
break;
}
}
}

return s_isUserOptedIn.Value;
}
set
{
s_isUserOptedIn = value;
}
}

private static readonly object s_lockObj = new object();
private static AppInsightsTelemetryClient s_instance = null;
private TelemetryClient _telemetryClient = null;

private AppInsightsTelemetryClient(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}

public static async Task<AppInsightsTelemetryClient> GetInstanceAsync(CancellationToken cancellationToken)
{
if (s_instance == null)
{
try
{
if (!bool.TryParse(Environment.GetEnvironmentVariable(testModeVariable), out bool testMode))
{
testMode = false;
}

lock (s_lockObj)
{
if (s_instance == null)
{
if (!IsUserOptedIn)
{
// If the user hasn't opted in return now with a null telemetry client to ensure we don't create any telemetry context.
return new AppInsightsTelemetryClient(null);
}

TelemetryConfiguration config;
try
{
config = TelemetryConfiguration.Active;
}
catch (InvalidOperationException)
{
config = new TelemetryConfiguration();
}

config.TelemetryChannel.DeveloperMode = testMode;

s_instance = new AppInsightsTelemetryClient(new TelemetryClient(config));
}
}

var telemetryClient = s_instance._telemetryClient;
telemetryClient.InstrumentationKey = instrumentationKey;

// Populate context with properties that are common and should be logged for all events.
var context = telemetryClient.Context;
context.Device.OperatingSystem = GetOperatingSystemString();

#if !NETCORE10
// Set the user id to a stable hash of the user's current username. Users with the same username
// or those with hash collisions will show up as the same id. So the user id won't be perfectly unique.
// However, it will give us some idea of how many different users are using the tool.
context.User.Id = GetStableHashCode(Environment.UserName).ToString();
#endif

// DebugLogger tracks telemetry when adding exceptions. We pass null for the logger to avoid the possibility of an endless cyclic call if something goes wrong in GetSdkVersionAsync.
var sdkVersion = await ProjectPropertyResolver.GetSdkVersionAsync(System.IO.Directory.GetCurrentDirectory(), null /* logger */, cancellationToken).ConfigureAwait(false);
context.Properties["SvcUtil.Version"] = Tool.PackageVersion;
context.Properties["Dotnet.Version"] = string.IsNullOrEmpty(sdkVersion) ? "unknown" : sdkVersion;
context.Properties["TestMode"] = testMode.ToString();
}
catch (Exception ex)
{
#if DEBUG
ToolConsole.WriteWarning(ex.Message);
#endif
s_isUserOptedIn = false;
}
}

return s_instance;
}

// This is copied from the 32 bit implementation from String.GetHashCode.
// It's a stable string hashing algorithm so it won't change with each run of the tool.
private static int GetStableHashCode(string str)
{
unsafe
{
fixed (char* src = str)
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;

int* pint = (int*)src;
int len = str.Length;
while (len > 2)
{
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1];
pint += 2;
len -= 4;
}

if (len > 0)
{
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
}

return hash1 + (hash2 * 1566083941);
}
}
}

private static string GetOperatingSystemString()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return "Windows";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return "macOS";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return "Linux";
}
else
{
return "Unknown";
}
}

public void TrackEvent(string eventName)
{
if (IsUserOptedIn)
{
_telemetryClient.TrackEvent(eventNamePrefix + eventName);
_telemetryClient.Flush();
}
}

public void TrackEvent(string eventName, Dictionary<string, string> properties)
{
if (IsUserOptedIn)
{
_telemetryClient.TrackEvent(eventNamePrefix + eventName, properties);
_telemetryClient.Flush();
}
}

public void TrackError(string eventName, Exception exceptionObject)
{
this.TrackError(eventName, exceptionObject.ToString());
}

public void TrackError(string eventName, string exceptionString)
{
if (IsUserOptedIn)
{
var properties = new Dictionary<string, string>();
properties.Add("ExceptionString", exceptionString);

_telemetryClient.TrackEvent(eventNamePrefix + eventName, properties);
_telemetryClient.Flush();
}
}
}
}
24 changes: 24 additions & 0 deletions src/dotnet-svcutil/lib/src/AppSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.Tools.ServiceModel.Svcutil
{
using System;
internal static class AppSettings
{
internal static bool EnableSoapEncoding = false;
internal static bool EnableMessageHeader = false;

internal static void Initialize(FrameworkInfo frameworkInfo)
{
// NOTE: this method assumes the passed in FrameworkInfo has been validated.

if (!frameworkInfo.IsDnx || frameworkInfo.Version >= new Version("2.0"))
{
EnableSoapEncoding = true;
EnableMessageHeader = true;
}
}
}
}
18 changes: 18 additions & 0 deletions src/dotnet-svcutil/lib/src/Bootstrapper/BootstrapException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microsoft.Tools.ServiceModel.Svcutil
{
internal class BootstrapException : Exception
{
public int ExitCode { get; private set; } = (int)ToolExitCode.BootstrapError;

public BootstrapException(string message) : base(message) { }
}
}
Loading

0 comments on commit 42b5572

Please sign in to comment.