internal static FrameworkSpecificGroup GetMostCompatibleGroup(NuGetFramework projectTargetFramework, IEnumerable <FrameworkSpecificGroup> itemGroups, bool altDirSeparator = false) { FrameworkReducer reducer = new FrameworkReducer(); NuGetFramework mostCompatibleFramework = reducer.GetNearest(projectTargetFramework, itemGroups.Select(i => i.TargetFramework)); if (mostCompatibleFramework != null) { IEnumerable <FrameworkSpecificGroup> mostCompatibleGroups = itemGroups.Where(i => i.TargetFramework.Equals(mostCompatibleFramework)); var mostCompatibleGroup = mostCompatibleGroups.SingleOrDefault(); if (IsValid(mostCompatibleGroup)) { mostCompatibleGroup = new FrameworkSpecificGroup(mostCompatibleGroup.TargetFramework, GetValidPackageItems(mostCompatibleGroup.Items).Select(item => altDirSeparator ? PathUtility.ReplaceDirSeparatorWithAltDirSeparator(item) : PathUtility.ReplaceAltDirSeparatorWithDirSeparator(item))); } return(mostCompatibleGroup); } return(null); }
internal static void AddFiles(IMSBuildNuGetProjectSystem msBuildNuGetProjectSystem, ZipArchive zipArchive, FrameworkSpecificGroup frameworkSpecificGroup, IDictionary <FileTransformExtensions, IPackageFileTransformer> fileTransformers) { var packageTargetFramework = frameworkSpecificGroup.TargetFramework; // Content files are maintained with AltDirectorySeparatorChar List <string> packageItemListAsArchiveEntryNames = frameworkSpecificGroup.Items.Select(i => PathUtility.ReplaceDirSeparatorWithAltDirSeparator(i)).ToList(); packageItemListAsArchiveEntryNames.Sort(new PackageItemComparer()); try { var zipArchiveEntryList = packageItemListAsArchiveEntryNames.Select(i => zipArchive.GetEntry(i)).Where(i => i != null).ToList(); try { var paths = zipArchiveEntryList.Select(file => ResolvePath(fileTransformers, fte => fte.InstallExtension, GetEffectivePathForContentFile(packageTargetFramework, file.FullName))); paths = paths.Where(p => !String.IsNullOrEmpty(p)); msBuildNuGetProjectSystem.BeginProcessing(paths); } catch (Exception) { // Ignore all exceptions for now } foreach (ZipArchiveEntry zipArchiveEntry in zipArchiveEntryList) { if (zipArchiveEntry == null) { throw new ArgumentNullException("zipArchiveEntry"); } if (IsEmptyFolder(zipArchiveEntry.FullName)) { continue; } var effectivePathForContentFile = GetEffectivePathForContentFile(packageTargetFramework, zipArchiveEntry.FullName); // Resolve the target path IPackageFileTransformer installTransformer; string path = ResolveTargetPath(msBuildNuGetProjectSystem, fileTransformers, fte => fte.InstallExtension, effectivePathForContentFile, out installTransformer); if (msBuildNuGetProjectSystem.IsSupportedFile(path)) { if (installTransformer != null) { installTransformer.TransformFile(zipArchiveEntry, path, msBuildNuGetProjectSystem); } else { // Ignore uninstall transform file during installation string truncatedPath; IPackageFileTransformer uninstallTransformer = FindFileTransformer(fileTransformers, fte => fte.UninstallExtension, effectivePathForContentFile, out truncatedPath); if (uninstallTransformer != null) { continue; } TryAddFile(msBuildNuGetProjectSystem, path, zipArchiveEntry.Open); } } } } finally { msBuildNuGetProjectSystem.EndProcessing(); } }
internal static void DeleteFiles(IMSBuildNuGetProjectSystem msBuildNuGetProjectSystem, 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(msBuildNuGetProjectSystem, 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; // 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(msBuildNuGetProjectSystem.ProjectFullPath, directory))) { continue; } try { foreach (var file in directoryFiles) { if (IsEmptyFolder(file)) { continue; } // Resolve the path string path = ResolveTargetPath(msBuildNuGetProjectSystem, fileTransformers, fte => fte.UninstallExtension, GetEffectivePathForContentFile(packageTargetFramework, file), out transformer); if (msBuildNuGetProjectSystem.IsSupportedFile(path)) { if (transformer != null) { // TODO: use the framework from packages.config instead of the current framework // which may have changed during re-targeting NuGetFramework projectFramework = msBuildNuGetProjectSystem.TargetFramework; List <InternalZipFileInfo> matchingFiles = new List <InternalZipFileInfo>(); foreach (var otherPackagePath in otherPackagesPath) { using (var otherPackageStream = File.OpenRead(otherPackagePath)) { var otherPackageZipArchive = new ZipArchive(otherPackageStream); var otherPackageZipReader = new PackageReader(otherPackageZipArchive); // use the project framework to find the group that would have been installed var mostCompatibleContentFilesGroup = GetMostCompatibleGroup(projectFramework, otherPackageZipReader.GetContentItems(), altDirSeparator: true); if (mostCompatibleContentFilesGroup != null && IsValid(mostCompatibleContentFilesGroup)) { 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 = zipArchive.GetEntry(PathUtility.ReplaceDirSeparatorWithAltDirSeparator(file)); if (zipArchiveFileEntry != null) { transformer.RevertFile(zipArchiveFileEntry, path, matchingFiles, msBuildNuGetProjectSystem); } } catch (Exception e) { msBuildNuGetProjectSystem.NuGetProjectContext.Log(MessageLevel.Warning, e.Message); } } else { var zipArchiveFileEntry = zipArchive.GetEntry(PathUtility.ReplaceDirSeparatorWithAltDirSeparator(file)); if (zipArchiveFileEntry != null) { DeleteFileSafe(path, zipArchiveFileEntry.Open, msBuildNuGetProjectSystem); } } } } // If the directory is empty then delete it if (!GetFilesSafe(msBuildNuGetProjectSystem, directory).Any() && !GetDirectoriesSafe(msBuildNuGetProjectSystem, directory).Any()) { DeleteDirectorySafe(msBuildNuGetProjectSystem, directory, recursive: false); } } finally { } } }