예제 #1
0
        public void DnuPackagesAddOverwritesInstalledPackageWhenShasDoNotMatch(string flavor, string os, string architecture)
        {
            var runtimeHomeDir = TestUtils.GetRuntimeHomeDir(flavor, os, architecture);

            using (var tempSamplesDir = TestUtils.PrepareTemporarySamplesFolder(runtimeHomeDir))
            {
                var projectFilePath     = Path.Combine(tempSamplesDir, ProjectName, Runtime.Project.ProjectFileName);
                var packagesDir         = Path.Combine(tempSamplesDir, PackagesDirName);
                var packagePathResolver = new DefaultPackagePathResolver(packagesDir);
                var nuspecPath          = packagePathResolver.GetManifestFilePath(ProjectName, ProjectVersion);

                SetProjectDescription(projectFilePath, "Old");
                BuildPackage(tempSamplesDir, runtimeHomeDir);

                string stdOut;
                var    exitCode = DnuPackagesAddOutputPackage(tempSamplesDir, runtimeHomeDir, out stdOut);
                Assert.Equal(0, exitCode);
                Assert.Contains($"Installing {ProjectName}.{ProjectVersion}", stdOut);

                var lastInstallTime = new FileInfo(nuspecPath).LastWriteTimeUtc;

                SetProjectDescription(projectFilePath, "New");
                BuildPackage(tempSamplesDir, runtimeHomeDir);

                exitCode = DnuPackagesAddOutputPackage(tempSamplesDir, runtimeHomeDir, out stdOut);
                Assert.Equal(0, exitCode);
                Assert.Contains($"Overwriting {ProjectName}.{ProjectVersion}", stdOut);

                var xDoc = XDocument.Load(packagePathResolver.GetManifestFilePath(ProjectName, ProjectVersion));
                var actualDescription = xDoc.Root.Descendants()
                                        .Single(x => string.Equals(x.Name.LocalName, "description")).Value;
                Assert.Equal("New", actualDescription);
                Assert.NotEqual(lastInstallTime, new FileInfo(nuspecPath).LastWriteTimeUtc);
            }
        }
예제 #2
0
        public void DnuPackagesAddSkipsInstalledPackageWhenShasMatch(string flavor, string os, string architecture)
        {
            var runtimeHomeDir = TestUtils.GetRuntimeHomeDir(flavor, os, architecture);

            using (var tempSamplesDir = TestUtils.PrepareTemporarySamplesFolder(runtimeHomeDir))
            {
                var projectFilePath     = Path.Combine(tempSamplesDir, ProjectName, Runtime.Project.ProjectFileName);
                var packagesDir         = Path.Combine(tempSamplesDir, PackagesDirName);
                var packagePathResolver = new DefaultPackagePathResolver(packagesDir);
                var nuspecPath          = packagePathResolver.GetManifestFilePath(ProjectName, ProjectVersion);

                BuildPackage(tempSamplesDir, runtimeHomeDir);

                string stdOut;
                var    exitCode = DnuPackagesAddOutputPackage(tempSamplesDir, runtimeHomeDir, out stdOut);
                Assert.Equal(0, exitCode);
                Assert.Contains($"Installing {ProjectName}.{ProjectVersion}", stdOut);

                var lastInstallTime = new FileInfo(nuspecPath).LastWriteTimeUtc;

                exitCode = DnuPackagesAddOutputPackage(tempSamplesDir, runtimeHomeDir, out stdOut);
                Assert.Equal(0, exitCode);
                Assert.Contains($"{ProjectName}.{ProjectVersion} already exists", stdOut);
                Assert.Equal(lastInstallTime, new FileInfo(nuspecPath).LastWriteTimeUtc);
            }
        }
