public void TestWritingNewPackages() { var page = new WorkbookPage(new WorkbookPackage()); var packageVersion = "9.0.1"; var package = new InteractivePackage("Fake.Package1", VersionRange.Parse(packageVersion)); page.Manifest.Packages = page.Manifest.Packages.Add(package); var writer = new StringWriter(); page.Write(writer, null); var serializedPage = writer.ToString(); var deserializedPage = new WorkbookPage(new WorkbookPackage()); deserializedPage.Read(new StringReader(serializedPage)); deserializedPage.Packages.Length.ShouldEqual(1); var deserializedPackage = deserializedPage.Packages [0]; deserializedPackage.Identity.Id.ShouldEqual(package.Identity.Id); // Make sure this doesn't serialize as [9.0.1, ) deserializedPackage.SupportedVersionRange.OriginalString.ShouldEqual(packageVersion); }
void ReferencePackageInWorkspace(InteractivePackage package) { foreach (var packageAssemblyReference in package.AssemblyReferences) { CompilationWorkspace.DependencyResolver.AddAssemblySearchPath( packageAssemblyReference.ParentDirectory); } }
public NuGetPackageNode(InteractivePackage package) { IconName = "nuget"; RepresentedObject = package; Name = package.Identity.Id; // Version is set if the package has been restored, otherwise use SupportedVersionRange to show // what's in the manifest. ToolTip = $"{Name} {package.Identity.Version?.ToString () ?? package.SupportedVersionRange?.ToString ()}"; Commands = new [] { RemovePackage }; }
async Task ReferenceTopLevelPackageAsync( InteractivePackage package, CancellationToken cancellationToken) { if (package.AssemblyReferences.Count == 0) { return; } var referenceBuffer = new StringBuilder(); foreach (var packageAssemblyReference in package.AssemblyReferences) { var resolvedAssembly = CompilationWorkspace .DependencyResolver .ResolveWithoutReferences(packageAssemblyReference); if (resolvedAssembly == null) { continue; } if (BannedReferencePrefixes.Any(resolvedAssembly.AssemblyName.Name.StartsWith)) { continue; } // Don't add #r for integration assemblies. if (HasIntegration(resolvedAssembly)) { continue; } if (referenceBuffer.Length > 0) { referenceBuffer.AppendLine(); } referenceBuffer .Append("#r \"") .Append(resolvedAssembly.AssemblyName.Name) .Append("\""); } if (referenceBuffer.Length > 0) { await WorkbookPageViewModel.EvaluateAsync(referenceBuffer.ToString(), cancellationToken); } }
public async Task InstallPackageAsync( PackageViewModel packageViewModel, CancellationToken cancellationToken = default(CancellationToken)) { var package = new InteractivePackage(packageViewModel.Package); var installedPackages = await Workbook.Packages.InstallPackageAsync( package, packageViewModel.SourceRepository, cancellationToken); // TODO: Should probably alert user that the package is already installed. // Should we add a fresh #r for the package in case that's what they're trying to get? // A feel good thing? if (installedPackages.Count == 0) { return; } foreach (var installedPackage in installedPackages) { ReferencePackageInWorkspace(installedPackage); await LoadPackageIntegrationsAsync(installedPackage, cancellationToken); } // TODO: Figure out metapackages. Install Microsoft.AspNet.SignalR, for example, // and no #r submission gets generated, so all the workspace reference stuff // above fails to bring in references to dependnet assemblies automatically. // User must type them out themselves. // // This was busted in our NuGet 2.x code as well. package = installedPackages.FirstOrDefault( p => PackageIdComparer.Equals(p, package)); // TODO: Same issue as installedPackages.Count == 0. What do we want to tell user? // probably they tried to install a package they already had installed, and // maybe it bumped a shared dep (which is why installedPackages is non-empty). if (package == null) { return; } await ReferenceTopLevelPackageAsync( package, cancellationToken); }
async Task LoadPackageIntegrationsAsync( InteractivePackage package, CancellationToken cancellationToken) { // Forms is special-cased because we own it and load the extension from our framework. if (PackageIdComparer.Equals(package.Identity.Id, "Xamarin.Forms")) { await CompilationWorkspaceFactory.LoadFormsAgentExtensions( package.Identity.Version.Version, this, CompilationWorkspace.DependencyResolver, CompilationWorkspace.EvaluationContextId, Agent.IncludePeImage); } var assembliesToLoadOnAgent = new List <ResolvedAssembly> (); // Integration assemblies are not expected to be in a TFM directory—we look for them in // the `xamarin.interactive` folder inside the NuGet package. var packagePath = Workbook .Packages .GetPackageInstallPath(package); var interactivePath = packagePath.Combine("xamarin.interactive"); if (interactivePath.DirectoryExists) { var interactiveAssemblies = interactivePath.EnumerateFiles("*.dll"); foreach (var interactiveReference in interactiveAssemblies) { var resolvedAssembly = CompilationWorkspace .DependencyResolver .ResolveWithoutReferences(interactiveReference); if (HasIntegration(resolvedAssembly)) { assembliesToLoadOnAgent.Add(resolvedAssembly); foreach (var dependency in resolvedAssembly.ExternalDependencies) { if (!(dependency is WebDependency)) { continue; } if (AddNuGetWebResource(dependency.Location, out var id)) { await WorkbookPageViewModel.LoadWorkbookDependencyAsync($"/static/{id}"); } } } } } if (assembliesToLoadOnAgent.Count > 0) { var assembliesToLoad = assembliesToLoadOnAgent.Select(dep => { var peImage = Agent.IncludePeImage ? GetFileBytes(dep.Path) : null; var syms = Agent.IncludePeImage ? GetDebugSymbolsFromAssemblyPath(dep.Path) : null; return(new AssemblyDefinition( dep.AssemblyName, dep.Path, peImage: peImage, debugSymbols: syms )); }).ToArray(); await Agent.Api.LoadAssembliesAsync( CompilationWorkspace.EvaluationContextId, assembliesToLoad); } await RefreshForAgentIntegration(); }