I have a bunch of small C# projects which use a couple of NuGet packages. I'd like to be able to update version of a given package automatically. More then that: I'd like to be warned if a project uses different version from the others.
How do I enforce same version dependency across multiple C# projects?
Click on “Manage NuGet Packages for Solution…” to open a slightly extended dialog to manage your NuGet packages: Browse, Installed and Updates work like the menus in the “default” NuGet packages dialog but contain all projects of this solution. The big addition is the Consolidate tab.
If you have more than one project in VS and your Pack file is dependant on another project then both need to be packed. Pack the dependency first, then pack your project. When adding the package using NuGet Package manager make sure your source is not nuget.org but instead your testing folder.
As I haven't found another way to enforce this, I've written a unit test which will fail if different package versions are being found in any packages.config in any subfolder. As this might be useful for others, you'll find the code below. You'll have to adapt the resolution of the root folder done in GetBackendDirectoryPath().
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Xml; using NUnit.Framework; namespace Base.Test.Unit { [TestFixture] public class NugetTest { private const string PACKAGES_CONFIG_FILE_NAME = "packages.config"; private const string BACKEND_DIRECTORY_NAME = "DeviceCloud/"; private const string PACKAGES_NODE_NAME = "packages"; private const string PACKAGE_ID_ATTRIBUTE_NAME = "id"; private const string PACKAGE_VERSION_ATTRIBUTE_NAME = "version"; /// <summary> /// Tests that all referenced nuget packages have the same version by doing: /// - Get all packages.config files contained in the backend /// - Retrieve the id and version of all packages /// - Fail this test if any referenced package has referenced to more than one version accross projects /// - Output a message mentioning the different versions for each package /// </summary> [Test] public void EnforceCoherentReferences() { // Act IDictionary<string, ICollection<PackageVersionItem>> packageVersionsById = new Dictionary<string, ICollection<PackageVersionItem>>(); foreach (string packagesConfigFilePath in GetAllPackagesConfigFilePaths()) { var doc = new XmlDocument(); doc.Load(packagesConfigFilePath); XmlNode packagesNode = doc.SelectSingleNode(PACKAGES_NODE_NAME); if (packagesNode != null && packagesNode.HasChildNodes) { foreach (var packageNode in packagesNode.ChildNodes.Cast<XmlNode>()) { if (packageNode.Attributes == null) { continue; } string packageId = packageNode.Attributes[PACKAGE_ID_ATTRIBUTE_NAME].Value; string packageVersion = packageNode.Attributes[PACKAGE_VERSION_ATTRIBUTE_NAME].Value; if (!packageVersionsById.TryGetValue(packageId, out ICollection<PackageVersionItem> packageVersions)) { packageVersions = new List<PackageVersionItem>(); packageVersionsById.Add(packageId, packageVersions); } //if (!packageVersions.Contains(packageVersion)) if(!packageVersions.Any(o=>o.Version.Equals(packageVersion))) { packageVersions.Add(new PackageVersionItem() { SourceFile = packagesConfigFilePath, Version = packageVersion }); } if (packageVersions.Count > 1) { //breakpoint to examine package source } } } } List<KeyValuePair<string, ICollection<PackageVersionItem>>> packagesWithIncoherentVersions = packageVersionsById.Where(kv => kv.Value.Count > 1).ToList(); // Assert string errorMessage = string.Empty; if (packagesWithIncoherentVersions.Any()) { errorMessage = $"Some referenced packages have incoherent versions. Please fix them by adapting the nuget reference:{Environment.NewLine}"; foreach (var packagesWithIncoherentVersion in packagesWithIncoherentVersions) { string packageName = packagesWithIncoherentVersion.Key; string packageVersions = string.Join("\n ", packagesWithIncoherentVersion.Value); errorMessage += $"{packageName}:\n {packageVersions}\n\n"; } } Assert.IsTrue(packagesWithIncoherentVersions.Count == 0,errorMessage); //Assert.IsEmpty(packagesWithIncoherentVersions, errorMessage); } private static IEnumerable<string> GetAllPackagesConfigFilePaths() { return Directory.GetFiles(GetBackendDirectoryPath(), PACKAGES_CONFIG_FILE_NAME, SearchOption.AllDirectories) .Where(o=>!o.Contains(".nuget")); } private static string GetBackendDirectoryPath() { string codeBase = Assembly.GetExecutingAssembly().CodeBase; var uri = new UriBuilder(codeBase); string path = Uri.UnescapeDataString(uri.Path); return Path.GetDirectoryName(path.Substring(0, path.IndexOf(BACKEND_DIRECTORY_NAME, StringComparison.Ordinal) + BACKEND_DIRECTORY_NAME.Length)); } } public class PackageVersionItem { public string SourceFile { get; set; } public string Version { get; set; } public override string ToString() { return $"{Version} in {SourceFile}"; } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With