예제 #3
0
        internal static async Task InstallFromStream(Stream stream, Library library, string packagesDirectory,
                                                     SHA512 sha512)
        {
            var packagePathResolver = new DefaultPackagePathResolver(packagesDirectory);

            var targetPath   = packagePathResolver.GetInstallPath(library.Name, library.Version);
            var targetNuspec = packagePathResolver.GetManifestFilePath(library.Name, library.Version);
            var targetNupkg  = packagePathResolver.GetPackageFilePath(library.Name, library.Version);
            var hashPath     = packagePathResolver.GetHashPath(library.Name, library.Version);

            // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
            // processes are extracting to the same destination simultaneously
            await ConcurrencyUtilities.ExecuteWithFileLocked(targetNupkg, async createdNewLock =>
            {
                // If this is the first process trying to install the target nupkg, go ahead
                // After this process successfully installs the package, all other processes
                // waiting on this lock don't need to install it again
                if (createdNewLock)
                {
                    Directory.CreateDirectory(targetPath);
                    using (var nupkgStream = new FileStream(targetNupkg, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete))
                    {
                        await stream.CopyToAsync(nupkgStream);
                        nupkgStream.Seek(0, SeekOrigin.Begin);

                        ExtractPackage(targetPath, nupkgStream);
                    }

                    //// Fixup the casing of the nuspec on disk to match what we expect
                    //var nuspecFile = Directory.EnumerateFiles(targetPath, "*" + Constants.ManifestExtension).Single();

                    //if (!string.Equals(nuspecFile, targetNuspec, StringComparison.Ordinal))
                    //{
                    //    Manifest manifest = null;
                    //    using (var nuspecStream = File.OpenRead(nuspecFile))
                    //    {
                    //        manifest = Manifest.ReadFrom(nuspecStream, validateSchema: false);
                    //        manifest.Metadata.Id = library.Name;
                    //    }

                    //    // Delete the previous nuspec file
                    //    File.Delete(nuspecFile);

                    //    // Write the new manifest
                    //    using (var targetNuspecStream = File.OpenWrite(targetNuspec))
                    //    {
                    //        manifest.Save(targetNuspecStream);
                    //    }
                    //}

                    stream.Seek(0, SeekOrigin.Begin);
                    var nupkgSHA = Convert.ToBase64String(sha512.ComputeHash(stream));
                    File.WriteAllText(hashPath, nupkgSHA);
                }

                return(0);
            });
        }
예제 #4
0
        private bool PrunePackages(PublishRoot root)
        {
            var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath);

            // Special cases (for backwards compat)
            var specialFolders = new List <string> {
                "native",
                "InteropAssemblies",
                "redist"
            };

            if (!root.NoSource)
            {
                // 'shared' folder is build time dependency, so we only copy it when deploying with source
                specialFolders.Add("shared");
            }

            var lockFilePath = Path.GetFullPath(Path.Combine(ApplicationBasePath, LockFileFormat.LockFileName));
            var format       = new LockFileFormat();

            root.LockFile = format.Read(lockFilePath);

            var keep = new HashSet <string>();

            foreach (var target in root.LockFile.Targets)
            {
                foreach (var library in target.Libraries)
                {
                    var packagesDir = resolver.GetInstallPath(library.Name, library.Version);
                    var manifest    = resolver.GetManifestFilePath(library.Name, library.Version);

                    keep.Add(manifest);

                    foreach (var path in library.RuntimeAssemblies)
                    {
                        keep.Add(CombinePath(packagesDir, path));
                    }

                    foreach (var path in library.CompileTimeAssemblies)
                    {
                        keep.Add(CombinePath(packagesDir, path));
                    }

                    foreach (var path in library.NativeLibraries)
                    {
                        keep.Add(CombinePath(packagesDir, path));
                    }

                    foreach (var specialFolder in specialFolders)
                    {
                        var specialFolderPath = CombinePath(packagesDir, specialFolder);

                        if (!Directory.Exists(specialFolderPath))
                        {
                            continue;
                        }

                        keep.AddRange(Directory.EnumerateFiles(specialFolderPath, "*.*", SearchOption.AllDirectories));
                    }
                }
            }

            foreach (var package in root.Packages)
            {
                var packageDir   = resolver.GetInstallPath(package.Library.Name, package.Library.Version);
                var packageFiles = Directory.EnumerateFiles(packageDir, "*.*", SearchOption.AllDirectories);

                foreach (var file in packageFiles)
                {
                    if (!keep.Contains(file))
                    {
                        File.Delete(file);
                    }
                }

                root.Operations.DeleteEmptyFolders(packageDir);
            }

            return(true);
        }
