public override Stream CreateFile(string fullPath, INuGetProjectContext nuGetProjectContext) { PendAddedFiles.Add(fullPath); return(FileSystemUtility.CreateFile(fullPath)); }
/// <summary> /// Asynchronously deletes a package. /// </summary> /// <param name="packageIdentity">A package identity.</param> /// <param name="nuGetProjectContext">A NuGet project context.</param> /// <param name="token">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation. /// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="bool" /> /// indication successfulness of the operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="nuGetProjectContext" /> /// is <c>null</c>.</exception> public async Task <bool> DeletePackage(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } var packageFilePath = GetInstalledPackageFilePath(packageIdentity); if (File.Exists(packageFilePath)) { var packageDirectoryPath = Path.GetDirectoryName(packageFilePath); using (var packageReader = new PackageArchiveReader(packageFilePath)) { var installedSatelliteFilesPair = await PackageHelper.GetInstalledSatelliteFilesAsync( packageReader, PackagePathResolver, GetPackageSaveMode(nuGetProjectContext), token); var runtimePackageDirectory = installedSatelliteFilesPair.Item1; var installedSatelliteFiles = installedSatelliteFilesPair.Item2; if (!string.IsNullOrEmpty(runtimePackageDirectory)) { try { // Delete all the package files now FileSystemUtility.DeleteFiles(installedSatelliteFiles, runtimePackageDirectory, nuGetProjectContext); } catch (Exception ex) { nuGetProjectContext.Log(MessageLevel.Warning, ex.Message); // Catch all exception with delete so that the package file is always deleted } } // Get all the package files before deleting the package file var installedPackageFiles = await PackageHelper.GetInstalledPackageFilesAsync( packageReader, packageIdentity, PackagePathResolver, GetPackageSaveMode(nuGetProjectContext), token); try { // Delete all the package files now FileSystemUtility.DeleteFiles(installedPackageFiles, packageDirectoryPath, nuGetProjectContext); } catch (Exception ex) { nuGetProjectContext.Log(MessageLevel.Warning, ex.Message); // Catch all exception with delete so that the package file is always deleted } } // Delete the package file FileSystemUtility.DeleteFile(packageFilePath, nuGetProjectContext); // Delete the package directory if any FileSystemUtility.DeleteDirectorySafe(packageDirectoryPath, recursive: true, nuGetProjectContext: nuGetProjectContext); // If this is the last package delete the package directory // If this is the last package delete the package directory if (!FileSystemUtility.GetFiles(Root, string.Empty, "*.*").Any() && !FileSystemUtility.GetDirectories(Root, string.Empty).Any()) { FileSystemUtility.DeleteDirectorySafe(Root, recursive: false, nuGetProjectContext: nuGetProjectContext); } } return(true); }
internal static void DeleteFiles(IMSBuildNuGetProjectSystem projectSystem, ZipArchive zipArchive, IEnumerable <string> otherPackagesPath, FrameworkSpecificGroup frameworkSpecificGroup, IDictionary <FileTransformExtensions, IPackageFileTransformer> fileTransformers) { var packageTargetFramework = frameworkSpecificGroup.TargetFramework; IPackageFileTransformer transformer; var directoryLookup = frameworkSpecificGroup.Items.ToLookup( p => Path.GetDirectoryName(ResolveTargetPath(projectSystem, fileTransformers, fte => fte.UninstallExtension, GetEffectivePathForContentFile(packageTargetFramework, p), out transformer))); // Get all directories that this package may have added var directories = from grouping in directoryLookup from directory in FileSystemUtility.GetDirectories(grouping.Key, altDirectorySeparator: false) orderby directory.Length descending select directory; string projectFullPath = projectSystem.ProjectFullPath; // Remove files from every directory foreach (var directory in directories) { var directoryFiles = directoryLookup.Contains(directory) ? directoryLookup[directory] : Enumerable.Empty <string>(); if (!Directory.Exists(Path.Combine(projectFullPath, directory))) { continue; } foreach (var file in directoryFiles) { if (IsEmptyFolder(file)) { continue; } // Resolve the path var path = ResolveTargetPath(projectSystem, fileTransformers, fte => fte.UninstallExtension, GetEffectivePathForContentFile(packageTargetFramework, file), out transformer); if (projectSystem.IsSupportedFile(path)) { // Register the file being uninstalled (used by web site project system). projectSystem.RegisterProcessedFiles(new[] { path }); if (transformer != null) { // TODO: use the framework from packages.config instead of the current framework // which may have changed during re-targeting var projectFramework = projectSystem.TargetFramework; var matchingFiles = new List <InternalZipFileInfo>(); foreach (var otherPackagePath in otherPackagesPath) { using (var otherPackageZipReader = new PackageArchiveReader(otherPackagePath)) { // use the project framework to find the group that would have been installed var mostCompatibleContentFilesGroup = GetMostCompatibleGroup( projectFramework, otherPackageZipReader.GetContentItems()); if (IsValid(mostCompatibleContentFilesGroup)) { // Should not normalize content files group. // It should be like a ZipFileEntry with a forward slash. foreach (var otherPackageItem in mostCompatibleContentFilesGroup.Items) { if (GetEffectivePathForContentFile(packageTargetFramework, otherPackageItem) .Equals( GetEffectivePathForContentFile(packageTargetFramework, file), StringComparison.OrdinalIgnoreCase)) { matchingFiles.Add(new InternalZipFileInfo(otherPackagePath, otherPackageItem)); } } } } } try { var zipArchiveFileEntry = PathUtility.GetEntry(zipArchive, file); if (zipArchiveFileEntry != null) { transformer.RevertFile(zipArchiveFileEntry.Open, path, matchingFiles, projectSystem); } } catch (Exception e) { projectSystem.NuGetProjectContext.Log(MessageLevel.Warning, e.Message); } } else { try { var zipArchiveFileEntry = PathUtility.GetEntry(zipArchive, file); if (zipArchiveFileEntry != null) { DeleteFileSafe(path, zipArchiveFileEntry.Open, projectSystem); } } catch (Exception e) { projectSystem.NuGetProjectContext.Log(MessageLevel.Warning, e.Message); } } } } // If the directory is empty then delete it if (!GetFilesSafe(projectSystem, directory).Any() && !GetDirectoriesSafe(projectSystem, directory).Any()) { DeleteDirectorySafe(projectSystem, directory); } } }
/// <summary> /// Asynchronously installs a package. /// </summary> /// <param name="packageIdentity">A package identity.</param> /// <param name="downloadResourceResult">A download resource result.</param> /// <param name="nuGetProjectContext">A NuGet project context.</param> /// <param name="token">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation. /// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="bool" /> /// indication successfulness of the operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="downloadResourceResult" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="nuGetProjectContext" /> /// is <c>null</c>.</exception> /// <exception cref="ArgumentException">Thrown if the package stream for /// <paramref name="downloadResourceResult" /> is not seekable.</exception> public override Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (downloadResourceResult == null) { throw new ArgumentNullException(nameof(downloadResourceResult)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } if (downloadResourceResult.Status == DownloadResourceResultStatus.Available && !downloadResourceResult.PackageStream.CanSeek) { throw new ArgumentException(Strings.PackageStreamShouldBeSeekable, nameof(downloadResourceResult)); } var packageDirectory = PackagePathResolver.GetInstallPath(packageIdentity); return(ConcurrencyUtilities.ExecuteWithFileLockedAsync( packageDirectory, action: async cancellationToken => { // 1. Set a default package extraction context, if necessary. var packageExtractionContext = nuGetProjectContext.PackageExtractionContext; if (packageExtractionContext == null) { packageExtractionContext = new PackageExtractionContext(new LoggerAdapter(nuGetProjectContext)); } // 2. Check if the Package already exists at root, if so, return false if (PackageExists(packageIdentity, packageExtractionContext.PackageSaveMode)) { nuGetProjectContext.Log(MessageLevel.Info, Strings.PackageAlreadyExistsInFolder, packageIdentity, Root); return false; } nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageToFolder, packageIdentity, Path.GetFullPath(Root)); // 3. Call PackageExtractor to extract the package into the root directory of this FileSystemNuGetProject if (downloadResourceResult.Status == DownloadResourceResultStatus.Available) { downloadResourceResult.PackageStream.Seek(0, SeekOrigin.Begin); } var addedPackageFilesList = new List <string>(); if (downloadResourceResult.PackageReader != null) { if (downloadResourceResult.Status == DownloadResourceResultStatus.AvailableWithoutStream) { addedPackageFilesList.AddRange( await PackageExtractor.ExtractPackageAsync( downloadResourceResult.PackageReader, PackagePathResolver, packageExtractionContext, cancellationToken)); } else { addedPackageFilesList.AddRange( await PackageExtractor.ExtractPackageAsync( downloadResourceResult.PackageReader, downloadResourceResult.PackageStream, PackagePathResolver, packageExtractionContext, cancellationToken)); } } else { addedPackageFilesList.AddRange( await PackageExtractor.ExtractPackageAsync( downloadResourceResult.PackageStream, PackagePathResolver, packageExtractionContext, cancellationToken)); } var packageSaveMode = GetPackageSaveMode(nuGetProjectContext); if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg)) { var packageFilePath = GetInstalledPackageFilePath(packageIdentity); if (File.Exists(packageFilePath)) { addedPackageFilesList.Add(packageFilePath); } } // Pend all the package files including the nupkg file FileSystemUtility.PendAddFiles(addedPackageFilesList, Root, nuGetProjectContext); nuGetProjectContext.Log(MessageLevel.Info, Strings.AddedPackageToFolder, packageIdentity, Path.GetFullPath(Root)); // Extra logging with source for verbosity detailed // Used by external tool CoreXT to track package provenance if (!string.IsNullOrEmpty(downloadResourceResult.PackageSource)) { nuGetProjectContext.Log(MessageLevel.Debug, Strings.AddedPackageToFolderFromSource, packageIdentity, Path.GetFullPath(Root), downloadResourceResult.PackageSource); } return true; }, token: token)); }
public override Task <bool> InstallPackageAsync( PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (downloadResourceResult == null) { throw new ArgumentNullException(nameof(downloadResourceResult)); } if (nuGetProjectContext == null) { throw new ArgumentNullException(nameof(nuGetProjectContext)); } if (!downloadResourceResult.PackageStream.CanSeek) { throw new ArgumentException(Strings.PackageStreamShouldBeSeekable); } var packageFile = PackagePathResolver.GetInstallPath(packageIdentity); return(ConcurrencyUtilities.ExecuteWithFileLockedAsync(packageFile, action: cancellationToken => { // 1. Check if the Package already exists at root, if so, return false if (PackageExists(packageIdentity)) { nuGetProjectContext.Log(MessageLevel.Info, Strings.PackageAlreadyExistsInFolder, packageIdentity, Root); return Task.FromResult(false); } nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageToFolder, packageIdentity, Path.GetFullPath(Root)); // 2. Call PackageExtractor to extract the package into the root directory of this FileSystemNuGetProject downloadResourceResult.PackageStream.Seek(0, SeekOrigin.Begin); var addedPackageFilesList = new List <string>(); PackageExtractionContext packageExtractionContext = nuGetProjectContext.PackageExtractionContext; if (packageExtractionContext == null) { packageExtractionContext = new PackageExtractionContext(new LoggerAdapter(nuGetProjectContext)); } if (downloadResourceResult.PackageReader != null) { addedPackageFilesList.AddRange( PackageExtractor.ExtractPackage( downloadResourceResult.PackageReader, downloadResourceResult.PackageStream, PackagePathResolver, packageExtractionContext, cancellationToken)); } else { addedPackageFilesList.AddRange( PackageExtractor.ExtractPackage( downloadResourceResult.PackageStream, PackagePathResolver, packageExtractionContext, cancellationToken)); } var packageSaveMode = GetPackageSaveMode(nuGetProjectContext); if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg)) { var packageFilePath = GetInstalledPackageFilePath(packageIdentity); if (File.Exists(packageFilePath)) { addedPackageFilesList.Add(packageFilePath); } } // Pend all the package files including the nupkg file FileSystemUtility.PendAddFiles(addedPackageFilesList, Root, nuGetProjectContext); nuGetProjectContext.Log(MessageLevel.Info, Strings.AddedPackageToFolder, packageIdentity, Path.GetFullPath(Root)); return Task.FromResult(true); }, token: token)); }