diff --git a/DotNetTry.sln b/DotNetTry.sln index 90abc5ec4..12b95a721 100644 --- a/DotNetTry.sln +++ b/DotNetTry.sln @@ -65,6 +65,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Interactiv EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XPlot.DotNet.Interactive.KernelExtensions", "XPlot.DotNet.Interactive.KernelExtensions\XPlot.DotNet.Interactive.KernelExtensions.csproj", "{90A9DF5F-CBEE-4B6B-8B58-BA94B0BDCF3C}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Microsoft.DotNet.Interactive.FSharp", "Microsoft.DotNet.Interactive.FSharp\Microsoft.DotNet.Interactive.FSharp.fsproj", "{12821999-9F44-486B-8EE3-38F0EFDFDA32}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -187,6 +189,10 @@ Global {90A9DF5F-CBEE-4B6B-8B58-BA94B0BDCF3C}.Debug|Any CPU.Build.0 = Debug|Any CPU {90A9DF5F-CBEE-4B6B-8B58-BA94B0BDCF3C}.Release|Any CPU.ActiveCfg = Release|Any CPU {90A9DF5F-CBEE-4B6B-8B58-BA94B0BDCF3C}.Release|Any CPU.Build.0 = Release|Any CPU + {12821999-9F44-486B-8EE3-38F0EFDFDA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12821999-9F44-486B-8EE3-38F0EFDFDA32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12821999-9F44-486B-8EE3-38F0EFDFDA32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12821999-9F44-486B-8EE3-38F0EFDFDA32}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -221,6 +227,7 @@ Global {113A4166-5734-4F6E-B609-D6CF42679399} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2} {2BB7CCD7-73D1-4B16-82EC-A5D0183F8CF5} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2} {90A9DF5F-CBEE-4B6B-8B58-BA94B0BDCF3C} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2} + {12821999-9F44-486B-8EE3-38F0EFDFDA32} = {6EE8F484-DFA2-4F0F-939F-400CE78DFAC2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D6CD99BA-B16B-4570-8910-225CBDFFA3AD} diff --git a/MLS.Agent.Tests/CommandLine/PackCommandTests.cs b/MLS.Agent.Tests/CommandLine/PackCommandTests.cs index 4522e61cf..685050907 100644 --- a/MLS.Agent.Tests/CommandLine/PackCommandTests.cs +++ b/MLS.Agent.Tests/CommandLine/PackCommandTests.cs @@ -7,9 +7,9 @@ using System.Threading.Tasks; using FluentAssertions; using MLS.Agent.CommandLine; +using MLS.Agent.Tools; using WorkspaceServer; using WorkspaceServer.Tests; -using WorkspaceServer.WorkspaceFeatures; using Xunit; namespace MLS.Agent.Tests.CommandLine diff --git a/WorkspaceServer/Dotnet.cs b/MLS.Agent.Tools/Dotnet.cs similarity index 85% rename from WorkspaceServer/Dotnet.cs rename to MLS.Agent.Tools/Dotnet.cs index 8d5e4188e..2fae4af7b 100644 --- a/WorkspaceServer/Dotnet.cs +++ b/MLS.Agent.Tools/Dotnet.cs @@ -9,9 +9,8 @@ using System.Reflection; using System.Threading.Tasks; using Clockwise; -using MLS.Agent.Tools; -namespace WorkspaceServer +namespace MLS.Agent.Tools { public class Dotnet { @@ -97,34 +96,6 @@ public async Task> ToolList(DirectoryInfo directory, Budget .Select(s => s.Split(separator, StringSplitOptions.RemoveEmptyEntries)[2]); } - private string RemoveTrailingSlash(string path) - { - // dotnet tool install doesn't like it if directory arguments end with "/" - if (path.EndsWith("\\")) - { - return path.Substring(0, path.Length - 1); - } - - return path; - } - - public Task ToolInstall( - string packageName, - DirectoryInfo toolPath, - PackageSource addSource = null, - Budget budget = null, - string version = null) - { - var versionArg = version != null ? $"--version {version}" : ""; - var args = $@"{packageName} --tool-path ""{RemoveTrailingSlash(toolPath.FullName)}"" {versionArg}"; - if (addSource != null) - { - args += $@" --add-source ""{addSource}"""; - } - - return Execute("tool install".AppendArgs(args), budget); - } - public Task Pack(string args = null, Budget budget = null) => Execute("pack".AppendArgs(args), budget); diff --git a/MLS.Agent.Tools/StringExtensions.cs b/MLS.Agent.Tools/StringExtensions.cs index c42376d3d..7b1457a8d 100644 --- a/MLS.Agent.Tools/StringExtensions.cs +++ b/MLS.Agent.Tools/StringExtensions.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Runtime.InteropServices; namespace MLS.Agent.Tools { @@ -23,5 +24,20 @@ public static void DeleteFileSystemObject(this string path) throw new ArgumentException($"Couldn't find a file or directory called {path}"); } } + + public static string ExecutableName(this string withoutExtension) => + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? withoutExtension + ".exe" + : withoutExtension; + + public static string RemoveTrailingSlash(this string path) + { + if (path.EndsWith("\\")) + { + return path.Substring(0, path.Length - 1); + } + + return path; + } } } diff --git a/MLS.Agent/CommandLine/CommandLineParser.cs b/MLS.Agent/CommandLine/CommandLineParser.cs index 1e7a62da4..85f8963f9 100644 --- a/MLS.Agent/CommandLine/CommandLineParser.cs +++ b/MLS.Agent/CommandLine/CommandLineParser.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.DotNet.Interactive; +using Microsoft.DotNet.Interactive.FSharp; using Microsoft.DotNet.Interactive.Jupyter; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -508,10 +509,11 @@ private static CompositeKernel CreateKernel() new CSharpKernel() .UseDefaultRendering() .UseNugetDirective() - .UseExtendDirective() .UseKernelHelpers() - .UseXplot() - }; + .UseXplot(), + new FSharpKernel() + .UseDefaultRendering() + }.UseExtendDirective(); } } } \ No newline at end of file diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs new file mode 100644 index 000000000..c46ec2144 --- /dev/null +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.DotNet.Interactive.FSharp + +open System +open System.ComponentModel +open System.Diagnostics +open System.Text +open System.Threading.Tasks +open Microsoft.DotNet.Interactive +open Microsoft.DotNet.Interactive.Commands +open Microsoft.DotNet.Interactive.Events +open MLS.Agent.Tools + +type FSharpKernel() = + inherit KernelBase() + let mutable proc: Process = null + let write (s: string) = proc.StandardInput.Write(s) + let sentinelValue = Guid.NewGuid().ToString() + let sentinelFound = Event<_>() + let stdout = StringBuilder() + let waitForReady () = + async { + write <| sprintf ";;printfn \"\\n%s\";;\n" sentinelValue + do! Async.AwaitEvent sentinelFound.Publish + } + let startProcess () = + async { + if isNull proc then + let outputReceived line = + if line = sentinelValue then + sentinelFound.Trigger() + else + stdout.AppendLine(line) |> ignore + proc <- Dotnet().StartProcess("fsi --nologo", output = Action(outputReceived)) + do! waitForReady() + } + let eval (code: string) = + async { + do! startProcess () + stdout.Clear() |> ignore + write code + do! waitForReady () + let value = stdout.ToString() + // trim garbage + let nl = Environment.NewLine + let headerGarbage = sprintf "val it : unit = ()%s%s" nl nl + let value = if value.StartsWith(headerGarbage) then value.Substring(headerGarbage.Length) else value + let footerGarbage = sprintf "%s%s> %s" nl nl nl + let value = if value.EndsWith(footerGarbage) then value.Substring(0, value.Length - footerGarbage.Length) else value + return value + } + do base.AddDisposable({ new IDisposable with + member __.Dispose() = + if not <| isNull proc then + try + proc.Kill() + with + | :? InvalidOperationException -> () + | :? NotSupportedException -> () + | :? Win32Exception -> () }) + let handleSubmitCode (codeSubmission: SubmitCode) (context: KernelInvocationContext) = + async { + let codeSubmissionReceived = CodeSubmissionReceived(codeSubmission.Code, codeSubmission) + context.OnNext(codeSubmissionReceived) + // submit code + let! value = eval codeSubmission.Code + context.OnNext(ValueProduced(value, codeSubmission, true, [FormattedValue("text/plain", value)])) + context.OnNext(CodeSubmissionEvaluated(codeSubmission)) + context.OnCompleted() + } + override __.Name = "fsharp" + override __.HandleAsync(command: IKernelCommand, _context: KernelInvocationContext): Task = + async { + match command with + | :? SubmitCode as submitCode -> submitCode.Handler <- fun invocationContext -> (handleSubmitCode submitCode invocationContext) |> Async.StartAsTask :> Task + | _ -> () + } |> Async.StartAsTask :> Task diff --git a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj new file mode 100644 index 000000000..6bee898b5 --- /dev/null +++ b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + false + + + + + + + + + + + + diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index cb199a61a..a75065827 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -1,52 +1,24 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; using Microsoft.DotNet.Interactive; -using Microsoft.DotNet.Interactive.Events; -using Pocket; using WorkspaceServer.Kernel; using Xunit.Abstractions; -using System.Reactive.Linq; -using System.Reactive; namespace WorkspaceServer.Tests.Kernel { - public abstract class CSharpKernelTestBase : IDisposable + public abstract class CSharpKernelTestBase : KernelTestBase { - protected CSharpKernelTestBase(ITestOutputHelper output) + public CSharpKernelTestBase(ITestOutputHelper output) : base(output) { - DisposeAfterTest(output.SubscribeToPocketLogger()); } - protected CSharpKernel CreateKernel() + protected override KernelBase CreateBaseKernel() { - var kernel = new CSharpKernel() - .UseDefaultRendering() - .UseNugetDirective() - .UseExtendDirective() - .UseKernelHelpers() - .LogEventsToPocketLogger(); - - DisposeAfterTest( - kernel.KernelEvents.Timestamp().Subscribe(KernelEvents.Add)); - - return kernel; - } - - private readonly CompositeDisposable _disposables = new CompositeDisposable(); - - protected IList> KernelEvents { get; } = new List>(); - - protected void DisposeAfterTest(IDisposable disposable) - { - _disposables.Add(disposable); - } - - public void Dispose() - { - _disposables?.Dispose(); + return new CSharpKernel() + .UseDefaultRendering() + .UseExtendDirective() + .UseKernelHelpers(); } } -} \ No newline at end of file +} diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTests.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTests.cs index 5afd27067..62b3e175b 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTests.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTests.cs @@ -3,9 +3,11 @@ using System; using System.IO; -using FluentAssertions; using System.Linq; +using System.Reactive.Linq; using System.Threading.Tasks; +using FluentAssertions; +using FluentAssertions.Extensions; using Microsoft.CodeAnalysis.Scripting; using Microsoft.DotNet.Interactive; using Microsoft.DotNet.Interactive.Commands; @@ -16,7 +18,6 @@ using WorkspaceServer.Kernel; using Xunit; using Xunit.Abstractions; -using FluentAssertions.Extensions; namespace WorkspaceServer.Tests.Kernel { diff --git a/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs b/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs new file mode 100644 index 000000000..dd4dc0515 --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs @@ -0,0 +1,57 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.DotNet.Interactive; +using Microsoft.DotNet.Interactive.Commands; +using Microsoft.DotNet.Interactive.Events; +using Microsoft.DotNet.Interactive.FSharp; +using WorkspaceServer.Kernel; +using Xunit; +using Xunit.Abstractions; + +namespace WorkspaceServer.Tests.Kernel +{ + public class FSharpKernelTests : KernelTestBase + { + public FSharpKernelTests(ITestOutputHelper output) : base(output) + { + } + + protected override KernelBase CreateBaseKernel() + { + return new FSharpKernel() + .UseDefaultRendering(); + } + + [Fact] + public async Task it_returns_an_object_value() + { + var kernel = CreateKernel(); + await kernel.SendAsync(new SubmitCode("123")); + AssertLastValue("> val it : int = 123"); + } + + [Fact] + public async Task it_remembers_state_between_submissions() + { + var kernel = CreateKernel(); + await kernel.SendAsync(new SubmitCode("let add x y = x + y")); + AssertLastValue("> val add : x:int -> y:int -> int"); + await kernel.SendAsync(new SubmitCode("add 2 3")); + AssertLastValue("> val it : int = 5"); + } + + private void AssertLastValue(string value) + { + KernelEvents.ValuesOnly() + .OfType() + .Last() + .Value + .Should() + .Be(value); + } + } +} diff --git a/WorkspaceServer.Tests/Kernel/KernelTestBase.cs b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs new file mode 100644 index 000000000..67cf2c32a --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Reactive; +using System.Reactive.Linq; +using Microsoft.DotNet.Interactive; +using Microsoft.DotNet.Interactive.Events; +using Pocket; +using Xunit.Abstractions; + +namespace WorkspaceServer.Tests.Kernel +{ + public abstract class KernelTestBase : IDisposable + { + public KernelTestBase(ITestOutputHelper output) + { + DisposeAfterTest(output.SubscribeToPocketLogger()); + } + + protected abstract KernelBase CreateBaseKernel(); + + protected KernelBase CreateKernel() + { + var kernel = CreateBaseKernel().LogEventsToPocketLogger(); + + DisposeAfterTest( + kernel.KernelEvents.Timestamp().Subscribe(KernelEvents.Add)); + + return kernel; + } + + private readonly CompositeDisposable _disposables = new CompositeDisposable(); + + protected IList> KernelEvents { get; } = new List>(); + + protected void DisposeAfterTest(IDisposable disposable) + { + _disposables.Add(disposable); + } + + public void Dispose() + { + _disposables?.Dispose(); + } + } +} diff --git a/WorkspaceServer.Tests/PackageTests2.cs b/WorkspaceServer.Tests/PackageTests2.cs index 37bf02644..38a192ce1 100644 --- a/WorkspaceServer.Tests/PackageTests2.cs +++ b/WorkspaceServer.Tests/PackageTests2.cs @@ -2,9 +2,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using FluentAssertions; using System.Linq; using System.Threading.Tasks; +using FluentAssertions; +using MLS.Agent.Tools; using WorkspaceServer.Packaging; using WorkspaceServer.Tests.Packaging; using Xunit; diff --git a/WorkspaceServer.Tests/RebuildablePackageTests.cs b/WorkspaceServer.Tests/RebuildablePackageTests.cs index 99b7cbb02..54c2b3bb4 100644 --- a/WorkspaceServer.Tests/RebuildablePackageTests.cs +++ b/WorkspaceServer.Tests/RebuildablePackageTests.cs @@ -2,17 +2,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using FluentAssertions; +using System.IO; +using System.Linq; using System.Threading.Tasks; using Clockwise; +using FluentAssertions; +using FluentAssertions.Extensions; +using Microsoft.Reactive.Testing; +using MLS.Agent.Tools; using Pocket; +using WorkspaceServer.Packaging; using Xunit; using Xunit.Abstractions; -using WorkspaceServer.Packaging; -using System.IO; -using FluentAssertions.Extensions; -using System.Linq; -using Microsoft.Reactive.Testing; namespace WorkspaceServer.Tests { diff --git a/WorkspaceServer/DotnetExtensions.cs b/WorkspaceServer/DotnetExtensions.cs new file mode 100644 index 000000000..33a96d1c1 --- /dev/null +++ b/WorkspaceServer/DotnetExtensions.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using System.Threading.Tasks; +using Clockwise; +using MLS.Agent.Tools; + +namespace WorkspaceServer +{ + public static class DotnetExtensions + { + + public static Task ToolInstall( + this Dotnet dotnet, + string packageName, + DirectoryInfo toolPath, + PackageSource addSource = null, + Budget budget = null, + string version = null) + { + var versionArg = version != null ? $"--version {version}" : ""; + var args = $@"{packageName} --tool-path ""{toolPath.FullName.RemoveTrailingSlash()}"" {versionArg}"; + if (addSource != null) + { + args += $@" --add-source ""{addSource}"""; + } + + return dotnet.Execute("tool install".AppendArgs(args), budget); + } + } +} diff --git a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs index 5997b0be1..cc715c855 100644 --- a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs +++ b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs @@ -17,7 +17,7 @@ public static class CSharpKernelExtensions public static CSharpKernel UseDefaultRendering( this CSharpKernel kernel) { - Task.Run(() => + Task.Run(() => kernel.SendAsync( new SubmitCode($@" using static {typeof(PocketViewTags).FullName}; diff --git a/WorkspaceServer/Kernel/FSharpKernelExtensions.cs b/WorkspaceServer/Kernel/FSharpKernelExtensions.cs new file mode 100644 index 000000000..141bc94c7 --- /dev/null +++ b/WorkspaceServer/Kernel/FSharpKernelExtensions.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.DotNet.Interactive.FSharp; + +namespace WorkspaceServer.Kernel +{ + public static class FSharpKernelExtensions + { + public static FSharpKernel UseDefaultRendering( + this FSharpKernel kernel) + { + // noop while the F# kernel is just a wrapper around fsi.exe forcing all return values to be strings + return kernel; + } + } +} diff --git a/WorkspaceServer/Packaging/LocalToolInstallingPackageDiscoveryStrategy.cs b/WorkspaceServer/Packaging/LocalToolInstallingPackageDiscoveryStrategy.cs index 5fbb6e9eb..af6a87461 100644 --- a/WorkspaceServer/Packaging/LocalToolInstallingPackageDiscoveryStrategy.cs +++ b/WorkspaceServer/Packaging/LocalToolInstallingPackageDiscoveryStrategy.cs @@ -1,10 +1,10 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.IO; using System.Threading.Tasks; using Clockwise; +using MLS.Agent.Tools; using Pocket; namespace WorkspaceServer.Packaging diff --git a/WorkspaceServer/Packaging/PackageBuilder.cs b/WorkspaceServer/Packaging/PackageBuilder.cs index 7293f1b28..39617f4e1 100644 --- a/WorkspaceServer/Packaging/PackageBuilder.cs +++ b/WorkspaceServer/Packaging/PackageBuilder.cs @@ -6,6 +6,7 @@ using System.IO; using System.Threading.Tasks; using Clockwise; +using MLS.Agent.Tools; namespace WorkspaceServer.Packaging { diff --git a/WorkspaceServer/Packaging/PackageInstallingWebAssemblyAssetFinder.cs b/WorkspaceServer/Packaging/PackageInstallingWebAssemblyAssetFinder.cs index f6a17ba16..2e4d626e6 100644 --- a/WorkspaceServer/Packaging/PackageInstallingWebAssemblyAssetFinder.cs +++ b/WorkspaceServer/Packaging/PackageInstallingWebAssemblyAssetFinder.cs @@ -1,9 +1,9 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.IO; using System.Threading.Tasks; using Clockwise; +using MLS.Agent.Tools; using Pocket; using WorkspaceServer.WorkspaceFeatures; diff --git a/WorkspaceServer/Packaging/ToolContainingWebAssemblyAssetLoader.cs b/WorkspaceServer/Packaging/ToolContainingWebAssemblyAssetLoader.cs index 9243af267..1e6e908fe 100644 --- a/WorkspaceServer/Packaging/ToolContainingWebAssemblyAssetLoader.cs +++ b/WorkspaceServer/Packaging/ToolContainingWebAssemblyAssetLoader.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using MLS.Agent.Tools; using WorkspaceServer.WorkspaceFeatures; namespace WorkspaceServer.Packaging diff --git a/WorkspaceServer/Paths.cs b/WorkspaceServer/Paths.cs index 27030de94..3ad46c831 100644 --- a/WorkspaceServer/Paths.cs +++ b/WorkspaceServer/Paths.cs @@ -32,11 +32,6 @@ static Paths() public static string NugetCache { get; } - public static string ExecutableName(this string withoutExtension) => - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? withoutExtension + ".exe" - : withoutExtension; - public static readonly string InstallDirectory = Path.GetDirectoryName(typeof(WorkspaceUtilities).Assembly.Location); } } diff --git a/WorkspaceServer/WorkspaceServer.csproj b/WorkspaceServer/WorkspaceServer.csproj index 0513697d7..0540b6681 100644 --- a/WorkspaceServer/WorkspaceServer.csproj +++ b/WorkspaceServer/WorkspaceServer.csproj @@ -102,6 +102,7 @@ +