예제 #5
0
        private async Task InstallPackages(List <GraphItem> installItems, string packagesDirectory, Func <Library, string, bool> packageFilter)
        {
            var packagePathResolver = new DefaultPackagePathResolver(packagesDirectory);

            using (var sha512 = SHA512.Create())
            {
                foreach (var item in installItems)
                {
                    var library = item.Match.Library;

                    var memStream = new MemoryStream();
                    await item.Match.Provider.CopyToAsync(item.Match, memStream);

                    memStream.Seek(0, SeekOrigin.Begin);
                    var nupkgSHA = Convert.ToBase64String(sha512.ComputeHash(memStream));

                    bool shouldInstall = packageFilter(library, nupkgSHA);
                    if (!shouldInstall)
                    {
                        continue;
                    }

                    Reports.Information.WriteLine(string.Format("Installing {0} {1}", library.Name.Bold(), library.Version));

                    var targetPath   = packagePathResolver.GetInstallPath(library.Name, library.Version);
                    var targetNuspec = packagePathResolver.GetManifestFilePath(library.Name, library.Version);
                    var targetNupkg  = packagePathResolver.GetPackageFilePath(library.Name, library.Version);
                    var hashPath     = packagePathResolver.GetHashPath(library.Name, library.Version);

                    // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
                    // processes are extracting to the same destination simultaneously
                    await ConcurrencyUtilities.ExecuteWithFileLocked(targetNupkg, async createdNewLock =>
                    {
                        // If this is the first process trying to install the target nupkg, go ahead
                        // After this process successfully installs the package, all other processes
                        // waiting on this lock don't need to install it again
                        if (createdNewLock)
                        {
                            Directory.CreateDirectory(targetPath);
                            using (var stream = new FileStream(targetNupkg, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete))
                            {
                                await item.Match.Provider.CopyToAsync(item.Match, stream);
                                stream.Seek(0, SeekOrigin.Begin);

                                ExtractPackage(targetPath, stream);
                            }

                            // Fixup the casing of the nuspec on disk to match what we expect
                            var nuspecFile = Directory.EnumerateFiles(targetPath, "*" + Constants.ManifestExtension).Single();

                            if (!string.Equals(nuspecFile, targetNuspec, StringComparison.Ordinal))
                            {
                                Manifest manifest = null;
                                using (var stream = File.OpenRead(nuspecFile))
                                {
                                    manifest             = Manifest.ReadFrom(stream, validateSchema: false);
                                    manifest.Metadata.Id = library.Name;
                                }

                                // Delete the previous nuspec file
                                File.Delete(nuspecFile);

                                // Write the new manifest
                                using (var stream = File.OpenWrite(targetNuspec))
                                {
                                    manifest.Save(stream);
                                }
                            }

                            // Ensure the manifest file name matches
                            File.WriteAllText(hashPath, nupkgSHA);
                        }

                        return(0);
                    });
                }
            }
        }
