这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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

This file was deleted.

This file was deleted.

21 changes: 21 additions & 0 deletions Microsoft.DotNet.Interactive/Commands/LoadExtensionsInDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +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.IO;
using MLS.Agent.Tools;
using Newtonsoft.Json;

namespace Microsoft.DotNet.Interactive.Commands
{
public class LoadExtensionsInDirectory : KernelCommandBase
{
public LoadExtensionsInDirectory(IDirectoryAccessor directory)
{
Directory = directory;
}

public IDirectoryAccessor Directory { get; }
}
}
25 changes: 11 additions & 14 deletions Microsoft.DotNet.Interactive/KernelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,37 +83,34 @@ private void AddDirectiveMiddlewareAndCommonCommandHandlers()
context,
next),

LoadExtensionFromNuGetPackage loadCSharpExtension =>
HandleLoadExtensionFromNuGetPackage(
loadCSharpExtension,
context,
LoadExtensionsInDirectory loadExtensionsInDirectory =>
HandleLoadExtensionsInDirectory(
loadExtensionsInDirectory,
context,
next),

_ => next(command, context)
});
}

private async Task HandleLoadExtensionFromNuGetPackage(
LoadExtensionFromNuGetPackage loadExtensionFromNuGetPackage,
private async Task HandleLoadExtensionsInDirectory(
LoadExtensionsInDirectory loadExtensionsInDirectory,
KernelInvocationContext invocationContext,
KernelPipelineContinuation next)
{
loadExtensionFromNuGetPackage.Handler = async context =>
loadExtensionsInDirectory.Handler = async context =>
{
if (context.HandlingKernel is IExtensibleKernel extensibleKernel)
{
if (NuGetPackagePathResolver.TryGetNuGetPackageBasePath(loadExtensionFromNuGetPackage.NugetPackageReference, loadExtensionFromNuGetPackage.MetadataReferences, out var nugetPackageDirectory))
{
await extensibleKernel.LoadExtensionsInDirectory(nugetPackageDirectory, context);
}
await extensibleKernel.LoadExtensionsInDirectory(loadExtensionsInDirectory.Directory, context);
}
else
{
context.Publish(new CommandFailed($"Kernel {context.HandlingKernel.Name} doesn't support loading extensions", loadExtensionFromNuGetPackage));
context.Publish(new CommandFailed($"Kernel {context.HandlingKernel.Name} doesn't support loading extensions", loadExtensionsInDirectory));
}
};

await next(loadExtensionFromNuGetPackage, invocationContext);
await next(loadExtensionsInDirectory, invocationContext);
}

private async Task HandleLoadExtension(
Expand Down Expand Up @@ -307,7 +304,7 @@ internal virtual async Task HandleInternalAsync(
await command.InvokeAsync(context);
}

private readonly ConcurrentQueue<KernelOperation> _commandQueue =
private readonly ConcurrentQueue<KernelOperation> _commandQueue =
new ConcurrentQueue<KernelOperation>();

public Task<IKernelCommandResult> SendAsync(
Expand Down
34 changes: 0 additions & 34 deletions Microsoft.DotNet.Interactive/NuGetPackagePathResolver.cs

This file was deleted.

13 changes: 3 additions & 10 deletions WorkspaceServer.Tests/Kernel/CSharpKernelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ public void ScriptState_is_not_null_prior_to_receiving_code_submissions()
}

[Fact]
public async Task Should_load_extension_in_nuget_package()
public async Task Should_load_extension_in_directory()
{
var directory = Create.EmptyWorkspace().Directory;

Expand All @@ -564,8 +564,6 @@ public async Task Should_load_extension_in_nuget_package()
directory.Subdirectory($"{nugetPackageName}/2.0.0"))
.CreateFiles();

var nugetPackageDll = nugetPackageDirectory.GetFullyQualifiedFilePath($"lib/netstandard2.0/{nugetPackageName}.dll");

var extensionsDir =
(FileSystemDirectoryAccessor) nugetPackageDirectory.GetDirectoryAccessorForRelativePath(new RelativeDirectoryPath("interactive-extensions/dotnet/cs"));

Expand All @@ -575,13 +573,8 @@ public async Task Should_load_extension_in_nuget_package()

var kernel = CreateKernel();

await kernel.SendAsync(
new LoadExtensionFromNuGetPackage(
new NugetPackageReference(nugetPackageName),
new List<FileInfo>
{
nugetPackageDll
}));
await kernel.SendAsync(new LoadExtensionsInDirectory(nugetPackageDirectory));


KernelEvents.Should()
.ContainSingle(e => e.Value is ExtensionLoaded &&
Expand Down
22 changes: 22 additions & 0 deletions WorkspaceServer.Tests/PackageRestoreContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using FluentAssertions;
using System.IO;
using System.Threading.Tasks;
using WorkspaceServer.Packaging;
using Xunit;
Expand All @@ -28,5 +29,26 @@ public async Task Returns_failure_if_package_installation_fails()
result.Succeeded.Should().BeFalse();
result.DetailedErrors.Should().NotBeEmpty();
}

[Fact]
public async Task Can_get_path_to_nuget_package()
{
var packageRestoreContext = new PackageRestoreContext();
await packageRestoreContext.AddPackage("fluentAssertions", "5.7.0");
var path = await packageRestoreContext.GetDirectoryForPackage("fluentassertions");
path.FullName.Should().EndWith("fluentassertions" + Path.DirectorySeparatorChar + "5.7.0");
path.Exists.Should().BeTrue();
}

[Fact]
public async Task Can_get_path_to_nuget_package_when_multiple_packages_are_added()
{
var packageRestoreContext = new PackageRestoreContext();
await packageRestoreContext.AddPackage("fluentAssertions", "5.7.0");
await packageRestoreContext.AddPackage("htmlagilitypack", "1.11.12");
var path = await packageRestoreContext.GetDirectoryForPackage("htmlagilitypack");
path.FullName.Should().EndWith("htmlagilitypack" + Path.DirectorySeparatorChar + "1.11.12");
path.Exists.Should().BeTrue();
}
}
}
4 changes: 3 additions & 1 deletion WorkspaceServer/Kernel/CSharpKernelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.DotNet.Interactive.Commands;
using Microsoft.DotNet.Interactive.Events;
using Microsoft.DotNet.Interactive.Rendering;
using MLS.Agent.Tools;
using WorkspaceServer.Packaging;

