Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop bubbling KernelCommandResult.Events from child commands #3191

Original file line number Diff line number Diff line change
Expand Up @@ -291,27 +291,35 @@ Microsoft.DotNet.Interactive
.ctor()
public class LinePosition, System.IEquatable<LinePosition>
public static LinePosition FromCodeAnalysisLinePosition(Microsoft.CodeAnalysis.Text.LinePosition linePosition)
public static System.Boolean op_Equality(LinePosition a, LinePosition b)
public static System.Boolean op_Inequality(LinePosition a, LinePosition b)
.ctor(System.Int32 line, System.Int32 character)
public System.Int32 Character { get;}
public System.Int32 Line { get;}
public static System.Boolean op_Equality(LinePosition left, LinePosition right)
public static System.Boolean op_Inequality(LinePosition left, LinePosition right)
.ctor(System.Int32 Line, System.Int32 Character)
public System.Int32 Character { get; set;}
public System.Int32 Line { get; set;}
public LinePosition <Clone>$()
public System.Void Deconstruct(ref System.Int32& Line, ref System.Int32& Character)
public System.Boolean Equals(System.Object obj)
public System.Boolean Equals(LinePosition other)
protected System.Type get_EqualityContract()
public System.Int32 GetHashCode()
protected System.Boolean PrintMembers(System.Text.StringBuilder builder)
public LinePosition SubtractLineOffset(LinePosition offset)
public Microsoft.CodeAnalysis.Text.LinePosition ToCodeAnalysisLinePosition()
public System.String ToString()
public class LinePositionSpan, System.IEquatable<LinePositionSpan>
public static LinePositionSpan FromCodeAnalysisLinePositionSpan(Microsoft.CodeAnalysis.Text.LinePositionSpan linePositionSpan)
public static System.Boolean op_Equality(LinePositionSpan a, LinePositionSpan b)
public static System.Boolean op_Inequality(LinePositionSpan a, LinePositionSpan b)
.ctor(LinePosition start, LinePosition end)
public LinePosition End { get;}
public LinePosition Start { get;}
public static System.Boolean op_Equality(LinePositionSpan left, LinePositionSpan right)
public static System.Boolean op_Inequality(LinePositionSpan left, LinePositionSpan right)
.ctor(LinePosition Start, LinePosition End)
public LinePosition End { get; set;}
public LinePosition Start { get; set;}
public LinePositionSpan <Clone>$()
public System.Void Deconstruct(ref LinePosition& Start, ref LinePosition& End)
public System.Boolean Equals(System.Object obj)
public System.Boolean Equals(LinePositionSpan other)
protected System.Type get_EqualityContract()
public System.Int32 GetHashCode()
protected System.Boolean PrintMembers(System.Text.StringBuilder builder)
public LinePositionSpan SubtractLineOffset(LinePosition offset)
public System.String ToString()
public class NoSuitableKernelException : System.Exception, System.Runtime.Serialization.ISerializable
Expand Down Expand Up @@ -395,7 +403,7 @@ Microsoft.DotNet.Interactive.Commands
public System.Boolean Equals(KernelCommand other)
public System.String GetOrCreateToken()
public System.Threading.Tasks.Task InvokeAsync(Microsoft.DotNet.Interactive.KernelInvocationContext context)
public System.Void SetParent(KernelCommand parent)
public System.Void SetParent(KernelCommand parent, System.Boolean bubbleEvents = False)
public System.Void SetToken(System.String token)
public abstract class LanguageServiceCommand : KernelCommand, System.IEquatable<KernelCommand>
public System.String Code { get;}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Reflection;
using System.Threading.Tasks;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// 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.CodeAnalysis;
using Microsoft.DotNet.Interactive.Commands;
using Microsoft.DotNet.Interactive.Events;
using Microsoft.DotNet.Interactive.Formatting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using HtmlAgilityPack;
using Microsoft.DotNet.Interactive.Events;
using Microsoft.DotNet.Interactive.Formatting;
using Microsoft.DotNet.Interactive.Tests.Utility;
using Xunit;

