/// <summary>
        /// In a dotnet-interactive REPL session (driver), nuget dependencies will be
        /// systematically added using <see cref="SparkContext.AddFile(string, bool)"/>.
        ///
        /// These files include:
        /// - "{packagename}.{version}.nupkg"
        ///   The nuget packages
        /// - <see cref="DependencyProviderUtils.CreateFileName(long)"/>
        ///   Serialized <see cref="DependencyProviderUtils.Metadata"/> object.
        ///
        /// On the Worker, in order to resolve the nuget dependencies referenced by
        /// the dotnet-interactive session, we instantiate a
        /// <see cref="DotNet.DependencyManager.DependencyProvider"/>.
        /// This provider will register an event handler to the Assembly Load Resolving event.
        /// By using <see cref="SparkFiles.GetRootDirectory"/>, we can access the
        /// required files added to the <see cref="SparkContext"/>.
        /// </summary>
        internal static void RegisterAssemblyHandler()
        {
            if (!s_runningREPL)
            {
                return;
            }

            string sparkFilesPath = SparkFiles.GetRootDirectory();

            string[] metadataFiles =
                DependencyProviderUtils.GetMetadataFiles(sparkFilesPath);
            foreach (string metdatafile in metadataFiles)
            {
                // The execution of the delegate passed to GetOrAdd is not guaranteed to run once.
                // Multiple Lazy objects may be created, but only one of them will be added to the
                // ConcurrentDictionary. The Lazy value is retrieved to materialize the
                // DependencyProvider object if it hasn't already been created.
                Lazy <DependencyProvider> dependecyProvider = s_dependencyProviders.GetOrAdd(
                    metdatafile,
                    mdf => new Lazy <DependencyProvider>(
                        () =>
                {
                    s_logger.LogInfo($"Creating {nameof(DependencyProvider)} using {mdf}");
                    return(new DependencyProvider(
                               mdf,
                               sparkFilesPath,
                               Directory.GetCurrentDirectory()));
                }));
                _ = dependecyProvider.Value;
            }
        }
示例#2
0
        public void TestsUnpackPackages()
        {
            string packageFileName = "package.name.1.0.0.nupkg";
            string packageName     = "package.name";
            string packageVersion  = "1.0.0";

            using var emptyFileDir = new TemporaryDirectory();
            string emptyFileName = "emptyfile";

            File.Create(Path.Combine(emptyFileDir.Path, emptyFileName)).Dispose();

            using var nupkgDir = new TemporaryDirectory();
            ZipFile.CreateFromDirectory(
                emptyFileDir.Path,
                Path.Combine(nupkgDir.Path, packageFileName));

            var metadata = new DependencyProviderUtils.Metadata
            {
                AssemblyProbingPaths = new string[] { "/assembly/probe/path" },
                NativeProbingPaths   = new string[] { "/native/probe/path" },
                NuGets = new DependencyProviderUtils.NuGetMetadata[]
                {
                    new DependencyProviderUtils.NuGetMetadata
                    {
                        FileName       = packageFileName,
                        PackageName    = packageName,
                        PackageVersion = packageVersion
                    }
                }
            };

            using var unpackDir = new TemporaryDirectory();
            string metadataFilePath =
                Path.Combine(nupkgDir.Path, DependencyProviderUtils.CreateFileName(1));

            metadata.Serialize(metadataFilePath);

            // Files located in nupkgDir
            // nuget: package.name.1.0.0.nupkg
            // metadata file: dependencyProviderMetadata_00000000000000000001
            var dependencyProvider =
                new DependencyProvider(metadataFilePath, nupkgDir.Path, unpackDir.Path);
            string expectedPackagePath =
                Path.Combine(unpackDir.Path, ".nuget", "packages", packageName, packageVersion);
            string expectedFilePath = Path.Combine(expectedPackagePath, emptyFileName);

            Assert.True(File.Exists(expectedFilePath));
        }
        public void TestFileNames()
        {
            using var tempDir = new TemporaryDirectory();
            foreach (long num in Enumerable.Range(0, 3).Select(x => System.Math.Pow(10, x)))
            {
                string filePath =
                    Path.Combine(tempDir.Path, DependencyProviderUtils.CreateFileName(num));
                File.Create(filePath).Dispose();
            }

            var expectedFiles = new string[]
            {
                "dependencyProviderMetadata_0000000000000000001",
                "dependencyProviderMetadata_0000000000000000010",
                "dependencyProviderMetadata_0000000000000000100",
            };
            IOrderedEnumerable <string> actualFiles = DependencyProviderUtils
                                                      .GetMetadataFiles(tempDir.Path)
                                                      .Select(f => Path.GetFileName(f))
                                                      .OrderBy(s => s);

            Assert.True(expectedFiles.SequenceEqual(actualFiles));
        }
