Woody1193
Woody1193

Reputation: 7960

Get all nuget packages in solution

I'm trying to write a unit test to enforce consolidation of Nuget packages (we have a build requirement that all unit tests pass so this would keep PRs that aren't consolidating from passing) and I was attempting to use Nuget.Core to do that. However, I cannot seem to find my way through their libraries and no one has asked this question yet. So, how can I get all the Nuget packages a given solution references programmatically?

Upvotes: 4

Views: 3521

Answers (2)

Woody1193
Woody1193

Reputation: 7960

This is the final solution (along with unit test). The key is to use the Directory library to iterate over all the projects in the solution and then use NuGet.Core to analyze the NuGet packages in each project.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NuGet;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace UnitTests
{
    [TestClass]
    public class NugetConsolidationTest
    {
        private List<string> _ignoredPackages = new List<string>();

        [TestMethod]
        public void AllNugetPackagesAreConsolidated()
        {
            var packageVersionMapping = new Dictionary<string, List<string>>();

            var parentDir = (Directory.GetParent(Directory.GetCurrentDirectory()).Parent).Parent.FullName;
            var files = Directory.GetFiles(parentDir, "packages.config", SearchOption.AllDirectories);
            foreach (var packageFile in files)
            {
                var file = new PackageReferenceFile(packageFile);
                var refs = file.GetPackageReferences(true);
                foreach (var packageRef in refs)
                {
                    if (_ignoredPackages.Contains(packageRef.Id))
                        continue;
                    if (!packageVersionMapping.ContainsKey(packageRef.Id))
                        packageVersionMapping[packageRef.Id] = new List<string>() { packageRef.Version.ToFullString() };
                    else
                    {
                        if (packageVersionMapping[packageRef.Id].All(x => !x.Equals(packageRef.Version.ToFullString(),
                                StringComparison.InvariantCultureIgnoreCase)))
                            packageVersionMapping[packageRef.Id].Add(packageRef.Version.ToFullString());
                    }
                }
            }

            var errors = packageVersionMapping.Where(x => x.Value.Count > 1)?.
                Select(x => $"Package {x.Key} has {x.Value.Count} separate versions installed! Current versions are {string.Join(", ", x.Value)}");
            errors.ShouldBeEmpty();
        }
    }
}

Upvotes: 4

Belgi
Belgi

Reputation: 15052

You can always read the package.config files and parse them.

The one that's inside the solution directory with reference other packages.config file is one for each project contained in the solution.

Upvotes: 1

Related Questions