Exemplo n.º 1
0
        private void WriteLockFile(LockFile previousLockFile,
                                   string projectLockFilePath,
                                   Runtime.Project project,
                                   List <GraphItem> graphItems,
                                   PackageRepository repository,
                                   IProjectResolver projectResolver,
                                   IEnumerable <TargetContext> contexts)
        {
            var resolver = new DefaultPackagePathResolver(repository.RepositoryRoot.Root);
            var previousPackageLibraries = previousLockFile?.PackageLibraries.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()))
            {
                if (item.Match.LibraryType.Equals(Runtime.LibraryTypes.Implicit))
                {
                    continue;
                }

                var library = item.Match.Library;
                if (library.Name == project.Name)
                {
                    continue;
                }

                if (item.Match.LibraryType.Equals(Runtime.LibraryTypes.Project))
                {
                    var projectDependency = projectResolver.FindProject(library.Name);
                    var projectLibrary    = LockFileUtils.CreateLockFileProjectLibrary(project, projectDependency);

                    lockFile.ProjectLibraries.Add(projectLibrary);
                }
                else if (item.Match.LibraryType.Equals(Runtime.LibraryTypes.Package))
                {
                    var packageInfo = repository.FindPackagesById(library.Name)
                                      .FirstOrDefault(p => p.Version == library.Version);

                    if (packageInfo == null)
                    {
                        throw new InvalidOperationException($"Unresolved package: {library.Name}");
                    }

                    LockFilePackageLibrary previousLibrary = null;
                    previousPackageLibraries?.TryGetValue(Tuple.Create(library.Name, library.Version), out previousLibrary);

                    var package = packageInfo.Package;

                    // The previousLibrary can't be a project, otherwise exception has been thrown.
                    lockFile.PackageLibraries.Add(LockFileUtils.CreateLockFilePackageLibrary(
                                                      previousLibrary,
                                                      resolver,
                                                      package,
                                                      correctedPackageName: library.Name));
                }
                else
                {
                    throw new InvalidOperationException($"Unresolved library: {library.Name}");
                }
            }

            var packageLibraries = lockFile.PackageLibraries.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 match in context.Matches.OrderBy(x => x.Library, new LibraryComparer()))
                {
                    if (match.Library.Name == project.Name)
                    {
                        continue;
                    }

                    if (match.LibraryType.Equals(Runtime.LibraryTypes.Project))
                    {
                        var projectDependency    = projectResolver.FindProject(match.Library.Name);
                        var projectTargetLibrary = LockFileUtils.CreateLockFileTargetLibrary(projectDependency, context.RestoreContext);
                        target.Libraries.Add(projectTargetLibrary);
                    }
                    else if (match.LibraryType.Equals(Runtime.LibraryTypes.Package))
                    {
                        var packageInfo = repository.FindPackagesById(match.Library.Name)
                                          .FirstOrDefault(p => p.Version == match.Library.Version);

                        var package = packageInfo.Package;

                        target.Libraries.Add(LockFileUtils.CreateLockFileTargetLibrary(
                                                 packageLibraries[Tuple.Create(match.Library.Name, match.Library.Version)],
                                                 package,
                                                 context.RestoreContext,
                                                 correctedPackageName: match.Library.Name));
                    }
                }

                lockFile.Targets.Add(target);
            }

            var lockFileFormat = new LockFileFormat();

            lockFileFormat.Write(projectLockFilePath, lockFile);
        }
Exemplo n.º 2
0
        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.PackageLibraries)
                {
                    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);
            }
        }