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

Enforce a minimum version for Kusto and SQL Service dotnet tools. #2689

Merged
merged 7 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions src/Microsoft.DotNet.Interactive.Kql/KqlKernelExtension.cs
Original file line number Diff line number Diff line change
@@ -1,11 +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;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.DotNet.Interactive.Utility;
using Microsoft.DotNet.Interactive.SqlServer;

namespace Microsoft.DotNet.Interactive.Kql;

Expand All @@ -15,16 +13,8 @@ public async Task OnLoadAsync(Kernel kernel)
{
if (kernel is CompositeKernel compositeKernel)
{
// Check if the required Sql Tools Service tool is installed, and then install it if necessary
var dotnet = new Dotnet();
var installedGlobalTools = await dotnet.ToolList();
const string kqlToolName = "MicrosoftKustoServiceLayer";
bool kqlToolInstalled = installedGlobalTools.Any(tool => string.Equals(tool, kqlToolName, StringComparison.InvariantCultureIgnoreCase));
if (!kqlToolInstalled)
{
var commandLineResult = await dotnet.ToolInstall("Microsoft.SqlServer.KustoServiceLayer.Tool", null, null, "1.1.0");
commandLineResult.ThrowOnFailure();
}
var kqlToolName = "MicrosoftKustoServiceLayer";
await Utils.CheckAndInstallGlobalToolAsync(kqlToolName, "1.1.0", "Microsoft.SqlServer.KustoServiceLayer.Tool");

compositeKernel
.AddKernelConnector(new ConnectKqlCommand(kqlToolName));
Expand Down
15 changes: 2 additions & 13 deletions src/Microsoft.DotNet.Interactive.SqlServer/MsSqlKernelExtension.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// 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.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.DotNet.Interactive.Utility;

namespace Microsoft.DotNet.Interactive.SqlServer;

Expand All @@ -15,16 +12,8 @@ public async Task OnLoadAsync(Kernel kernel)
{
if (kernel is CompositeKernel compositeKernel)
{
// Check if the required Sql Tools Service tool is installed, and then install it if necessary
var dotnet = new Dotnet();
var installedGlobalTools = await dotnet.ToolList();
const string sqlToolName = "MicrosoftSqlToolsServiceLayer";
bool sqlToolInstalled = installedGlobalTools.Any(tool => string.Equals(tool, sqlToolName, StringComparison.InvariantCultureIgnoreCase));
if (!sqlToolInstalled)
{
var commandLineResult = await dotnet.ToolInstall("Microsoft.SqlServer.SqlToolsServiceLayer.Tool", null, null, "1.1.0");
commandLineResult.ThrowOnFailure();
}
var sqlToolName = "MicrosoftSqlToolsServiceLayer";
await Utils.CheckAndInstallGlobalToolAsync(sqlToolName, "1.1.0", "Microsoft.SqlServer.SqlToolsServiceLayer.Tool");

compositeKernel
.AddKernelConnector(new ConnectMsSqlCommand(sqlToolName));
Expand Down
76 changes: 76 additions & 0 deletions src/Microsoft.DotNet.Interactive.SqlServer/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
// 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 Microsoft.DotNet.Interactive.Utility;

namespace Microsoft.DotNet.Interactive.SqlServer;

public class DotnetToolInfo {
corivera marked this conversation as resolved.
Show resolved Hide resolved
public string PackageId { get; set; }
public string PackageVersion { get; set; }
public string CommandName { get; set; }

}

public static class Utils
corivera marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
Expand All @@ -24,4 +37,67 @@ public static string AsDoubleQuotedString(this string str)
{
return $"\"{str.Replace("\"", "\\\"")}\"";
}

public static async Task<IEnumerable<DotnetToolInfo>> GetGlobalToolListAsync()
{
var dotnet = new Dotnet();
var result = await dotnet.Execute("tool list --global");
if (result.ExitCode != 0)
{
return new DotnetToolInfo[0];
}

// Output of dotnet tool list is:
// Package Id Version Commands
// -------------------------------------------
// dotnettry.p1 1.0.0 dotnettry.p1

string[] separator = new[] { " " };
return result.Output
.Skip(2)
.Where(s => !string.IsNullOrWhiteSpace(s))
.Select(s =>
{
var parts = s.Split(separator, StringSplitOptions.RemoveEmptyEntries);
return new DotnetToolInfo()
{
PackageId = parts[0],
PackageVersion = parts[1],
CommandName = parts[2]
};
});
}

public static async Task CheckAndInstallGlobalToolAsync(string toolName, string minimumVersion, string nugetPackage)
{
var installedGlobalTools = await Utils.GetGlobalToolListAsync();
var expectedVersion = Version.Parse(minimumVersion);
var installNeeded = true;
var updateNeeded = false;
foreach (var tool in installedGlobalTools)
{
if (string.Equals(tool.CommandName, toolName, StringComparison.InvariantCultureIgnoreCase))
{
installNeeded = false;
var installedVersion = Version.Parse(tool.PackageVersion);
if (installedVersion < expectedVersion)
{
updateNeeded = true;
}
break;
}
}

var dotnet = new Dotnet();
if (updateNeeded)
{
var commandLineResult = await dotnet.Execute($"tool update --global \"{nugetPackage}\" --version \"{minimumVersion}\"");
commandLineResult.ThrowOnFailure();
}
else if (installNeeded)
{
var commandLineResult = await dotnet.Execute($"tool install --global \"{nugetPackage}\" --version \"{minimumVersion}\"");
commandLineResult.ThrowOnFailure();
}
}
}