예제 #6
0
        internal static async Task InstallFromStream(
            Stream stream,
            LibraryIdentity library,
            string packagesDirectory,
            IReport information,
            string packageHash = null)
        {
            var packagePathResolver = new DefaultPackagePathResolver(packagesDirectory);

            var targetPath     = packagePathResolver.GetInstallPath(library.Name, library.Version);
            var targetNuspec   = packagePathResolver.GetManifestFilePath(library.Name, library.Version);
            var targetNupkg    = packagePathResolver.GetPackageFilePath(library.Name, library.Version);
            var targetHashPath = packagePathResolver.GetHashPath(library.Name, library.Version);

            // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
            // processes are extracting to the same destination simultaneously
            await ConcurrencyUtilities.ExecuteWithFileLocked(targetNupkg, action : async _ =>
            {
                if (string.IsNullOrEmpty(packageHash))
                {
                    using (var sha512 = SHA512.Create())
                    {
                        packageHash = Convert.ToBase64String(sha512.ComputeHash(stream));
                    }
                }

                var actionName           = "Installing";
                var installedPackageHash = string.Empty;
                if (File.Exists(targetHashPath) && File.Exists(targetNuspec))
                {
                    installedPackageHash = File.ReadAllText(targetHashPath);
                    actionName           = "Overwriting";
                }

                if (string.Equals(packageHash, installedPackageHash, StringComparison.Ordinal))
                {
                    information.WriteLine($"{library.Name}.{library.Version} already exists");
                }
                else
                {
                    information.WriteLine($"{actionName} {library.Name}.{library.Version}");

                    Directory.CreateDirectory(targetPath);
                    using (var nupkgStream = new FileStream(
                               targetNupkg,
                               FileMode.Create,
                               FileAccess.ReadWrite,
                               FileShare.ReadWrite | FileShare.Delete,
                               bufferSize: 4096,
                               useAsync: true))
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                        await stream.CopyToAsync(nupkgStream);
                        nupkgStream.Seek(0, SeekOrigin.Begin);

                        ExtractPackage(targetPath, nupkgStream);
                    }

                    // Fixup the casing of the nuspec on disk to match what we expect
                    var nuspecFile = Directory.EnumerateFiles(targetPath, "*" + NuGet.Constants.ManifestExtension).Single();

                    Manifest manifest = null;
                    using (var nuspecStream = File.OpenRead(nuspecFile))
                    {
                        manifest                  = Manifest.ReadFrom(nuspecStream, validateSchema: false);
                        manifest.Metadata.Id      = library.Name;
                        manifest.Metadata.Version = library.Version;
                    }

                    // Delete the previous nuspec file
                    File.Delete(nuspecFile);

                    // Write the new manifest
                    using (var targetNuspecStream = File.OpenWrite(targetNuspec))
                    {
                        manifest.Save(targetNuspecStream);
                    }

                    // Note: PackageRepository relies on the hash file being written out as the final operation as part of a package install
                    // to assume a package was fully installed.
                    File.WriteAllText(targetHashPath, packageHash);
                }

                return(0);
            });
        }
예제 #7
0
        internal static async Task InstallFromStream(
            Stream stream,
            LibraryIdentity library,
            string packagesDirectory,
            ILogger log)
        {
            var packagePathResolver = new DefaultPackagePathResolver(packagesDirectory);

            var targetPath   = packagePathResolver.GetInstallPath(library.Name, library.Version);
            var targetNuspec = packagePathResolver.GetManifestFilePath(library.Name, library.Version);
            var targetNupkg  = packagePathResolver.GetPackageFilePath(library.Name, library.Version);
            var hashPath     = packagePathResolver.GetHashPath(library.Name, library.Version);

            // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
            // processes are extracting to the same destination simultaneously
            await ConcurrencyUtilities.ExecuteWithFileLocked(targetNupkg, async createdNewLock =>
            {
                // If this is the first process trying to install the target nupkg, go ahead
                // After this process successfully installs the package, all other processes
                // waiting on this lock don't need to install it again.
                if (createdNewLock && !File.Exists(targetNupkg))
                {
                    log.LogInformation($"Installing {library.Name} {library.Version}");

                    Directory.CreateDirectory(targetPath);
                    using (var nupkgStream = new FileStream(
                               targetNupkg,
                               FileMode.Create,
                               FileAccess.ReadWrite,
                               FileShare.ReadWrite | FileShare.Delete,
                               bufferSize: 4096,
                               useAsync: true))
                    {
                        await stream.CopyToAsync(nupkgStream);
                        nupkgStream.Seek(0, SeekOrigin.Begin);

                        ExtractPackage(targetPath, nupkgStream);
                    }

                    // DNU REFACTORING TODO: delete the hacky FixNuSpecIdCasing() and uncomment logic below after we
                    // have implementation of NuSpecFormatter.Read()
                    // Fixup the casing of the nuspec on disk to match what we expect
                    var nuspecFile = Directory.EnumerateFiles(targetPath, "*" + ManifestExtension).Single();
                    FixNuSpecIdCasing(nuspecFile, targetNuspec, library.Name);

                    /*var actualNuSpecName = Path.GetFileName(nuspecFile);
                     * var expectedNuSpecName = Path.GetFileName(targetNuspec);
                     *
                     * if (!string.Equals(actualNuSpecName, expectedNuSpecName, StringComparison.Ordinal))
                     * {
                     * MetadataBuilder metadataBuilder = null;
                     * var nuspecFormatter = new NuSpecFormatter();
                     * using (var nuspecStream = File.OpenRead(nuspecFile))
                     * {
                     *  metadataBuilder = nuspecFormatter.Read(nuspecStream);
                     *  // REVIEW: any way better hardcoding "id"?
                     *  metadataBuilder.SetMetadataValue("id", library.Name);
                     * }
                     *
                     * // Delete the previous nuspec file
                     * File.Delete(nuspecFile);
                     *
                     * // Write the new manifest
                     * using (var targetNuspecStream = File.OpenWrite(targetNuspec))
                     * {
                     *  nuspecFormatter.Save(metadataBuilder, targetNuspecStream);
                     * }
                     * }*/

                    stream.Seek(0, SeekOrigin.Begin);
                    string packageHash;
                    using (var sha512 = SHA512.Create())
                    {
                        packageHash = Convert.ToBase64String(sha512.ComputeHash(stream));
                    }

                    // Note: PackageRepository relies on the hash file being written out as the final operation as part of a package install
                    // to assume a package was fully installed.
                    File.WriteAllText(hashPath, packageHash);
                }

                return(0);
            });
        }