namespace WorkspaceServer.Kernel
Expand Down Expand Up @@ -103,7 +104,8 @@ public static CSharpKernel UseNugetDirective(this CSharpKernel kernel, INativeAs
context.Publish(new DisplayedValueProduced($"Successfully added reference to package {package.PackageName}, version {result.InstalledVersion}", context.Command));
context.Publish(new NuGetPackageAdded(addPackage, package));

await pipelineContext.HandlingKernel.SendAsync(new LoadExtensionFromNuGetPackage(package, result.References.Select(reference => new FileInfo(reference.Display))));
var nugetPackageDirectory = new FileSystemDirectoryAccessor(await restoreContext.GetDirectoryForPackage(package.PackageName));
await pipelineContext.HandlingKernel.SendAsync(new LoadExtensionsInDirectory(nugetPackageDirectory));
}
else
{
Expand Down
68 changes: 66 additions & 2 deletions WorkspaceServer/Packaging/PackageRestoreContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Clockwise;
Expand All @@ -12,7 +13,6 @@ namespace WorkspaceServer.Packaging
{
public partial class PackageRestoreContext
{

private readonly AsyncLazy<Package> _lazyPackage;

public PackageRestoreContext()
Expand All @@ -30,8 +30,9 @@ private async Task<Package> CreatePackage()
packageBuilder.CreateUsingDotnet("console");
packageBuilder.TrySetLanguageVersion("8.0");
packageBuilder.AddPackageReference("Newtonsoft.Json");
var package = (Package) packageBuilder.GetPackage();
var package = (Package)packageBuilder.GetPackage();
await package.CreateRoslynWorkspaceForRunAsync(new Budget());
AddDirectoryProps(package);
return package;
}

Expand Down Expand Up @@ -66,5 +67,68 @@ public async Task<IEnumerable<MetadataReference>> GetAllReferences()
var currentWorkspace = await package.CreateRoslynWorkspaceForRunAsync(new Budget());
return currentWorkspace.CurrentSolution.Projects.First().MetadataReferences;
}

public async Task<DirectoryInfo> GetDirectoryForPackage(string packageName)
{
var package = await _lazyPackage.ValueAsync();
var nugetPathsFile = package.Directory.GetFiles("*.nuget.paths").Single();
var nugetPackagePaths = File.ReadAllText(Path.Combine(package.Directory.FullName, nugetPathsFile.FullName)).Split(',','\r', '\n').Where(t => !string.IsNullOrWhiteSpace(t)).ToArray();
var pathsDictionary = nugetPackagePaths
.Select((v, i) => new { Index = i, Value = v })
.GroupBy(p => p.Index / 2)
.ToDictionary(g => g.First().Value, g => g.Last().Value, StringComparer.OrdinalIgnoreCase);

return new DirectoryInfo(pathsDictionary[packageName.ToLower()]);
}

private void AddDirectoryProps(Package package)
{
const string generatePathsPropertyTarget =
@" <Target Name=""AddGeneratePathsProperty"" BeforeTargets=""CollectPackageReferences"">
<!--Show the properties-->
<Message Text = ""Starting: Add GeneratePathProperty=true for package %(PackageReference.Identity)"" Importance = ""high"" />

<ItemGroup>
<PackageReference Condition = ""'%(PackageReference.GeneratePathProperty)' != 'true'"">
<GeneratePathProperty>true </GeneratePathProperty>
</PackageReference>
</ItemGroup>

<!--Show the changes -->
<Message Text = ""Done: GeneratePathProperty:%(PackageReference.GeneratePathProperty) for package %(PackageReference.Identity)"" Importance = ""high"" />
</Target> ";

const string computePackageRootsTarget =
@" <Target Name='ComputePackageRoots' BeforeTargets='CoreCompile;PrintNuGetPackagesPaths' DependsOnTargets='CollectPackageReferences'>
<ItemGroup>
<!-- Read the package path from the Pkg{PackageName} properties that are present in the nuget.g.props file -->
<AddedNuGetPackage Include='@(ResolvedCompileFileDefinitions)'>
<PackageRootProperty>Pkg$([System.String]::Copy('%(ResolvedCompileFileDefinitions.NugetPackageId)').Replace('.','_'))</PackageRootProperty>
<PackageRoot>$(%(AddedNuGetPackage.PackageRootProperty))</PackageRoot>
</AddedNuGetPackage>
</ItemGroup>

<Message Text=""Done: Read package root : %(AddedNuGetPackage.PackageRoot) for %(AddedNuGetPackage.NuGetPackageId)"" Condition=""%(AddedNuGetPackage.PackageRoot) != ''"" Importance=""high""/>
</Target>";

const string writePackageRootsToDiskTarget =
@" <Target Name='PrintNuGetPackagesPaths' DependsOnTargets='ResolvePackageAssets;ComputePackageRoots' AfterTargets='PrepareForBuild'>
<ItemGroup>
<ReferenceLines Remove='@(ReferenceLines)' />
<ReferenceLines Include='%(AddedNuGetPackage.NuGetPackageId),%(AddedNuGetPackage.PackageRoot)' Condition=""%(AddedNuGetPackage.PackageRoot) != ''""/>
</ItemGroup>

<WriteLinesToFile Lines='@(ReferenceLines)' File='$(MSBuildProjectFullPath).nuget.paths' Overwrite='True' WriteOnlyWhenDifferent='True' />
</Target>";

string directoryPropsContent =
$@"<Project>
{generatePathsPropertyTarget}
{computePackageRootsTarget}
{writePackageRootsToDiskTarget}
</Project>";

File.WriteAllText(Path.Combine(package.Directory.FullName, "Directory.Build.props"), directoryPropsContent);
}
}
}