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); }); }
public void Emit(PackRoot root) { var package = _nugetDependencyResolver.FindCandidate( _libraryDescription.Identity.Name, _libraryDescription.Identity.Version); Console.WriteLine("Packing nupkg dependency {0} {1}", package.Id, package.Version); var resolver = new DefaultPackagePathResolver(root.PackagesPath); TargetPath = resolver.GetInstallPath(package.Id, package.Version); if (Directory.Exists(TargetPath)) { if (root.Overwrite) { root.Operations.Delete(TargetPath); } else { Console.WriteLine(" {0} already exists.", TargetPath); return; } } Console.WriteLine(" Target {0}", TargetPath); var targetNupkgPath = resolver.GetPackageFilePath(package.Id, package.Version); var hashPath = resolver.GetHashPath(package.Id, package.Version); using (var sourceStream = package.GetStream()) { using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read)) { root.Operations.ExtractNupkg(archive, TargetPath); } } using (var sourceStream = package.GetStream()) { using (var targetStream = new FileStream(targetNupkgPath, FileMode.Create, FileAccess.Write, FileShare.None)) { sourceStream.CopyTo(targetStream); } sourceStream.Seek(0, SeekOrigin.Begin); var sha512Bytes = SHA512.Create().ComputeHash(sourceStream); File.WriteAllText(hashPath, Convert.ToBase64String(sha512Bytes)); } }
public void Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library); var packagePathResolver = new DefaultPackagePathResolver(root.SourcePackagesPath); var srcNupkgPath = packagePathResolver.GetPackageFilePath(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version); var options = new Microsoft.Framework.PackageManager.Packages.AddOptions { NuGetPackage = srcNupkgPath, SourcePackages = root.TargetPackagesPath, Reports = root.Reports }; var packagesAddCommand = new Microsoft.Framework.PackageManager.Packages.AddCommand(options); packagesAddCommand.Execute().GetAwaiter().GetResult(); }
public async Task Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library); var packagePathResolver = new DefaultPackagePathResolver(root.SourcePackagesPath); var srcNupkgPath = packagePathResolver.GetPackageFilePath(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version); var options = new Packages.AddOptions { NuGetPackage = srcNupkgPath, PackageHashFilePath = Path.ChangeExtension(srcNupkgPath, NuGet.Constants.HashFileExtension), SourcePackages = root.TargetPackagesPath, }; // Mute "packages add" subcommand options.Reports = Reports.Constants.NullReports; var packagesAddCommand = new Packages.AddCommand(options); await packagesAddCommand.Execute(); }
private async Task <bool> RestoreForProject(LocalPackageRepository localRepository, string projectJsonPath, string rootDirectory, string packagesDirectory) { var success = true; Reports.Information.WriteLine(string.Format("Restoring packages for {0}", projectJsonPath.Bold())); var sw = new Stopwatch(); sw.Start(); Project project; if (!Project.TryGetProject(projectJsonPath, out project)) { throw new Exception("TODO: project.json parse error"); } Func <string, string> getVariable = key => { return(null); }; ScriptExecutor.Execute(project, "prerestore", getVariable); var projectDirectory = project.ProjectDirectory; var restoreOperations = new RestoreOperations { Report = Reports.Information }; var projectProviders = new List <IWalkProvider>(); var localProviders = new List <IWalkProvider>(); var remoteProviders = new List <IWalkProvider>(); var contexts = new List <RestoreContext>(); projectProviders.Add( new LocalWalkProvider( new ProjectReferenceDependencyProvider( new ProjectResolver( projectDirectory, rootDirectory)))); localProviders.Add( new LocalWalkProvider( new NuGetDependencyResolver( packagesDirectory, new EmptyFrameworkResolver()))); var allSources = SourceProvider.LoadPackageSources(); var enabledSources = Sources.Any() ? Enumerable.Empty <PackageSource>() : allSources.Where(s => s.IsEnabled); var addedSources = Sources.Concat(FallbackSources).Select( value => allSources.FirstOrDefault(source => CorrectName(value, source)) ?? new PackageSource(value)); var effectiveSources = enabledSources.Concat(addedSources).Distinct().ToList(); foreach (var source in effectiveSources) { if (new Uri(source.Source).IsFile) { remoteProviders.Add( new RemoteWalkProvider( new PackageFolder( source.Source, Reports.Verbose))); } else { remoteProviders.Add( new RemoteWalkProvider( new PackageFeed( source.Source, source.UserName, source.Password, NoCache, Reports.Verbose))); } } foreach (var configuration in project.GetTargetFrameworks()) { var context = new RestoreContext { FrameworkName = configuration.FrameworkName, ProjectLibraryProviders = projectProviders, LocalLibraryProviders = localProviders, RemoteLibraryProviders = remoteProviders, }; contexts.Add(context); } if (!contexts.Any()) { contexts.Add(new RestoreContext { FrameworkName = ApplicationEnvironment.TargetFramework, ProjectLibraryProviders = projectProviders, LocalLibraryProviders = localProviders, RemoteLibraryProviders = remoteProviders, }); } var tasks = new List <Task <GraphNode> >(); foreach (var context in contexts) { tasks.Add(restoreOperations.CreateGraphNode(context, new Library { Name = project.Name, Version = project.Version }, _ => true)); } var graphs = await Task.WhenAll(tasks); Reports.Information.WriteLine(string.Format("{0}, {1}ms elapsed", "Resolving complete".Green(), sw.ElapsedMilliseconds)); var installItems = new List <GraphItem>(); var missingItems = new List <Library>(); ForEach(graphs, node => { if (node == null || node.Library == null) { return; } if (node.Item == null || node.Item.Match == null) { if (node.Library.Version != null && !missingItems.Contains(node.Library)) { missingItems.Add(node.Library); Reports.Information.WriteLine(string.Format("Unable to locate {0} >= {1}", node.Library.Name.Red().Bold(), node.Library.Version)); success = false; } return; } var isRemote = remoteProviders.Contains(node.Item.Match.Provider); var isAdded = installItems.Any(item => item.Match.Library == node.Item.Match.Library); if (!isAdded && isRemote) { installItems.Add(node.Item); } }); var dependencies = new Dictionary <Library, string>(); // If there is a global.json file specified, we should do SHA value verification var globalJsonFileSpecified = !string.IsNullOrEmpty(GlobalJsonFile); JToken dependenciesNode = null; if (globalJsonFileSpecified) { var globalJson = JObject.Parse(File.ReadAllText(GlobalJsonFile)); dependenciesNode = globalJson["dependencies"]; if (dependenciesNode != null) { dependencies = dependenciesNode .OfType <JProperty>() .ToDictionary(d => new Library() { Name = d.Name, Version = SemanticVersion.Parse(d.Value.Value <string>("version")) }, d => d.Value.Value <string>("sha")); } } 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)); string expectedSHA; if (dependencies.TryGetValue(library, out expectedSHA)) { if (!string.Equals(expectedSHA, nupkgSHA, StringComparison.Ordinal)) { Reports.Information.WriteLine( string.Format("SHA of downloaded package {0} doesn't match expected value.".Red().Bold(), library.ToString())); success = false; continue; } } else { // Report warnings only when given global.json contains "dependencies" if (globalJsonFileSpecified && dependenciesNode != null) { Reports.Information.WriteLine( string.Format("Expected SHA of package {0} doesn't exist in given global.json file.".Yellow().Bold(), library.ToString())); } } Reports.Information.WriteLine(string.Format("Installing {0} {1}", library.Name.Bold(), library.Version)); var targetPath = packagePathResolver.GetInstallPath(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); } File.WriteAllText(hashPath, nupkgSHA); } return(0); }); } } ScriptExecutor.Execute(project, "postrestore", getVariable); ScriptExecutor.Execute(project, "prepare", getVariable); Reports.Information.WriteLine(string.Format("{0}, {1}ms elapsed", "Restore complete".Green().Bold(), sw.ElapsedMilliseconds)); // Print the dependency graph if (success) { var graphNum = contexts.Count; for (int i = 0; i < graphNum; i++) { PrintDependencyGraph(graphs[i], contexts[i].FrameworkName); } } return(success); }
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); }); } } }
private void PrunePackages(PublishRoot root) { if (root.MainProjectLockFile == null) { return; } var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); var lockFilePath = Path.GetFullPath(Path.Combine(ApplicationBasePath, LockFileFormat.LockFileName)); root.PublishedLockFile = new LockFileFormat().Read(lockFilePath); var filesToKeep = new HashSet <string>(); var filesToRemove = new HashSet <string>(); foreach (var target in root.PublishedLockFile.Targets) { foreach (var library in target.Libraries) { var packageDir = resolver.GetInstallPath(library.Name, library.Version); if (library.Name != root.MainProjectName && string.Equals(library.Type, Runtime.LibraryTypes.Package, StringComparison.OrdinalIgnoreCase)) { filesToRemove.Add(resolver.GetHashPath(library.Name, library.Version)); filesToRemove.Add(resolver.GetPackageFilePath(library.Name, library.Version)); filesToRemove.AddRange(Directory.EnumerateFiles(packageDir, $"{library.Name}.xml", SearchOption.AllDirectories)); } foreach (var path in library.RuntimeAssemblies) { filesToKeep.Add(Path.Combine(packageDir, path)); } foreach (var path in library.CompileTimeAssemblies) { filesToKeep.Add(Path.Combine(packageDir, path)); } foreach (var path in library.NativeLibraries) { filesToKeep.Add(Path.Combine(packageDir, path)); } foreach (var path in library.ResourceAssemblies) { filesToKeep.Add(Path.Combine(packageDir, path)); } } } foreach (var target in root.MainProjectLockFile.Targets.Where(projectTarget => string.IsNullOrEmpty(projectTarget.RuntimeIdentifier) && !root.PublishedLockFile.Targets.Any(publishTarget => projectTarget.TargetFramework == publishTarget.TargetFramework))) { foreach (var library in target.Libraries) { var packageDir = resolver.GetInstallPath(library.Name, library.Version); if (Directory.Exists(packageDir)) { foreach (var path in library.RuntimeAssemblies) { filesToRemove.Add(Path.Combine(packageDir, path)); } foreach (var path in library.CompileTimeAssemblies) { filesToRemove.Add(Path.Combine(packageDir, path)); } foreach (var path in library.NativeLibraries) { filesToRemove.Add(Path.Combine(packageDir, path)); } foreach (var path in library.ResourceAssemblies) { filesToRemove.Add(Path.Combine(packageDir, path)); } } } } foreach (var file in filesToRemove.Except(filesToKeep)) { File.Delete(file); } if (Directory.Exists(root.TargetPackagesPath)) { root.Operations.DeleteEmptyFolders(root.TargetPackagesPath); } return; }
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); }); }
private void EmitNupkg(PackRoot root) { root.Reports.Quiet.WriteLine(" Packing nupkg from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); Runtime.Project project; if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project)) { throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name); } var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); var targetNupkg = resolver.GetPackageFileName(project.Name, project.Version); TargetPath = resolver.GetInstallPath(project.Name, project.Version); root.Reports.Quiet.WriteLine(" Source {0}", _libraryDescription.Path.Bold()); root.Reports.Quiet.WriteLine(" Target {0}", TargetPath); if (Directory.Exists(TargetPath)) { if (root.Overwrite) { root.Operations.Delete(TargetPath); } else { root.Reports.Quiet.WriteLine(" {0} already exists.", TargetPath); return; } } // Generate nupkg from this project dependency var buildOptions = new BuildOptions(); buildOptions.ProjectDir = project.ProjectDirectory; buildOptions.OutputDir = Path.Combine(project.ProjectDirectory, "bin"); buildOptions.Configurations.Add(root.Configuration); buildOptions.Reports = root.Reports; var buildManager = new BuildManager(root.HostServices, buildOptions); if (!buildManager.Build()) { return; } // Extract the generated nupkg to target path var srcNupkgPath = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg); var targetNupkgPath = resolver.GetPackageFilePath(project.Name, project.Version); var hashFile = resolver.GetHashPath(project.Name, project.Version); using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read)) { using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read)) { root.Operations.ExtractNupkg(archive, TargetPath); } } using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read)) { using (var targetStream = new FileStream(targetNupkgPath, FileMode.Create, FileAccess.Write, FileShare.None)) { sourceStream.CopyTo(targetStream); } sourceStream.Seek(0, SeekOrigin.Begin); var sha512Bytes = SHA512.Create().ComputeHash(sourceStream); File.WriteAllText(hashFile, Convert.ToBase64String(sha512Bytes)); } // Copy content files (e.g. html, js and images) of main project into "root" folder of the exported package var rootFolderPath = Path.Combine(TargetPath, "root"); var rootProjectJson = Path.Combine(rootFolderPath, Runtime.Project.ProjectFileName); CopyProject(root, project, rootFolderPath, includeSource: false); UpdateWebRoot(root, rootFolderPath); UpdateJson(rootProjectJson, jsonObj => { // Update the project entrypoint jsonObj["entryPoint"] = _libraryDescription.Identity.Name; // Set mark this as non loadable jsonObj["loadable"] = false; // Update the dependencies node to reference the main project var deps = new JObject(); jsonObj["dependencies"] = deps; deps[_libraryDescription.Identity.Name] = _libraryDescription.Identity.Version.ToString(); }); _applicationBase = Path.Combine("..", PackRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); }
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); }); }
private void UpdateLockFile(PublishRoot root) { var lockFileFormat = new LockFileFormat(); string lockFilePath; if (root.NoSource) { lockFilePath = Path.Combine(TargetPath, "root", LockFileFormat.LockFileName); } else { lockFilePath = Path.Combine(TargetPath, LockFileFormat.LockFileName); } LockFile lockFile; if (File.Exists(lockFilePath)) { lockFile = lockFileFormat.Read(lockFilePath); } else { lockFile = new LockFile { Islocked = false }; var project = GetCurrentProject(); // Restore dependency groups for future lockfile validation lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, project.Dependencies.Select(x => x.LibraryRange.ToString()))); foreach (var frameworkInfo in project.GetTargetFrameworks()) { lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( frameworkInfo.FrameworkName.ToString(), frameworkInfo.Dependencies.Select(x => x.LibraryRange.ToString()))); } } if (root.NoSource) { // The dependency group shared by all frameworks should only contain the main nupkg (i.e. entrypoint) lockFile.ProjectFileDependencyGroups.RemoveAll(g => string.IsNullOrEmpty(g.FrameworkName)); lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, new[] { _libraryDescription.LibraryRange.ToString() })); } var repository = new PackageRepository(root.TargetPackagesPath); var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); // For dependency projects that were published to nupkgs // Add them to lockfile to ensure the contents of lockfile are still valid using (var sha512 = SHA512.Create()) { foreach (var publishProject in root.Projects.Where(p => p.IsPackage)) { var packageInfo = repository.FindPackagesById(publishProject.Name) .SingleOrDefault(); if (packageInfo == null) { root.Reports.Information.WriteLine("Unable to locate published package {0} in {1}", publishProject.Name.Yellow(), repository.RepositoryRoot); continue; } var package = packageInfo.Package; var nupkgPath = resolver.GetPackageFilePath(package.Id, package.Version); var project = publishProject.GetCurrentProject(); lockFile.Libraries.Add(LockFileUtils.CreateLockFileLibraryForProject( project, package, sha512, project.GetTargetFrameworks().Select(f => f.FrameworkName), resolver)); } } lockFileFormat.Write(lockFilePath, lockFile); }
public void EmitNupkg(PackRoot root) { Console.WriteLine("Packing nupkg from project dependency {0}", _libraryDescription.Identity.Name); Runtime.Project project; if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project)) { throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name); } var resolver = new DefaultPackagePathResolver(root.PackagesPath); var targetNupkg = resolver.GetPackageFileName(project.Name, project.Version); TargetPath = resolver.GetInstallPath(project.Name, project.Version); Console.WriteLine(" Source {0}", project.ProjectDirectory); Console.WriteLine(" Target {0}", TargetPath); if (Directory.Exists(TargetPath)) { if (root.Overwrite) { root.Operations.Delete(TargetPath); } else { Console.WriteLine(" {0} already exists.", TargetPath); return; } } // Generate nupkg from this project dependency var buildOptions = new BuildOptions(); buildOptions.ProjectDir = project.ProjectDirectory; buildOptions.OutputDir = Path.Combine(project.ProjectDirectory, "bin"); buildOptions.Configurations.Add(root.Configuration); var buildManager = new BuildManager(root.HostServices, buildOptions); if (!buildManager.Build()) { return; } // Extract the generated nupkg to target path var srcNupkgPath = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg); var targetNupkgPath = resolver.GetPackageFilePath(project.Name, project.Version); var hashFile = resolver.GetHashPath(project.Name, project.Version); using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read)) { using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read)) { root.Operations.ExtractNupkg(archive, TargetPath); } } using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read)) { using (var targetStream = new FileStream(targetNupkgPath, FileMode.Create, FileAccess.Write, FileShare.None)) { sourceStream.CopyTo(targetStream); } sourceStream.Seek(0, SeekOrigin.Begin); var sha512Bytes = SHA512.Create().ComputeHash(sourceStream); File.WriteAllText(hashFile, Convert.ToBase64String(sha512Bytes)); } }
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); }); }