示例#4
0
        /// <summary>
        /// Generates and serializes a <see cref="DependencyProviderUtils.Metadata"/> to
        /// <paramref name="writePath"/>. Returns a list of file paths which include the
        /// the serialized <see cref="DependencyProviderUtils.Metadata"/> and nuget file
        /// dependencies.
        /// </summary>
        /// <param name="writePath">Path to write metadata.</param>
        /// <returns>
        /// List of file paths of the serialized <see cref="DependencyProviderUtils.Metadata"/>
        /// and nuget file dependencies.
        /// </returns>
        internal IEnumerable <string> GetFiles(string writePath)
        {
            IEnumerable <ResolvedNuGetPackage> nugetPackagesToCopy = GetNewPackages();

            var assemblyProbingPaths = new List <string>();
            var nativeProbingPaths   = new List <string>();
            var nugetMetadata        = new List <DependencyProviderUtils.NuGetMetadata>();

            foreach (ResolvedNuGetPackage package in nugetPackagesToCopy)
            {
                ResolvedPackageReference resolvedPackage = package.ResolvedPackage;

                foreach (FileInfo asmPath in resolvedPackage.AssemblyPaths)
                {
                    // asmPath.FullName
                    //   /path/to/packages/package.name/package.version/lib/framework/1.dll
                    // resolvedPackage.PackageRoot
                    //   /path/to/packages/package.name/package.version/
                    // GetRelativeToPackages(..)
                    //   package.name/package.version/lib/framework/1.dll
                    assemblyProbingPaths.Add(
                        GetPathRelativeToPackages(
                            asmPath.FullName,
                            resolvedPackage.PackageRoot));
                }

                foreach (DirectoryInfo probePath in resolvedPackage.ProbingPaths)
                {
                    // probePath.FullName
                    //   /path/to/packages/package.name/package.version/
                    // resolvedPackage.PackageRoot
                    //   /path/to/packages/package.name/package.version/
                    // GetRelativeToPackages(..)
                    //   package.name/package.version
                    nativeProbingPaths.Add(
                        GetPathRelativeToPackages(
                            probePath.FullName,
                            resolvedPackage.PackageRoot));
                }

                nugetMetadata.Add(
                    new DependencyProviderUtils.NuGetMetadata
                {
                    FileName       = package.NuGetFile.Name,
                    PackageName    = resolvedPackage.PackageName,
                    PackageVersion = resolvedPackage.PackageVersion
                });

                yield return(package.NuGetFile.FullName);
            }

            if (nugetMetadata.Count > 0)
            {
                var metadataPath =
                    Path.Combine(
                        writePath,
                        DependencyProviderUtils.CreateFileName(
                            Interlocked.Increment(ref _metadataCounter)));
                new DependencyProviderUtils.Metadata
                {
                    AssemblyProbingPaths = assemblyProbingPaths.ToArray(),
                    NativeProbingPaths   = nativeProbingPaths.ToArray(),
                    NuGets = nugetMetadata.ToArray()
                }.Serialize(metadataPath);

                yield return(metadataPath);
            }
        }
示例#5
0
        public void TestPackageResolver()
        {
            using var tempDir = new TemporaryDirectory();

            string packageName     = "package.name";
            string packageVersion  = "0.1.0";
            string packageRootPath =
                Path.Combine(tempDir.Path, "path", "to", "packages", packageName, packageVersion);
            string packageFrameworkPath = Path.Combine(packageRootPath, "lib", "framework");

            Directory.CreateDirectory(packageRootPath);
            var nugetFile = new FileInfo(
                Path.Combine(packageRootPath, $"{packageName}.{packageVersion}.nupkg"));

            using (File.Create(nugetFile.FullName))
            {
            }

            var assemblyPaths = new List <FileInfo>
            {
                new FileInfo(Path.Combine(packageFrameworkPath, "1.dll")),
                new FileInfo(Path.Combine(packageFrameworkPath, "2.dll"))
            };
            var probingPaths = new List <DirectoryInfo> {
                new DirectoryInfo(packageRootPath)
            };

            var mockPackageRestoreContextWrapper = new Mock <PackageRestoreContextWrapper>();

            mockPackageRestoreContextWrapper
            .SetupGet(m => m.ResolvedPackageReferences)
            .Returns(new ResolvedPackageReference[]
            {
                new ResolvedPackageReference(
                    packageName,
                    packageVersion,
                    assemblyPaths,
                    new DirectoryInfo(packageRootPath),
                    probingPaths)
            });

            var packageResolver = new PackageResolver(mockPackageRestoreContextWrapper.Object);
            IEnumerable <string> actualFiles = packageResolver.GetFiles(tempDir.Path);

            string metadataFilePath =
                Path.Combine(tempDir.Path, DependencyProviderUtils.CreateFileName(1));
            var expectedFiles = new string[]
            {
                nugetFile.FullName,
                metadataFilePath
            };

            Assert.True(expectedFiles.SequenceEqual(actualFiles));
            Assert.True(File.Exists(metadataFilePath));

            DependencyProviderUtils.Metadata actualMetadata =
                DependencyProviderUtils.Metadata.Deserialize(metadataFilePath);
            var expectedMetadata = new DependencyProviderUtils.Metadata
            {
                AssemblyProbingPaths = new string[]
                {
                    Path.Combine(packageName, packageVersion, "lib", "framework", "1.dll"),
                    Path.Combine(packageName, packageVersion, "lib", "framework", "2.dll")
                },
                NativeProbingPaths = new string[]
                {
                    Path.Combine(packageName, packageVersion)
                },
                NuGets = new DependencyProviderUtils.NuGetMetadata[]
                {
                    new DependencyProviderUtils.NuGetMetadata
                    {
                        FileName       = $"{packageName}.{packageVersion}.nupkg",
                        PackageName    = packageName,
                        PackageVersion = packageVersion
                    }
                }
            };

            Assert.True(expectedMetadata.Equals(actualMetadata));
        }