// TODO: add HasLocalInstalledPackage() ?
        // ReSharper disable once CyclomaticComplexity
        public static IEnumerable <InstalledPackage> GetLocalInstalledPackages(
            string packagesConfigFile = null,
            bool includeDependencies  = false)
        {
            packagesConfigFile = packagesConfigFile ?? GetBuildPackagesConfigFile();
            ControlFlow.Assert(!IncludesDependencies(packagesConfigFile) || includeDependencies,
                               $"!IncludesDependencies({packagesConfigFile}) || includeDependencies");
            var packagesDirectory = GetPackagesDirectory(packagesConfigFile);

            var packageIds = XmlTasks.XmlPeek(
                packagesConfigFile,
                IsLegacyFile(packagesConfigFile)
                    ? ".//package/@id"
                    : ".//*[local-name() = 'PackageReference']/@Include");

            var installedPackages = new HashSet <InstalledPackage>(InstalledPackage.Comparer.Instance);

            foreach (var packageId in packageIds)
            {
                // TODO: use xml namespaces
                // TODO: version as tag
                var version = XmlTasks.XmlPeekSingle(
                    packagesConfigFile,
                    IsLegacyFile(packagesConfigFile)
                            ? $".//package[@id='{packageId}']/@version"
                            : $".//*[local-name() = 'PackageReference'][@Include='{packageId}']/@Version")
                              .NotNull("version != null");

                var packageData = GetGlobalInstalledPackage(packageId, version, packagesDirectory);
                if (packageData == null)
                {
                    continue;
                }

                installedPackages.Add(packageData);
                yield return(packageData);
            }

            if (includeDependencies)
            {
                var packagesToCheck = new Queue <InstalledPackage>(installedPackages);
                while (packagesToCheck.Any())
                {
                    var packageToCheck = packagesToCheck.Dequeue();

                    foreach (var dependentPackage in GetDependentPackages(packageToCheck, packagesDirectory))
                    {
                        if (installedPackages.Contains(dependentPackage))
                        {
                            continue;
                        }

                        installedPackages.Add(dependentPackage);
                        packagesToCheck.Enqueue(dependentPackage);

                        yield return(dependentPackage);
                    }
                }
            }
        }
示例#2
0
        private static string GetPackagesDirectory([CanBeNull] string packagesConfigFile)
        {
            string TryGetFromEnvironmentVariable()
            => EnvironmentInfo.GetVariable <string>("NUGET_PACKAGES");

            string TryGetGlobalDirectoryFromConfig()
            => GetConfigFiles(packagesConfigFile)
            .Select(x => new
            {
                File    = x,
                Setting = XmlTasks.XmlPeekSingle(x, ".//add[@key='globalPackagesFolder']/@value")
            })
            .Where(x => x.Setting != null)
            .Select(x => Path.IsPathRooted(x.Setting)
                        ? x.Setting
                        : Path.Combine(Path.GetDirectoryName(x.File).NotNull(), x.Setting))
            .FirstOrDefault();

            string TryGetDefaultGlobalDirectory()
            => packagesConfigFile == null || !IsLegacyFile(packagesConfigFile)
                    ? Path.Combine(
                EnvironmentInfo.SpecialFolder(SpecialFolders.UserProfile)
                .NotNull("EnvironmentInfo.SpecialFolder(SpecialFolders.UserProfile) != null"),
                ".nuget",
                "packages")
                    : null;

            string TryGetLocalDirectory()
            => packagesConfigFile != null
                    ? new FileInfo(packagesConfigFile).Directory.NotNull()
            .DescendantsAndSelf(x => x.Parent)
            .Where(x => x.GetFiles("*.sln").Any())
            .Select(x => Path.Combine(x.FullName, "packages"))
            .FirstOrDefault(Directory.Exists)
                    : null;

            var packagesDirectory = TryGetFromEnvironmentVariable() ??
                                    TryGetGlobalDirectoryFromConfig() ??
                                    TryGetDefaultGlobalDirectory() ??
                                    TryGetLocalDirectory();

            return(packagesDirectory != null && Directory.Exists(packagesDirectory)
                ? packagesDirectory
                : null);
        }