예제 #8
0
        internal static async Task InstallFromStream(Stream stream,
                                                     Library library,
                                                     string packagesDirectory,
                                                     SHA512 sha512,
                                                     bool performingParallelInstalls = false)
        {
            var packagePathResolver = new DefaultPackagePathResolver(packagesDirectory);

            var targetPath   = packagePathResolver.GetInstallPath(library.Name, library.Version);
            var targetNuspec = packagePathResolver.GetManifestFilePath(library.Name, library.Version);
            var targetNupkg  = packagePathResolver.GetPackageFilePath(library.Name, library.Version);
            var hashPath     = packagePathResolver.GetHashPath(library.Name, library.Version);

            // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
            // processes are extracting to the same destination simultaneously
            await ConcurrencyUtilities.ExecuteWithFileLocked(targetNupkg, async createdNewLock =>
            {
                // If this is the first process trying to install the target nupkg, go ahead
                // After this process successfully installs the package, all other processes
                // waiting on this lock don't need to install it again.
                if (createdNewLock && !File.Exists(targetNupkg))
                {
                    var extractPath = targetPath;
                    if (performingParallelInstalls)
                    {
                        // Extracting to the {id}/{version} has an issue with concurrent installs - when a package has been partially
                        // extracted, the Restore Operation can inadvertly conclude the package is available locally and proceed to read
                        // partially written package contents. To avoid this we'll extract the package to a sibling directory and Move it
                        // to the target path.
                        extractPath = Path.Combine(Path.GetDirectoryName(targetPath), Path.GetRandomFileName());
                        targetNupkg = Path.Combine(extractPath, Path.GetFileName(targetNupkg));
                    }

                    var extractDirectory = Directory.CreateDirectory(extractPath);
                    using (var nupkgStream = new FileStream(
                               targetNupkg,
                               FileMode.Create,
                               FileAccess.ReadWrite,
                               FileShare.ReadWrite | FileShare.Delete,
                               bufferSize: 4096,
                               useAsync: true))
                    {
                        await stream.CopyToAsync(nupkgStream);
                        nupkgStream.Seek(0, SeekOrigin.Begin);

                        ExtractPackage(extractPath, nupkgStream);
                    }

                    // Fixup the casing of the nuspec on disk to match what we expect
                    var nuspecFile = Directory.EnumerateFiles(targetPath, "*" + NuGet.Constants.ManifestExtension).Single();

                    if (!string.Equals(nuspecFile, targetNuspec, StringComparison.Ordinal))
                    {
                        Manifest manifest = null;
                        using (var nuspecStream = File.OpenRead(nuspecFile))
                        {
                            manifest             = Manifest.ReadFrom(nuspecStream, validateSchema: false);
                            manifest.Metadata.Id = library.Name;
                        }

                        // Delete the previous nuspec file
                        File.Delete(nuspecFile);

                        // Write the new manifest
                        using (var targetNuspecStream = File.OpenWrite(targetNuspec))
                        {
                            manifest.Save(targetNuspecStream);
                        }
                    }

                    stream.Seek(0, SeekOrigin.Begin);
                    var nupkgSHA = Convert.ToBase64String(sha512.ComputeHash(stream));
                    File.WriteAllText(hashPath, nupkgSHA);

                    if (performingParallelInstalls)
                    {
                        extractDirectory.MoveTo(targetPath);
                    }
                }

                return(0);
            });
        }