private void WriteLockFile(LockFile previousLockFile, string projectLockFilePath, Runtime.Project project, List <GraphItem> graphItems, PackageRepository repository, IEnumerable <TargetContext> contexts) { var resolver = new DefaultPackagePathResolver(repository.RepositoryRoot); var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create(l.Name, l.Version)); var lockFile = new LockFile(); lockFile.Islocked = Lock; // Use empty string as the key of dependencies shared by all frameworks 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()))); } // Record all libraries used foreach (var item in graphItems.OrderBy(x => x.Match.Library, new LibraryComparer())) { var library = item.Match.Library; var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var package = packageInfo.Package; LockFileLibrary previousLibrary = null; previousLibraries?.TryGetValue(Tuple.Create(library.Name, library.Version), out previousLibrary); var lockFileLib = LockFileUtils.CreateLockFileLibrary( previousLibrary, resolver, package, correctedPackageName: library.Name); lockFile.Libraries.Add(lockFileLib); } var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version)); // Add the contexts foreach (var context in contexts) { var target = new LockFileTarget(); target.TargetFramework = context.RestoreContext.FrameworkName; target.RuntimeIdentifier = context.RestoreContext.RuntimeName; foreach (var library in context.Libraries.OrderBy(x => x, new LibraryComparer())) { var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var package = packageInfo.Package; var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], package, context.RestoreContext, correctedPackageName: library.Name); target.Libraries.Add(targetLibrary); } lockFile.Targets.Add(target); } var lockFileFormat = new LockFileFormat(); lockFileFormat.Write(projectLockFilePath, lockFile); }
private void PurgeOrphanPackages() { _reports.Verbose.WriteLine("Removing orphaned packages..."); // Find the packages still used by the command scripts var applicationPackagesStillUsed = _commandsRepo.Commands .Select(cmd => _commandsRepo.FindCommandOwner(cmd)) .Distinct(); // Get all the installed packages var packagesRepo = new PackageRepository( _commandsRepo.PackagesRoot, caseSensitivePackagesName: false); // Key = package<id, version>, Value = bool (true if used, false otherwise) var usedPackages = packagesRepo .GetAllPackages() .SelectMany(pack => pack.Value) .ToDictionary( pack => pack, _ => false); var lockFileFormat = new LockFileFormat(); // Mark all the packages still in used by using the dependencies in the lock file foreach (var applicationPackage in applicationPackagesStillUsed) { var appLockFileFullPath = Path.Combine( _commandsRepo.PackagesRoot.Root, _commandsRepo.PathResolver.GetPackageDirectory(applicationPackage.Id, applicationPackage.Version), InstallBuilder.CommandsFolderName, LockFileFormat.LockFileName); if (!File.Exists(appLockFileFullPath)) { _reports.Verbose.WriteLine("Lock file {0} not found. This package will be removed if it is not used by another application", appLockFileFullPath); // The lock file is missing, probably the app is not installed correctly // unless someone else is using it, we'll remove it continue; } var lockFile = lockFileFormat.Read(appLockFileFullPath); foreach (var dependency in lockFile.Libraries) { var dependencyPackage = new NuGet.PackageInfo( _commandsRepo.PackagesRoot, dependency.Name, dependency.Version, null, null); if (usedPackages.ContainsKey(dependencyPackage)) { // Mark the dependency as used usedPackages[dependencyPackage] = true; } } } // Now it's time to remove those unused packages var unusedPackages = usedPackages .Where(pack => !pack.Value) .Select(pack => pack.Key); foreach (var package in unusedPackages) { packagesRepo.RemovePackage(package); _reports.Verbose.WriteLine("Removed orphaned package: {0} {1}", package.Id, package.Version); } }