From c1a06f651893f8adcd91a5107fc2586372d11e37 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Mon, 5 Aug 2019 13:04:28 -0700 Subject: [PATCH 1/9] add simple `FSharpKernel` wrapper around fsi.exe --- DotNetTry.sln | 7 ++ MLS.Agent/CommandLine/CommandLineParser.cs | 4 +- .../FSharpKernel.fs | 96 +++++++++++++++++++ ...Microsoft.DotNet.Interactive.FSharp.fsproj | 15 +++ .../Kernel/CSharpKernelTestBase.cs | 43 ++------- .../Kernel/CSharpKernelTests.cs | 5 +- .../Kernel/FSharpKernelTests.cs | 55 +++++++++++ .../Kernel/KernelTestBase.cs | 48 ++++++++++ WorkspaceServer/WorkspaceServer.csproj | 1 + 9 files changed, 234 insertions(+), 40 deletions(-) create mode 100644 Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs create mode 100644 Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj create mode 100644 WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs create mode 100644 WorkspaceServer.Tests/Kernel/KernelTestBase.cs 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/CommandLine/CommandLineParser.cs b/MLS.Agent/CommandLine/CommandLineParser.cs index 1e7a62da4..4b1046db8 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; @@ -510,7 +511,8 @@ private static CompositeKernel CreateKernel() .UseNugetDirective() .UseExtendDirective() .UseKernelHelpers() - .UseXplot() + .UseXplot(), + new FSharpKernel() }; } } diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs new file mode 100644 index 000000000..62d209357 --- /dev/null +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -0,0 +1,96 @@ +// 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 + +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 command = "dotnet" + let startInfo = ProcessStartInfo(command) + startInfo.Arguments <- "fsi --nologo" + startInfo.UseShellExecute <- false + startInfo.CreateNoWindow <- true + startInfo.RedirectStandardInput <- true + startInfo.RedirectStandardOutput <- true + startInfo.RedirectStandardError <- true + proc <- new Process() + proc.Exited.Add(fun args -> + ()) + proc.ErrorDataReceived.Add(fun args -> + let line = args.Data + ()) + proc.OutputDataReceived.Add(fun args -> + let line = args.Data + if not <| isNull line then + if line = sentinelValue then + sentinelFound.Trigger() + else + stdout.AppendLine(line) |> ignore) + proc.StartInfo <- startInfo + proc.Start() |> ignore + proc.BeginOutputReadLine() + proc.BeginErrorReadLine() + 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 + let produced = ValueProduced(value, codeSubmission, true, [FormattedValue("text/plain", value)]) + context.OnNext(produced) + } + 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..582bd88bb --- /dev/null +++ b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index cb199a61a..8b47f3cf8 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -1,52 +1,21 @@ -// 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(); } } -} \ 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..ac84a3ed5 --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs @@ -0,0 +1,55 @@ +// 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 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(); + } + + [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/WorkspaceServer.csproj b/WorkspaceServer/WorkspaceServer.csproj index 0513697d7..0540b6681 100644 --- a/WorkspaceServer/WorkspaceServer.csproj +++ b/WorkspaceServer/WorkspaceServer.csproj @@ -102,6 +102,7 @@ + From 24b793b203f06f0eb3de444cd60aa6843d9d3d99 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 6 Aug 2019 11:53:31 -0700 Subject: [PATCH 2/9] fix formatting --- .../FSharpKernel.fs | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index 62d209357..6d37012d1 100644 --- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -26,33 +26,33 @@ type FSharpKernel() = } let startProcess () = async { - if isNull proc then - let command = "dotnet" - let startInfo = ProcessStartInfo(command) - startInfo.Arguments <- "fsi --nologo" - startInfo.UseShellExecute <- false - startInfo.CreateNoWindow <- true - startInfo.RedirectStandardInput <- true - startInfo.RedirectStandardOutput <- true - startInfo.RedirectStandardError <- true - proc <- new Process() - proc.Exited.Add(fun args -> - ()) - proc.ErrorDataReceived.Add(fun args -> - let line = args.Data - ()) - proc.OutputDataReceived.Add(fun args -> - let line = args.Data - if not <| isNull line then - if line = sentinelValue then - sentinelFound.Trigger() - else - stdout.AppendLine(line) |> ignore) - proc.StartInfo <- startInfo - proc.Start() |> ignore - proc.BeginOutputReadLine() - proc.BeginErrorReadLine() - do! waitForReady() + if isNull proc then + let command = "dotnet" + let startInfo = ProcessStartInfo(command) + startInfo.Arguments <- "fsi --nologo" + startInfo.UseShellExecute <- false + startInfo.CreateNoWindow <- true + startInfo.RedirectStandardInput <- true + startInfo.RedirectStandardOutput <- true + startInfo.RedirectStandardError <- true + proc <- new Process() + proc.Exited.Add(fun args -> + ()) + proc.ErrorDataReceived.Add(fun args -> + let line = args.Data + ()) + proc.OutputDataReceived.Add(fun args -> + let line = args.Data + if not <| isNull line then + if line = sentinelValue then + sentinelFound.Trigger() + else + stdout.AppendLine(line) |> ignore) + proc.StartInfo <- startInfo + proc.Start() |> ignore + proc.BeginOutputReadLine() + proc.BeginErrorReadLine() + do! waitForReady() } let eval (code: string) = async { @@ -84,8 +84,9 @@ type FSharpKernel() = context.OnNext(codeSubmissionReceived) // submit code let! value = eval codeSubmission.Code - let produced = ValueProduced(value, codeSubmission, true, [FormattedValue("text/plain", value)]) - context.OnNext(produced) + 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 = From 08d4b3e375e1a987c4ea78b88c8ab10f2af91d96 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 6 Aug 2019 12:42:03 -0700 Subject: [PATCH 3/9] move `Dotnet` helper class down the stack --- .../CommandLine/PackCommandTests.cs | 2 +- .../Dotnet.cs | 31 +----------------- MLS.Agent.Tools/StringExtensions.cs | 16 ++++++++++ .../FSharpKernel.fs | 32 ++++--------------- ...Microsoft.DotNet.Interactive.FSharp.fsproj | 1 + WorkspaceServer.Tests/PackageTests2.cs | 3 +- .../RebuildablePackageTests.cs | 13 ++++---- WorkspaceServer/DotnetExtensions.cs | 32 +++++++++++++++++++ ...lToolInstallingPackageDiscoveryStrategy.cs | 2 +- WorkspaceServer/Packaging/PackageBuilder.cs | 1 + ...PackageInstallingWebAssemblyAssetFinder.cs | 2 +- .../ToolContainingWebAssemblyAssetLoader.cs | 1 + WorkspaceServer/Paths.cs | 5 --- 13 files changed, 71 insertions(+), 70 deletions(-) rename {WorkspaceServer => MLS.Agent.Tools}/Dotnet.cs (85%) create mode 100644 WorkspaceServer/DotnetExtensions.cs 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/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index 6d37012d1..c46ec2144 100644 --- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -11,6 +11,7 @@ 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() @@ -27,31 +28,12 @@ type FSharpKernel() = let startProcess () = async { if isNull proc then - let command = "dotnet" - let startInfo = ProcessStartInfo(command) - startInfo.Arguments <- "fsi --nologo" - startInfo.UseShellExecute <- false - startInfo.CreateNoWindow <- true - startInfo.RedirectStandardInput <- true - startInfo.RedirectStandardOutput <- true - startInfo.RedirectStandardError <- true - proc <- new Process() - proc.Exited.Add(fun args -> - ()) - proc.ErrorDataReceived.Add(fun args -> - let line = args.Data - ()) - proc.OutputDataReceived.Add(fun args -> - let line = args.Data - if not <| isNull line then - if line = sentinelValue then - sentinelFound.Trigger() - else - stdout.AppendLine(line) |> ignore) - proc.StartInfo <- startInfo - proc.Start() |> ignore - proc.BeginOutputReadLine() - proc.BeginErrorReadLine() + 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) = diff --git a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj index 582bd88bb..ef6242448 100644 --- a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj +++ b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj @@ -10,6 +10,7 @@ + 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/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); } } From e6360cd926b16ccbf42cd08d8625c663c9e6bc14 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Tue, 6 Aug 2019 12:42:19 -0700 Subject: [PATCH 4/9] use proper rendering in CSharpKernel --- WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index 8b47f3cf8..fba8b8a30 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -15,7 +15,7 @@ public CSharpKernelTestBase(ITestOutputHelper output) : base(output) protected override KernelBase CreateBaseKernel() { - return new CSharpKernel(); + return new CSharpKernel().UseDefaultRendering(); } } } From 88724d9c6e2554e5dcc112417041e02d8922aa8a Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Wed, 7 Aug 2019 15:29:11 -0700 Subject: [PATCH 5/9] move rendering request into IKernel --- MLS.Agent/CommandLine/CommandLineParser.cs | 15 ++++++++++----- .../FSharpKernel.fs | 2 ++ Microsoft.DotNet.Interactive/CompositeKernel.cs | 8 ++++++++ Microsoft.DotNet.Interactive/IKernel.cs | 2 ++ Microsoft.DotNet.Interactive/KernelBase.cs | 2 ++ .../Kernel/CSharpKernelTestBase.cs | 2 +- .../Kernel/CompositeKernelTests.cs | 4 ++++ WorkspaceServer.Tests/Kernel/KernelTestBase.cs | 1 + WorkspaceServer/Kernel/CSharpKernel.cs | 10 ++++++++++ WorkspaceServer/Kernel/CSharpKernelExtensions.cs | 14 -------------- 10 files changed, 40 insertions(+), 20 deletions(-) diff --git a/MLS.Agent/CommandLine/CommandLineParser.cs b/MLS.Agent/CommandLine/CommandLineParser.cs index 4b1046db8..c026d2cb3 100644 --- a/MLS.Agent/CommandLine/CommandLineParser.cs +++ b/MLS.Agent/CommandLine/CommandLineParser.cs @@ -506,14 +506,19 @@ private static CompositeKernel CreateKernel() { return new CompositeKernel { - new CSharpKernel() - .UseDefaultRendering() + PrepareKernel(new CSharpKernel() .UseNugetDirective() - .UseExtendDirective() .UseKernelHelpers() - .UseXplot(), - new FSharpKernel() + .UseXplot()), + PrepareKernel(new FSharpKernel()) }; } + + private static KernelBase PrepareKernel(KernelBase kernel) + { + kernel.UseExtendDirective(); + kernel.SetDefaultRendering(); + return kernel; + } } } \ No newline at end of file diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index c46ec2144..4cd78d2b9 100644 --- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -77,3 +77,5 @@ type FSharpKernel() = | :? SubmitCode as submitCode -> submitCode.Handler <- fun invocationContext -> (handleSubmitCode submitCode invocationContext) |> Async.StartAsTask :> Task | _ -> () } |> Async.StartAsTask :> Task + override __.SetDefaultRendering() = + () diff --git a/Microsoft.DotNet.Interactive/CompositeKernel.cs b/Microsoft.DotNet.Interactive/CompositeKernel.cs index 7decabc39..f8f56302a 100644 --- a/Microsoft.DotNet.Interactive/CompositeKernel.cs +++ b/Microsoft.DotNet.Interactive/CompositeKernel.cs @@ -86,6 +86,14 @@ protected internal override async Task HandleAsync( throw new NoSuitableKernelException(); } + public override void SetDefaultRendering() + { + foreach (var kernel in _kernels) + { + kernel.SetDefaultRendering(); + } + } + public IEnumerator GetEnumerator() => _kernels.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/Microsoft.DotNet.Interactive/IKernel.cs b/Microsoft.DotNet.Interactive/IKernel.cs index cb3680fae..c2cc7583a 100644 --- a/Microsoft.DotNet.Interactive/IKernel.cs +++ b/Microsoft.DotNet.Interactive/IKernel.cs @@ -16,5 +16,7 @@ public interface IKernel : IDisposable IObservable KernelEvents { get; } Task SendAsync(IKernelCommand command, CancellationToken cancellationToken); + + void SetDefaultRendering(); } } \ No newline at end of file diff --git a/Microsoft.DotNet.Interactive/KernelBase.cs b/Microsoft.DotNet.Interactive/KernelBase.cs index ae807c380..5a36a08c0 100644 --- a/Microsoft.DotNet.Interactive/KernelBase.cs +++ b/Microsoft.DotNet.Interactive/KernelBase.cs @@ -322,6 +322,8 @@ protected virtual void SetKernel( IKernelCommand command, KernelInvocationContext context) => context.Kernel = this; + public abstract void SetDefaultRendering(); + public void Dispose() => _disposables.Dispose(); } } \ No newline at end of file diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index fba8b8a30..8b47f3cf8 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -15,7 +15,7 @@ public CSharpKernelTestBase(ITestOutputHelper output) : base(output) protected override KernelBase CreateBaseKernel() { - return new CSharpKernel().UseDefaultRendering(); + return new CSharpKernel(); } } } diff --git a/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs b/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs index 18a38dcc6..5cefc5932 100644 --- a/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs +++ b/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs @@ -189,6 +189,10 @@ protected override Task HandleAsync( command.As().Handler = Handle; return Task.CompletedTask; } + + public override void SetDefaultRendering() + { + } } } } \ No newline at end of file diff --git a/WorkspaceServer.Tests/Kernel/KernelTestBase.cs b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs index 67cf2c32a..02109bd64 100644 --- a/WorkspaceServer.Tests/Kernel/KernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs @@ -24,6 +24,7 @@ public KernelTestBase(ITestOutputHelper output) protected KernelBase CreateKernel() { var kernel = CreateBaseKernel().LogEventsToPocketLogger(); + kernel.SetDefaultRendering(); DisposeAfterTest( kernel.KernelEvents.Timestamp().Subscribe(KernelEvents.Add)); diff --git a/WorkspaceServer/Kernel/CSharpKernel.cs b/WorkspaceServer/Kernel/CSharpKernel.cs index 9f9872cb0..75dba9f59 100644 --- a/WorkspaceServer/Kernel/CSharpKernel.cs +++ b/WorkspaceServer/Kernel/CSharpKernel.cs @@ -87,6 +87,16 @@ protected override async Task HandleAsync( } } + public override void SetDefaultRendering() + { + Task.Run(() => + this.SendAsync( + new SubmitCode($@" +using static {typeof(PocketViewTags).FullName}; +using {typeof(PocketView).Namespace}; +"))).Wait(); + } + private async Task HandleSubmitCode( SubmitCode submitCode, KernelInvocationContext context) diff --git a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs index 5997b0be1..e7ada18c8 100644 --- a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs +++ b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs @@ -7,26 +7,12 @@ using Microsoft.DotNet.Interactive; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.Events; -using Microsoft.DotNet.Interactive.Rendering; using WorkspaceServer.Packaging; namespace WorkspaceServer.Kernel { public static class CSharpKernelExtensions { - public static CSharpKernel UseDefaultRendering( - this CSharpKernel kernel) - { - Task.Run(() => - kernel.SendAsync( - new SubmitCode($@" -using static {typeof(PocketViewTags).FullName}; -using {typeof(PocketView).Namespace}; -"))).Wait(); - - return kernel; - } - public static CSharpKernel UseKernelHelpers( this CSharpKernel kernel) { From 4340063fbb3ef157bf49ea7dccb4c054b87ba621 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Thu, 8 Aug 2019 13:03:03 -0700 Subject: [PATCH 6/9] call UseExtendDirective() from the composite kernel --- MLS.Agent/CommandLine/CommandLineParser.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MLS.Agent/CommandLine/CommandLineParser.cs b/MLS.Agent/CommandLine/CommandLineParser.cs index c026d2cb3..31e3a05ca 100644 --- a/MLS.Agent/CommandLine/CommandLineParser.cs +++ b/MLS.Agent/CommandLine/CommandLineParser.cs @@ -511,12 +511,11 @@ private static CompositeKernel CreateKernel() .UseKernelHelpers() .UseXplot()), PrepareKernel(new FSharpKernel()) - }; + }.UseExtendDirective(); } private static KernelBase PrepareKernel(KernelBase kernel) { - kernel.UseExtendDirective(); kernel.SetDefaultRendering(); return kernel; } From 1dd40fa02cf8e7695a79b081872498b86e59a3b3 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Thu, 8 Aug 2019 13:45:04 -0700 Subject: [PATCH 7/9] fix tests --- WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index 8b47f3cf8..093e8574e 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -15,7 +15,9 @@ public CSharpKernelTestBase(ITestOutputHelper output) : base(output) protected override KernelBase CreateBaseKernel() { - return new CSharpKernel(); + return new CSharpKernel() + .UseExtendDirective() + .UseKernelHelpers(); } } } From dd91c9d0c94eb8af603a6c20ce1d513bd4901920 Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Thu, 8 Aug 2019 14:55:24 -0700 Subject: [PATCH 8/9] refactor UseDefaultRendering extension methods --- MLS.Agent/CommandLine/CommandLineParser.cs | 14 +++++--------- .../FSharpKernel.fs | 2 -- Microsoft.DotNet.Interactive/CompositeKernel.cs | 8 -------- Microsoft.DotNet.Interactive/IKernel.cs | 2 -- Microsoft.DotNet.Interactive/KernelBase.cs | 2 -- .../Kernel/CSharpKernelTestBase.cs | 1 + .../Kernel/CompositeKernelTests.cs | 4 ---- .../Kernel/FSharpKernelTests.cs | 4 +++- WorkspaceServer.Tests/Kernel/KernelTestBase.cs | 1 - WorkspaceServer/Kernel/CSharpKernel.cs | 10 ---------- .../Kernel/CSharpKernelExtensions.cs | 14 ++++++++++++++ .../Kernel/FSharpKernelExtensions.cs | 17 +++++++++++++++++ 12 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 WorkspaceServer/Kernel/FSharpKernelExtensions.cs diff --git a/MLS.Agent/CommandLine/CommandLineParser.cs b/MLS.Agent/CommandLine/CommandLineParser.cs index 31e3a05ca..85f8963f9 100644 --- a/MLS.Agent/CommandLine/CommandLineParser.cs +++ b/MLS.Agent/CommandLine/CommandLineParser.cs @@ -506,18 +506,14 @@ private static CompositeKernel CreateKernel() { return new CompositeKernel { - PrepareKernel(new CSharpKernel() + new CSharpKernel() + .UseDefaultRendering() .UseNugetDirective() .UseKernelHelpers() - .UseXplot()), - PrepareKernel(new FSharpKernel()) + .UseXplot(), + new FSharpKernel() + .UseDefaultRendering() }.UseExtendDirective(); } - - private static KernelBase PrepareKernel(KernelBase kernel) - { - kernel.SetDefaultRendering(); - return kernel; - } } } \ No newline at end of file diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index 4cd78d2b9..c46ec2144 100644 --- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -77,5 +77,3 @@ type FSharpKernel() = | :? SubmitCode as submitCode -> submitCode.Handler <- fun invocationContext -> (handleSubmitCode submitCode invocationContext) |> Async.StartAsTask :> Task | _ -> () } |> Async.StartAsTask :> Task - override __.SetDefaultRendering() = - () diff --git a/Microsoft.DotNet.Interactive/CompositeKernel.cs b/Microsoft.DotNet.Interactive/CompositeKernel.cs index f8f56302a..7decabc39 100644 --- a/Microsoft.DotNet.Interactive/CompositeKernel.cs +++ b/Microsoft.DotNet.Interactive/CompositeKernel.cs @@ -86,14 +86,6 @@ protected internal override async Task HandleAsync( throw new NoSuitableKernelException(); } - public override void SetDefaultRendering() - { - foreach (var kernel in _kernels) - { - kernel.SetDefaultRendering(); - } - } - public IEnumerator GetEnumerator() => _kernels.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/Microsoft.DotNet.Interactive/IKernel.cs b/Microsoft.DotNet.Interactive/IKernel.cs index c2cc7583a..cb3680fae 100644 --- a/Microsoft.DotNet.Interactive/IKernel.cs +++ b/Microsoft.DotNet.Interactive/IKernel.cs @@ -16,7 +16,5 @@ public interface IKernel : IDisposable IObservable KernelEvents { get; } Task SendAsync(IKernelCommand command, CancellationToken cancellationToken); - - void SetDefaultRendering(); } } \ No newline at end of file diff --git a/Microsoft.DotNet.Interactive/KernelBase.cs b/Microsoft.DotNet.Interactive/KernelBase.cs index 5a36a08c0..ae807c380 100644 --- a/Microsoft.DotNet.Interactive/KernelBase.cs +++ b/Microsoft.DotNet.Interactive/KernelBase.cs @@ -322,8 +322,6 @@ protected virtual void SetKernel( IKernelCommand command, KernelInvocationContext context) => context.Kernel = this; - public abstract void SetDefaultRendering(); - public void Dispose() => _disposables.Dispose(); } } \ No newline at end of file diff --git a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs index 093e8574e..a75065827 100644 --- a/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/CSharpKernelTestBase.cs @@ -16,6 +16,7 @@ public CSharpKernelTestBase(ITestOutputHelper output) : base(output) protected override KernelBase CreateBaseKernel() { return new CSharpKernel() + .UseDefaultRendering() .UseExtendDirective() .UseKernelHelpers(); } diff --git a/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs b/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs index 5cefc5932..18a38dcc6 100644 --- a/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs +++ b/WorkspaceServer.Tests/Kernel/CompositeKernelTests.cs @@ -189,10 +189,6 @@ protected override Task HandleAsync( command.As().Handler = Handle; return Task.CompletedTask; } - - public override void SetDefaultRendering() - { - } } } } \ No newline at end of file diff --git a/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs b/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs index ac84a3ed5..dd4dc0515 100644 --- a/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs +++ b/WorkspaceServer.Tests/Kernel/FSharpKernelTests.cs @@ -8,6 +8,7 @@ using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.FSharp; +using WorkspaceServer.Kernel; using Xunit; using Xunit.Abstractions; @@ -21,7 +22,8 @@ public FSharpKernelTests(ITestOutputHelper output) : base(output) protected override KernelBase CreateBaseKernel() { - return new FSharpKernel(); + return new FSharpKernel() + .UseDefaultRendering(); } [Fact] diff --git a/WorkspaceServer.Tests/Kernel/KernelTestBase.cs b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs index 02109bd64..67cf2c32a 100644 --- a/WorkspaceServer.Tests/Kernel/KernelTestBase.cs +++ b/WorkspaceServer.Tests/Kernel/KernelTestBase.cs @@ -24,7 +24,6 @@ public KernelTestBase(ITestOutputHelper output) protected KernelBase CreateKernel() { var kernel = CreateBaseKernel().LogEventsToPocketLogger(); - kernel.SetDefaultRendering(); DisposeAfterTest( kernel.KernelEvents.Timestamp().Subscribe(KernelEvents.Add)); diff --git a/WorkspaceServer/Kernel/CSharpKernel.cs b/WorkspaceServer/Kernel/CSharpKernel.cs index 75dba9f59..9f9872cb0 100644 --- a/WorkspaceServer/Kernel/CSharpKernel.cs +++ b/WorkspaceServer/Kernel/CSharpKernel.cs @@ -87,16 +87,6 @@ protected override async Task HandleAsync( } } - public override void SetDefaultRendering() - { - Task.Run(() => - this.SendAsync( - new SubmitCode($@" -using static {typeof(PocketViewTags).FullName}; -using {typeof(PocketView).Namespace}; -"))).Wait(); - } - private async Task HandleSubmitCode( SubmitCode submitCode, KernelInvocationContext context) diff --git a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs index e7ada18c8..cc715c855 100644 --- a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs +++ b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs @@ -7,12 +7,26 @@ using Microsoft.DotNet.Interactive; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.Events; +using Microsoft.DotNet.Interactive.Rendering; using WorkspaceServer.Packaging; namespace WorkspaceServer.Kernel { public static class CSharpKernelExtensions { + public static CSharpKernel UseDefaultRendering( + this CSharpKernel kernel) + { + Task.Run(() => + kernel.SendAsync( + new SubmitCode($@" +using static {typeof(PocketViewTags).FullName}; +using {typeof(PocketView).Namespace}; +"))).Wait(); + + return kernel; + } + public static CSharpKernel UseKernelHelpers( this CSharpKernel kernel) { 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; + } + } +} From 98328fbe46e7fc38d05fc9bdc59bfadc56622c8c Mon Sep 17 00:00:00 2001 From: "Brett V. Forsgren" Date: Fri, 16 Aug 2019 15:38:18 -0700 Subject: [PATCH 9/9] don't convert F# portable PDBs --- .../Microsoft.DotNet.Interactive.FSharp.fsproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj index ef6242448..6bee898b5 100644 --- a/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj +++ b/Microsoft.DotNet.Interactive.FSharp/Microsoft.DotNet.Interactive.FSharp.fsproj @@ -2,6 +2,7 @@ netstandard2.0 + false