From d11f5a0ec934a95a25a5379a3664fed8c6ef0380 Mon Sep 17 00:00:00 2001 From: Jon Sequeira Date: Thu, 5 Dec 2024 14:14:43 -0800 Subject: [PATCH] Infer specific data kernel package version in discoverability kernels (#3788) * publish PostreSQL package * make repack.ps1 version number match informational version number * data kernel cleanup, suggest specific package version in discoverability --- .../PublishPolyglotNotebooksHelper.psm1 | 1 + repack.ps1 | 4 +- ...nteractive_api_is_not_changed.approved.txt | 4 -- .../KernelExtensionTests.cs | 2 +- .../TabularData/TabularDataFormatterSource.cs | 2 + .../JupyterKernelTestBase.cs | 6 -- .../KqlConnectionTests.cs | 12 +--- .../KqlFactAttribute.cs | 6 +- .../PostgreSqlConnectionTests.cs | 9 +-- .../PostgreSqlFactAttribute.cs | 15 ++-- .../README.md | 21 +----- ...osoft.DotNet.Interactive.PostgreSql.csproj | 4 +- .../PostgreSqlKernel.cs | 23 +++---- .../SQLiteConnectionTests.cs | 5 +- .../MsSqlConnectionTests.cs | 5 +- .../KqlDiscoverabilityKernelTests.cs | 6 +- .../LanguageKernelFormattingTests.cs | 4 +- .../SqlDiscoverabilityKernelTests.cs | 6 +- .../Connection}/KqlDiscoverabilityKernel.cs | 59 ++++++++-------- .../Connection/PackageAcquisition.cs | 30 ++++++++ .../Connection}/SqlDiscoverabilityKernel.cs | 69 ++++++++++--------- src/dotnet-interactive/KernelBuilder.cs | 1 - 22 files changed, 157 insertions(+), 137 deletions(-) rename src/{Microsoft.DotNet.Interactive => dotnet-interactive/Connection}/KqlDiscoverabilityKernel.cs (62%) create mode 100644 src/dotnet-interactive/Connection/PackageAcquisition.cs rename src/{Microsoft.DotNet.Interactive => dotnet-interactive/Connection}/SqlDiscoverabilityKernel.cs (59%) diff --git a/eng/publish/PublishPolyglotNotebooksHelper.psm1 b/eng/publish/PublishPolyglotNotebooksHelper.psm1 index 02262ffccd..0378375c95 100644 --- a/eng/publish/PublishPolyglotNotebooksHelper.psm1 +++ b/eng/publish/PublishPolyglotNotebooksHelper.psm1 @@ -70,6 +70,7 @@ function PublishStableExtensionAndNuGetPackages { "Microsoft.DotNet.Interactive.Mermaid", "Microsoft.DotNet.Interactive.NamedPipeConnector", "Microsoft.DotNet.Interactive.PackageManagement", + "Microsoft.DotNet.Interactive.PostgreSQL", "Microsoft.DotNet.Interactive.PowerShell", "Microsoft.DotNet.Interactive.SQLite", "Microsoft.DotNet.Interactive.SqlServer", diff --git a/repack.ps1 b/repack.ps1 index d9eccee96c..5fe7146bd6 100644 --- a/repack.ps1 +++ b/repack.ps1 @@ -8,8 +8,8 @@ try # build and pack dotnet-interactive dotnet clean -c debug - dotnet build -c debug - dotnet pack -c debug /p:PackageVersion=2.0.0 + dotnet build -c debug /p:Version=2.0.0 + dotnet pack --no-build -c debug /p:PackageVersion=2.0.0 # copy the dotnet-interactive packages to the temp directory $destinationPath = "C:\temp\packages" diff --git a/src/Microsoft.DotNet.Interactive.ApiCompatibility.Tests/ApiCompatibilityTests.Interactive_api_is_not_changed.approved.txt b/src/Microsoft.DotNet.Interactive.ApiCompatibility.Tests/ApiCompatibilityTests.Interactive_api_is_not_changed.approved.txt index 89d59bfe21..146bfb950f 100644 --- a/src/Microsoft.DotNet.Interactive.ApiCompatibility.Tests/ApiCompatibilityTests.Interactive_api_is_not_changed.approved.txt +++ b/src/Microsoft.DotNet.Interactive.ApiCompatibility.Tests/ApiCompatibilityTests.Interactive_api_is_not_changed.approved.txt @@ -253,8 +253,6 @@ Microsoft.DotNet.Interactive .ctor(System.String name = value, System.Net.Http.HttpClient httpClient = null) public Microsoft.DotNet.Interactive.Directives.KernelSpecifierDirective KernelSpecifierDirective { get;} public System.Collections.Generic.IReadOnlyDictionary Values { get;} - public class KqlDiscoverabilityKernel : Kernel, IKernelCommandHandler, IKernelCommandHandler, System.IDisposable - .ctor() public class LinePosition, System.IEquatable public static LinePosition FromCodeAnalysisLinePosition(Microsoft.CodeAnalysis.Text.LinePosition linePosition) public static System.Boolean op_Equality(LinePosition left, LinePosition right) @@ -338,8 +336,6 @@ Microsoft.DotNet.Interactive public FormattedValue Documentation { get;} public System.String Label { get;} public System.Collections.Generic.IReadOnlyList Parameters { get;} - public class SqlDiscoverabilityKernel : Kernel, IKernelCommandHandler, IKernelCommandHandler, System.IDisposable - .ctor() public class TabularDataResourceSummaryExplorer : DataExplorer .ctor(Microsoft.DotNet.Interactive.Formatting.TabularData.TabularDataResource data) protected Microsoft.AspNetCore.Html.IHtmlContent ToHtml() diff --git a/src/Microsoft.DotNet.Interactive.DuckDB.Tests/KernelExtensionTests.cs b/src/Microsoft.DotNet.Interactive.DuckDB.Tests/KernelExtensionTests.cs index c34c9723b6..175d6b391d 100644 --- a/src/Microsoft.DotNet.Interactive.DuckDB.Tests/KernelExtensionTests.cs +++ b/src/Microsoft.DotNet.Interactive.DuckDB.Tests/KernelExtensionTests.cs @@ -16,9 +16,9 @@ namespace Microsoft.DotNet.Interactive.DuckDB.Tests; +[Trait("Databases", "Data query tests")] public class DuckDbConnectionTests { - [Fact] public async Task It_can_connect_and_query_data() { diff --git a/src/Microsoft.DotNet.Interactive.Formatting/TabularData/TabularDataFormatterSource.cs b/src/Microsoft.DotNet.Interactive.Formatting/TabularData/TabularDataFormatterSource.cs index 33b349199d..43b2b91ed8 100644 --- a/src/Microsoft.DotNet.Interactive.Formatting/TabularData/TabularDataFormatterSource.cs +++ b/src/Microsoft.DotNet.Interactive.Formatting/TabularData/TabularDataFormatterSource.cs @@ -14,6 +14,8 @@ internal class TabularDataFormatterSource : ITypeFormatterSource { public IEnumerable CreateTypeFormatters() { + Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); + yield return new HtmlFormatter((value, context) => FormatHtml(context, value)); yield return new JsonFormatter((value, context) => diff --git a/src/Microsoft.DotNet.Interactive.Jupyter.Tests/JupyterKernelTestBase.cs b/src/Microsoft.DotNet.Interactive.Jupyter.Tests/JupyterKernelTestBase.cs index 78cd47169f..6c308faf2e 100644 --- a/src/Microsoft.DotNet.Interactive.Jupyter.Tests/JupyterKernelTestBase.cs +++ b/src/Microsoft.DotNet.Interactive.Jupyter.Tests/JupyterKernelTestBase.cs @@ -3,9 +3,6 @@ using FluentAssertions; using Microsoft.DotNet.Interactive.CSharp; -using Microsoft.DotNet.Interactive.Formatting; -using Microsoft.DotNet.Interactive.Formatting.Csv; -using Microsoft.DotNet.Interactive.Formatting.TabularData; using Microsoft.DotNet.Interactive.Jupyter.Connection; using Microsoft.DotNet.Interactive.Jupyter.Protocol; using Microsoft.DotNet.Interactive.Tests.Utility; @@ -13,7 +10,6 @@ using System.Collections.Generic; using System.Reactive.Disposables; using System.Threading.Tasks; -using Formatter = Microsoft.DotNet.Interactive.Formatting.Formatter; using Message = Microsoft.DotNet.Interactive.Jupyter.Messaging.Message; namespace Microsoft.DotNet.Interactive.Jupyter.Tests; @@ -34,8 +30,6 @@ public virtual void Dispose() protected CompositeKernel CreateCompositeKernelAsync(params IJupyterKernelConnectionOptions[] optionsList) { - Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); - var csharpKernel = new CSharpKernel() .UseKernelHelpers() .UseValueSharing(); diff --git a/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlConnectionTests.cs b/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlConnectionTests.cs index e700f2bf6f..c7b768373e 100644 --- a/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlConnectionTests.cs +++ b/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlConnectionTests.cs @@ -1,13 +1,13 @@ // 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.Linq; using System.Threading.Tasks; using FluentAssertions; using Microsoft.DotNet.Interactive.App; +using Microsoft.DotNet.Interactive.App.Connection; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.CSharp; using Microsoft.DotNet.Interactive.Events; @@ -21,11 +21,11 @@ namespace Microsoft.DotNet.Interactive.Kql.Tests; -public class KqlConnectionTests : IDisposable +[Trait("Databases", "Data query tests")] +public class KqlConnectionTests { private static async Task CreateKernelAsync() { - Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); var csharpKernel = new CSharpKernel().UseNugetDirective(); var kernel = new CompositeKernel @@ -448,10 +448,4 @@ await kernel.SubmitCodeAsync( resultSet.Should().NotBeNull().And.HaveCount(1); } - - public void Dispose() - { - Formatter.ResetToDefault(); - DataExplorer.ResetToDefault(); - } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlFactAttribute.cs b/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlFactAttribute.cs index 0d9923d96c..0ce2c49220 100644 --- a/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlFactAttribute.cs +++ b/src/Microsoft.DotNet.Interactive.Kql.Tests/KqlFactAttribute.cs @@ -26,8 +26,10 @@ internal static string TestConnectionAndReturnSkipReason() string clusterName = GetClusterForTests(); if (string.IsNullOrWhiteSpace(clusterName)) { - return $"Environment variable {TEST_KQL_CONNECTION_STRING} is not set. To run tests that require " - + "KQL Cluster, this environment variable must be set to a valid connection string value."; + return + $""" + Environment variable {TEST_KQL_CONNECTION_STRING} is not set. To run tests that require a KQL Cluster, this environment variable must be set to a valid connection string value. + """; } return null; diff --git a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlConnectionTests.cs b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlConnectionTests.cs index fe2ded4a13..5ab2d94f67 100644 --- a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlConnectionTests.cs +++ b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlConnectionTests.cs @@ -12,14 +12,16 @@ using Microsoft.DotNet.Interactive.CSharp; using Microsoft.DotNet.Interactive.App; using FluentAssertions; +using Microsoft.DotNet.Interactive.App.Connection; +using Xunit; namespace Microsoft.DotNet.Interactive.PostgreSql.Tests; +[Trait("Databases", "Data query tests")] public class PostgreSqlConnectionTests : IDisposable { private static CompositeKernel CreateKernel() { - Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); var csharpKernel = new CSharpKernel().UseNugetDirective().UseValueSharing(); var kernel = new CompositeKernel @@ -48,7 +50,7 @@ public async Task It_can_connect_and_query_data() result = await kernel.SubmitCodeAsync(""" #!sql-adventureworks - SELECT * FROM Person.Person LIMIT 100; + SELECT * FROM customers LIMIT 100; """); result.Events.Should().NotContainErrors(); @@ -71,7 +73,7 @@ public async Task It_returns_error_if_query_is_not_valid() result = await kernel.SubmitCodeAsync(""" #!sql-adventureworks - SELECT not_known_column FROM Person.Person LIMIT 100; + SELECT not_known_column FROM customers LIMIT 100; """); result.Events.Should() @@ -85,6 +87,5 @@ public async Task It_returns_error_if_query_is_not_valid() public void Dispose() { DataExplorer.ResetToDefault(); - Formatter.ResetToDefault(); } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlFactAttribute.cs b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlFactAttribute.cs index 298bc2220d..04cc5945a7 100644 --- a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlFactAttribute.cs +++ b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/PostgreSqlFactAttribute.cs @@ -30,8 +30,10 @@ internal static string TestConnectionAndReturnSkipReason() string connectionString = GetConnectionStringForTests(); if (string.IsNullOrWhiteSpace(connectionString)) { - return $"Environment variable {TEST_POSTGRESQL_CONNECTION_STRING} is not set. To run tests that require " - + "SQL Server, this environment variable must be set to a valid connection string value."; + return + $""" + Environment variable {TEST_POSTGRESQL_CONNECTION_STRING} is not set. To run tests that require PostgreSQL, this environment variable must be set to a valid connection string value. + """; } try @@ -41,9 +43,10 @@ internal static string TestConnectionAndReturnSkipReason() } catch (Exception e) { - return $"A connection could not be established to SQL Server. Verify the connection string value used " + - $"for environment variable {TEST_POSTGRESQL_CONNECTION_STRING} targets a running SQL Server instance. " + - $"Connection failed failed with error: {e}"; + return + $""" + A connection could not be established to a PostgreSQL server. Verify the connection string value used for environment variable {TEST_POSTGRESQL_CONNECTION_STRING} targets a running PostgreSQL instance. Connection failed failed with error: {e} + """; } return null; @@ -51,7 +54,7 @@ internal static string TestConnectionAndReturnSkipReason() public static string GetConnectionStringForTests() { - const string fallbackConnectionString = "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=Adventureworks"; + const string fallbackConnectionString = "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=northwind"; return Environment.GetEnvironmentVariable(TEST_POSTGRESQL_CONNECTION_STRING) ?? fallbackConnectionString; } diff --git a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/README.md b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/README.md index 85f3180dbe..22c46ca3e9 100644 --- a/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/README.md +++ b/src/Microsoft.DotNet.Interactive.PostgreSql.Tests/README.md @@ -2,25 +2,10 @@ ## Setup Test Database -Take a look at [AdventureWorks-for-Postgres](https://github.com/lorint/AdventureWorks-for-Postgres) repository. It contains a script to create the AdventureWorks database on a PostgreSQL server. +The tests use the sample [Northwind database](https://github.com/pthom/northwind_psql). You can create a blank database and install it using [this script](https://github.com/pthom/northwind_psql/blob/master/northwind.sql). -You can use Docker to run a PostgreSQL server with the AdventureWorks database: - -Install repository: - -```bash -git clone https://github.com/lorint/AdventureWorks-for-Postgres -``` - -Run PostgreSQL server: - -```bash -podman build -t adventure-postgres ./ -podman run -d -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 adventure-postgres -``` - -Setup connection string as environment variable: +The tests will only run when the environment variable `TEST_POSTGRESQL_CONNECTION_STRING` has set to a valid connection string. Here's an example using a default Postgres installation: ```bash -export TEST_POSTGRESQL_CONNECTION_STRING='Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=Adventureworks' +export TEST_POSTGRESQL_CONNECTION_STRING='Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=northwind' ``` \ No newline at end of file diff --git a/src/Microsoft.DotNet.Interactive.PostgreSql/Microsoft.DotNet.Interactive.PostgreSql.csproj b/src/Microsoft.DotNet.Interactive.PostgreSql/Microsoft.DotNet.Interactive.PostgreSql.csproj index f30021924b..10d206d96f 100644 --- a/src/Microsoft.DotNet.Interactive.PostgreSql/Microsoft.DotNet.Interactive.PostgreSql.csproj +++ b/src/Microsoft.DotNet.Interactive.PostgreSql/Microsoft.DotNet.Interactive.PostgreSql.csproj @@ -3,7 +3,7 @@ net8.0 true - Microsoft PostgreSQL support for .NET Interactive + PostgreSQL support for .NET Interactive polyglot notebook dotnet interactive SQL PostgreSQL Data true $(NoWarn);NU5100;VSTHRD002 @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Microsoft.DotNet.Interactive.PostgreSql/PostgreSqlKernel.cs b/src/Microsoft.DotNet.Interactive.PostgreSql/PostgreSqlKernel.cs index 399110e3f0..ed23cbbbf9 100644 --- a/src/Microsoft.DotNet.Interactive.PostgreSql/PostgreSqlKernel.cs +++ b/src/Microsoft.DotNet.Interactive.PostgreSql/PostgreSqlKernel.cs @@ -1,4 +1,4 @@ -// 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.Collections.Generic; @@ -109,23 +109,20 @@ void ResolveColumnNameClashes(string[] names) } } - public static void AddPostgreSqlKernelConnectorTo(CompositeKernel kernel) - { - kernel.AddConnectDirective(new ConnectPostgreSqlDirective()); - - KernelInvocationContext.Current?.Display( - new HtmlString(@"
Query PostgreSql databases. -

This extension adds support for connecting to PostgreSql databases using the #!connect postgres magic command. For more information, run a cell using the #!sql magic command.

-
"), - "text/html"); - } - public static void AddPostgreSqlKernelConnectorToCurrentRoot() { if (KernelInvocationContext.Current is { } context && context.HandlingKernel.RootKernel is CompositeKernel root) { - AddPostgreSqlKernelConnectorTo(root); + root.AddConnectDirective(new ConnectPostgreSqlDirective()); + + context.Display( + new HtmlString(""" +
Query PostgreSQL databases. +

This extension adds support for connecting to PostgreSql databases using the #!connect postgres magic command.

+
+ """), + "text/html"); } } } diff --git a/src/Microsoft.DotNet.Interactive.SQLite.Tests/SQLiteConnectionTests.cs b/src/Microsoft.DotNet.Interactive.SQLite.Tests/SQLiteConnectionTests.cs index 7e2e0dea4a..48331d37fe 100644 --- a/src/Microsoft.DotNet.Interactive.SQLite.Tests/SQLiteConnectionTests.cs +++ b/src/Microsoft.DotNet.Interactive.SQLite.Tests/SQLiteConnectionTests.cs @@ -6,17 +6,20 @@ using FluentAssertions; using Microsoft.Data.Sqlite; using Microsoft.DotNet.Interactive.App; +using Microsoft.DotNet.Interactive.App.Connection; using Microsoft.DotNet.Interactive.CSharp; using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.Formatting; using Microsoft.DotNet.Interactive.Tests.Utility; +using Xunit; namespace Microsoft.DotNet.Interactive.SQLite.Tests; +[Trait("Databases", "Data query tests")] public class SQLiteConnectionTests { [WindowsFact] - public async Task SQLKernel_suggests_SQLite_connection_when_statements_are_submitted_to_it() + public async Task SQLDiscoverabilityKernel_suggests_SQLite_connection_when_statements_are_submitted_to_it() { using var kernel = new CompositeKernel { diff --git a/src/Microsoft.DotNet.Interactive.SqlServer.Tests/MsSqlConnectionTests.cs b/src/Microsoft.DotNet.Interactive.SqlServer.Tests/MsSqlConnectionTests.cs index f42e4ca073..f438a8c401 100644 --- a/src/Microsoft.DotNet.Interactive.SqlServer.Tests/MsSqlConnectionTests.cs +++ b/src/Microsoft.DotNet.Interactive.SqlServer.Tests/MsSqlConnectionTests.cs @@ -9,6 +9,7 @@ using FluentAssertions; using FluentAssertions.Execution; using Microsoft.DotNet.Interactive.App; +using Microsoft.DotNet.Interactive.App.Connection; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.CSharp; using Microsoft.DotNet.Interactive.Events; @@ -20,14 +21,13 @@ namespace Microsoft.DotNet.Interactive.SqlServer.Tests; +[Trait("Databases", "Data query tests")] public class MsSqlConnectionTests : IDisposable { private async Task CreateKernelAsync() { - Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); var csharpKernel = new CSharpKernel().UseNugetDirective().UseValueSharing(); - // TODO: remove SQLKernel it is used to test current patch var kernel = new CompositeKernel { new SqlDiscoverabilityKernel(), @@ -584,6 +584,5 @@ public async Task An_input_type_hint_is_set_for_connection_strings() public void Dispose() { DataExplorer.ResetToDefault(); - Formatter.ResetToDefault(); } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Interactive.Tests/KqlDiscoverabilityKernelTests.cs b/src/Microsoft.DotNet.Interactive.Tests/KqlDiscoverabilityKernelTests.cs index 2d4c8965e2..b2a2347394 100644 --- a/src/Microsoft.DotNet.Interactive.Tests/KqlDiscoverabilityKernelTests.cs +++ b/src/Microsoft.DotNet.Interactive.Tests/KqlDiscoverabilityKernelTests.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using FluentAssertions; +using Microsoft.DotNet.Interactive.App.Connection; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.Tests.Utility; @@ -78,9 +79,10 @@ public async Task kql_kernel_emits_help_message_without_sql_server_extension_ins var message = displayValue.Value.ToString(); - // Should contain instructions for how to install SqlServer extension package - message.Should().Contain(@"#r ""nuget:Microsoft.DotNet.Interactive.Kql,*-*"""); + message.Should().Contain(""" + #r "nuget:Microsoft.DotNet.Interactive.Kql,1.0.0 + """); // Should contain instructions for how to get help message for MSSQL kernel message.Should().Contain("#!connect kql --kernel-name mydatabase --cluster \"https://help.kusto.windows.net\" --database \"Samples\""); diff --git a/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelFormattingTests.cs b/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelFormattingTests.cs index bd2d16179c..c52584f3ab 100644 --- a/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelFormattingTests.cs +++ b/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelFormattingTests.cs @@ -1,4 +1,4 @@ -// 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; @@ -173,7 +173,7 @@ public async Task DisplayTable_produces_tabular_HTML_output_for_IEnumerable_T(La result.Events .Should().ContainSingle() .Which - .FormattedValues.Should().ContainSingle() + .FormattedValues.Should().ContainSingle(v => v.MimeType == "text/html") .Which .Value.Should().ContainEquivalentHtmlFragments(""" diff --git a/src/Microsoft.DotNet.Interactive.Tests/SqlDiscoverabilityKernelTests.cs b/src/Microsoft.DotNet.Interactive.Tests/SqlDiscoverabilityKernelTests.cs index 0be898688a..3d87de4370 100644 --- a/src/Microsoft.DotNet.Interactive.Tests/SqlDiscoverabilityKernelTests.cs +++ b/src/Microsoft.DotNet.Interactive.Tests/SqlDiscoverabilityKernelTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using FluentAssertions; +using Microsoft.DotNet.Interactive.App.Connection; using Microsoft.DotNet.Interactive.Commands; using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.Tests.Utility; @@ -13,7 +14,6 @@ namespace Microsoft.DotNet.Interactive.Tests; public class SqlDiscoverabilityKernelTests { - [Fact] public async Task sql_kernel_does_not_execute_query() { @@ -81,7 +81,9 @@ public async Task sql_kernel_emits_help_message_without_sql_server_extension_ins // Should contain instructions for how to install SqlServer extension package - message.Should().Contain(@"#r ""nuget:Microsoft.DotNet.Interactive.SqlServer,*-*"""); + message.Should().Contain(""" + #r "nuget:Microsoft.DotNet.Interactive.SqlServer,1.0.0 + """); // Should contain instructions for how to get help message for MSSQL kernel message.Should().Contain("#!connect mssql --kernel-name"); diff --git a/src/Microsoft.DotNet.Interactive/KqlDiscoverabilityKernel.cs b/src/dotnet-interactive/Connection/KqlDiscoverabilityKernel.cs similarity index 62% rename from src/Microsoft.DotNet.Interactive/KqlDiscoverabilityKernel.cs rename to src/dotnet-interactive/Connection/KqlDiscoverabilityKernel.cs index 09549bbc5d..a9a291590c 100644 --- a/src/Microsoft.DotNet.Interactive/KqlDiscoverabilityKernel.cs +++ b/src/dotnet-interactive/Connection/KqlDiscoverabilityKernel.cs @@ -8,7 +8,7 @@ using Microsoft.DotNet.Interactive.Formatting; using static Microsoft.DotNet.Interactive.Formatting.PocketViewTags; -namespace Microsoft.DotNet.Interactive; +namespace Microsoft.DotNet.Interactive.App.Connection; /// This kernel is used as a placeholder for the MSKQL kernel in order to enable KQL language coloring in the editor. Language grammars can only be defined for fixed kernel names, but MSKQL subkernels are user-defined via the #!connect magic command. So, this kernel is specified in addition to the user-defined kernel as a kind of "styling" kernel as well as to provide guidance and discoverability for KQL features. public class KqlDiscoverabilityKernel : @@ -25,7 +25,7 @@ public KqlDiscoverabilityKernel() : base(DefaultKernelName) "MsKqlKernel" }; KernelInfo.LanguageName = "KQL"; - KernelInfo.Description = $""" + KernelInfo.Description = """ Query a Kusto database """; } @@ -45,33 +45,38 @@ Task IKernelCommandHandler.HandleAsync(SubmitCode command, KernelInv }); var codeSample = !string.IsNullOrWhiteSpace(command.Code) - ? command.Code - : @"tableName | take 10"; + ? command.Code + : "tableName | take 10"; - if (connectedKqlKernelNames.Count == 0) + if (connectedKqlKernelNames.Count is 0) { - context.Display(HTML($@" -