namespace Microsoft.DotNet.Interactive.Mermaid.Tests;
Expand Down Expand Up @@ -66,8 +67,9 @@ public async Task mermaid_kernel_handles_SubmitCode()
");

var returnValue = result.Events
.OfType<DisplayedValueProduced>()
.Single()
.Should()
.ContainSingle<DisplayedValueProduced>()
.Which
.Value as MermaidMarkdown;

returnValue.ToString().Should().Be(@"graph TD
Expand Down Expand Up @@ -121,8 +123,9 @@ graph TD
");

var formattedData = result.Events
.OfType<DisplayedValueProduced>()
.Single()
.Should()
.ContainSingle<DisplayedValueProduced>()
.Which
.FormattedValues
.Single(fm => fm.MimeType == HtmlFormatter.MimeType)
.Value;
Expand Down Expand Up @@ -154,8 +157,9 @@ graph TD
");

var formattedData = result.Events
.OfType<DisplayedValueProduced>()
.Single()
.Should()
.ContainSingle<DisplayedValueProduced>()
.Which
.FormattedValues
.Single(fm => fm.MimeType == HtmlFormatter.MimeType)
.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<ProjectReference Include="..\Microsoft.DotNet.Interactive.Mermaid\Microsoft.DotNet.Interactive.Mermaid.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Interactive.Tests\Microsoft.DotNet.Interactive.Tests.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.8.0" />
<PackageReference Include="Assent" Version="1.7.0" />
Expand All @@ -31,4 +32,9 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>


<ItemGroup>
<Folder Include="Utility\" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace Microsoft.DotNet.Interactive;

public static class KernelSupportsNugetExtensions
{
public static T UseNugetDirective<T>(this T kernel, bool useResultsCache = true)
where T: Kernel, ISupportNuget
public static T UseNugetDirective<T>(this T kernel, bool useResultsCache = true)
where T : Kernel, ISupportNuget
{
kernel.AddDirective(i());
kernel.AddDirective(r());
Expand All @@ -28,6 +28,8 @@ public static T UseNugetDirective<T>(this T kernel, bool useResultsCache = true)
kernel.AddDirective(restore);

return kernel;

static KernelCommandInvocation DoNugetRestore() => async (_, context) => await context.ScheduleAsync(Restore);
}

private static Command i()
Expand Down Expand Up @@ -151,70 +153,62 @@ private static bool EndsInDirectorySeparator(string path)
return path.Length > 0 && path.EndsWith(Path.DirectorySeparatorChar);
}

internal static KernelCommandInvocation DoNugetRestore()
private static async Task Restore(KernelInvocationContext context)
{
return async (_, invocationContext) =>
if (context.HandlingKernel is not ISupportNuget kernel)
{
async Task Restore(KernelInvocationContext context)
{
if (context.HandlingKernel is not ISupportNuget kernel)
{
return;
}
return;
}

var requestedPackages = kernel.RequestedPackageReferences.Select(s => s.PackageName).OrderBy(s => s).ToList();
var requestedPackages = kernel.RequestedPackageReferences.Select(s => s.PackageName).OrderBy(s => s).ToList();

var requestedSources = kernel.RestoreSources.OrderBy(s => s).ToList();
var requestedSources = kernel.RestoreSources.OrderBy(s => s).ToList();

var installMessage = new InstallPackagesMessage(requestedSources, requestedPackages, Array.Empty<string>(), 0);
var installMessage = new InstallPackagesMessage(requestedSources, requestedPackages, Array.Empty<string>(), 0);

var displayedValue = context.Display(installMessage);
var displayedValue = context.Display(installMessage);

var restorePackagesTask = kernel.RestoreAsync();
var delay = 500;
while (await Task.WhenAny(Task.Delay(delay), restorePackagesTask) != restorePackagesTask)
{
if (context.CancellationToken.IsCancellationRequested)
{
break;
}
var restorePackagesTask = kernel.RestoreAsync();
var delay = 500;
while (await Task.WhenAny(Task.Delay(delay), restorePackagesTask) != restorePackagesTask)
{
if (context.CancellationToken.IsCancellationRequested)
{
break;
}

installMessage.Progress++;
installMessage.Progress++;

displayedValue.Update(installMessage);
}
displayedValue.Update(installMessage);
}

var result = await restorePackagesTask;
var result = await restorePackagesTask;

var resultMessage = new InstallPackagesMessage(
requestedSources,
Array.Empty<string>(),
kernel.ResolvedPackageReferences
.Where(r => requestedPackages.Contains(r.PackageName, StringComparer.OrdinalIgnoreCase))
.Select(s => $"{s.PackageName}, {s.PackageVersion}")
.OrderBy(s => s)
.ToList(),
0);
var resultMessage = new InstallPackagesMessage(
requestedSources,
Array.Empty<string>(),
kernel.ResolvedPackageReferences
.Where(r => requestedPackages.Contains(r.PackageName, StringComparer.OrdinalIgnoreCase))
.Select(s => $"{s.PackageName}, {s.PackageVersion}")
.OrderBy(s => s)
.ToList(),
0);

if (result.Succeeded)
{
kernel.RegisterResolvedPackageReferences(result.ResolvedReferences);
foreach (var resolvedReference in result.ResolvedReferences)
{
context.Publish(new PackageAdded(resolvedReference, context.Command));
}
displayedValue.Update(resultMessage);
}
else
{
var errors = string.Join(Environment.NewLine, result.Errors);
displayedValue.Update(resultMessage);
context.Fail(context.Command, message: errors);
}
if (result.Succeeded)
{
kernel.RegisterResolvedPackageReferences(result.ResolvedReferences);
foreach (var resolvedReference in result.ResolvedReferences)
{
context.Publish(new PackageAdded(resolvedReference, context.Command));
}

await invocationContext.ScheduleAsync(Restore);
};
displayedValue.Update(resultMessage);
}
else
{
var errors = string.Join(Environment.NewLine, result.Errors);
displayedValue.Update(resultMessage);
context.Fail(context.Command, message: errors);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ public async Task<PackageRestoreResult> RestoreAsync()
if (!result.Success)
{
errors.AddRange(result.StdOut);

packageRestoreResult = new PackageRestoreResult(
succeeded: false,
requestedPackages: newlyRequestedPackageReferences,
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.DotNet.Interactive.Tests/DirectiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.DotNet.Interactive.Commands;
using Microsoft.DotNet.Interactive.CSharp;
using Microsoft.DotNet.Interactive.Events;
using Microsoft.DotNet.Interactive.Formatting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public async Task Commands_sent_within_the_code_of_another_command_do_not_publis
.NotContain(e => e is CommandFailed);
}

[Fact(Skip = "Need to remove command id first")] // FIX: (Commands_sent_within_the_code_of_another_command_do_not_publish_events_to_the_outer_result)
[Fact]
public async Task Commands_sent_within_the_code_of_another_command_do_not_publish_events_to_the_outer_result()
{
using var kernel = new CompositeKernel
Expand All @@ -124,6 +124,33 @@ public async Task Commands_sent_within_the_code_of_another_command_do_not_publis
result.Events.Should().NotContain(e => e is ReturnValueProduced);
}

[Fact]
public async Task Commands_sent_via_API_within_a_split_submission_do_not_bubble_events()
{
using var kernel = new CompositeKernel
{
new CSharpKernel("cs1"),
new CSharpKernel("cs2")
};

var command = new SubmitCode($"""
#!cs1
using {typeof(Kernel).Namespace};
using {typeof(KernelCommand).Namespace};
var result = await Kernel.Root.SendAsync(new SubmitCode("123.Display();\n456", "cs2"));

#!cs2
Console.WriteLine(789);
""");

var result = await kernel.SendAsync(command);

using var _ = new AssertionScope();
result.Events.Should().NotContainErrors();
result.Events.Should().NotContain(e => e is DisplayedValueProduced);
result.Events.Should().NotContain(e => e is ReturnValueProduced);
}

[Fact]
public async Task Commands_sent_within_the_code_of_another_command_publish_CommandSucceeded_to_the_inner_result()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.DotNet.Interactive.Formatting;
using Microsoft.DotNet.Interactive.Tests.Utility;
using Microsoft.DotNet.Interactive.Utility;
using Pocket;
Expand Down
Loading
Loading