A KQL connection has not been established.

-

To connect to a database, first add the KQL extension package by running the following in a C# cell:

- -
-    #r ""nuget:Microsoft.DotNet.Interactive.Kql,*-*""
-    
-
-Now, you can connect to a Microsoft Kusto Server database by running the following in a C# cell: - -
-    #!connect kql --kernel-name mydatabase --cluster ""https://help.kusto.windows.net"" --database ""Samples""
-    
-
-

Once a connection is established, you can send KQL statements by prefixing them with the magic command for your connection.

- -
-#!kql-mydatabase
-{codeSample}
-    
-
-"), "text/html"); + var version = PackageAcquisition.InferCompatiblePackageVersion(); + + context.Display( + HTML( + $""" +

A KQL connection has not been established.

+

To connect to a database, first add the KQL extension package by running the following in a C# cell:

+ +
+                         #r "nuget:Microsoft.DotNet.Interactive.Kql,{version}"
+                         
+
+ Now, you can connect to a Microsoft Kusto Server database by running the following in a C# cell: + +
+                         #!connect kql --kernel-name mydatabase --cluster "https://help.kusto.windows.net" --database "Samples"
+                         
+
+

Once a connection is established, you can send KQL statements by prefixing them with the magic command for your connection.

+ +
+                     #!kql-mydatabase
+                     {codeSample}
+                         
+
+ + """), "text/html"); } else { diff --git a/src/dotnet-interactive/Connection/PackageAcquisition.cs b/src/dotnet-interactive/Connection/PackageAcquisition.cs new file mode 100644 index 0000000000..cd5a003525 --- /dev/null +++ b/src/dotnet-interactive/Connection/PackageAcquisition.cs @@ -0,0 +1,30 @@ +// 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.Reflection; +using Microsoft.DotNet.Interactive.Formatting; + +namespace Microsoft.DotNet.Interactive.App.Connection; + +internal static class PackageAcquisition +{ + internal static string InferCompatiblePackageVersion() + { + var informationalVersion = typeof(Formatter) + .Assembly + .GetCustomAttribute() + .InformationalVersion; + + if (informationalVersion.Contains("+")) + { + informationalVersion = informationalVersion.Split("+")[0]; + } + + var splitInformationalVersion = informationalVersion.Split('.'); + + var version = splitInformationalVersion.Length is 4 + ? string.Join(".", splitInformationalVersion[0..4]) + : informationalVersion; + return version; + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Interactive/SqlDiscoverabilityKernel.cs b/src/dotnet-interactive/Connection/SqlDiscoverabilityKernel.cs similarity index 59% rename from src/Microsoft.DotNet.Interactive/SqlDiscoverabilityKernel.cs rename to src/dotnet-interactive/Connection/SqlDiscoverabilityKernel.cs index 399cc45cef..015baeae4f 100644 --- a/src/Microsoft.DotNet.Interactive/SqlDiscoverabilityKernel.cs +++ b/src/dotnet-interactive/Connection/SqlDiscoverabilityKernel.cs @@ -8,7 +8,7 @@ using Microsoft.DotNet.Interactive.Formatting; using static Microsoft.DotNet.Interactive.Formatting.PocketViewTags; -namespace Microsoft.DotNet.Interactive; +namespace Microsoft.DotNet.Interactive.App.Connection; /// This kernel is used as a placeholder for the MSSQL kernel in order to enable SQL language coloring in the editor. Language grammars can only be defined for fixed kernel names, but MSSQL subkernels are user-defined via the #!connect magic command. So, this kernel is specified in addition to the user-defined kernel as a kind of "styling" kernel as well as to provide guidance and discoverability for SQL features. public class SqlDiscoverabilityKernel : @@ -20,13 +20,14 @@ public class SqlDiscoverabilityKernel : public SqlDiscoverabilityKernel() : base(DefaultKernelName) { - _kernelNameFilter = new HashSet - { + _kernelNameFilter = + [ "MsSqlKernel", + "PostgreSqlKernel", "SQLiteKernel" - }; + ]; KernelInfo.LanguageName = "SQL"; - KernelInfo.Description = $""" + KernelInfo.Description = """ Query a Microsoft SQL database """; } @@ -46,37 +47,41 @@ Task IKernelCommandHandler.HandleAsync(SubmitCode command, KernelInv }); var codeSample = !string.IsNullOrWhiteSpace(command.Code) - ? command.Code - : "SELECT TOP * FROM ..."; + ? command.Code + : "SELECT TOP * FROM ..."; - if (connectedSqlKernelNames.Count == 0) + if (connectedSqlKernelNames.Count is 0) { - context.Display(HTML($@" -

A SQL connection has not been established.

-

To connect to a database, first add the SQL extension package by running the following in a C# cell:

- -
-    #r ""nuget:Microsoft.DotNet.Interactive.SqlServer,*-*""
-    
-
-Now, you can connect to a Microsoft SQL Server database by running the following in a C# cell: - -
-    #!connect mssql --kernel-name mydatabase ""Persist Security Info=False; Integrated Security=true; Initial Catalog=MyDatabase; Server=localhost""
-    
-
-

Once a connection is established, you can send SQL statements by prefixing them with the magic command for your connection.

- -
-#!sql-mydatabase
-{codeSample}
-    
-
-"), "text/html"); + var version = PackageAcquisition.InferCompatiblePackageVersion(); + + context.Display( + HTML( + $""" +

A SQL connection has not been established.

+

To connect to a database, first add the SQL extension package by running the following in a C# cell:

+ +
+                         #r "nuget:Microsoft.DotNet.Interactive.SqlServer,{version}"
+                         
+
+ Now, you can connect to a Microsoft SQL Server database by running the following in a C# cell: + +
+                         #!connect mssql --kernel-name mydatabase "Persist Security Info=False; Integrated Security=true; Initial Catalog=MyDatabase; Server=localhost"
+                         
+
+

Once a connection is established, you can send SQL statements by prefixing them with the magic command for your connection.

+ +
+                     #!sql-mydatabase
+                     {codeSample}
+                         
+
+ + """), "text/html"); } else { - PocketView view = div( p("You can send SQL statements to one of the following connected SQL kernels:"), @@ -92,7 +97,7 @@ Task IKernelCommandHandler.HandleAsync(SubmitCode command, KernelInv { context.Fail(command, message: "SQL statements cannot be executed in this kernel."); } - + return Task.CompletedTask; } } \ No newline at end of file diff --git a/src/dotnet-interactive/KernelBuilder.cs b/src/dotnet-interactive/KernelBuilder.cs index cbe69e0c8b..538d8cd4d9 100644 --- a/src/dotnet-interactive/KernelBuilder.cs +++ b/src/dotnet-interactive/KernelBuilder.cs @@ -107,7 +107,6 @@ internal static void SetUpFormatters(FrontendEnvironment frontendEnvironment) { Formatter.DefaultMimeType = HtmlFormatter.MimeType; Formatter.SetPreferredMimeTypesFor(typeof(string), PlainTextFormatter.MimeType); - Formatter.SetPreferredMimeTypesFor(typeof(TabularDataResource), HtmlFormatter.MimeType, CsvFormatter.MimeType); } } } \ No newline at end of file