Last active
January 5, 2016 09:15
-
-
Save PolarbearDK/2c41dc401727de26568f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text.RegularExpressions; | |
using System.Xml.Serialization; | |
using NUnit.Framework; | |
namespace UnitTests | |
{ | |
/// <summary> | |
/// Verify that all projects uses same version of NuGet packages. | |
/// This is done by analyzing packages.config files. | |
/// Projects targeting different Framework Versions are allowed to use different package versions. | |
/// </summary> | |
[TestFixture] | |
public class VerifyNuGetPackagesUnitTest | |
{ | |
[Test] | |
public void VerifyNuGetPackagesTest() | |
{ | |
// Get solution directory three levels up assuming code runs from UnitTests/bin/Debug | |
var directoryName = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Environment.CurrentDirectory))); | |
Assert.That( | |
AnalyzeNuGetPackageFiles(directoryName), | |
"One or more package uses different version or target framework"); | |
} | |
private bool AnalyzeNuGetPackageFiles(string path) | |
{ | |
var list = new List<Package>(); | |
XmlSerializer serializer = new XmlSerializer(typeof(Package[]), new XmlRootAttribute("packages")); | |
var result = true; | |
foreach (var packageFile in | |
Directory | |
.GetFiles(path, "packages.config", SearchOption.AllDirectories) | |
.Where(x => x.IndexOf(@"\obj\", 0, StringComparison.InvariantCultureIgnoreCase) == -1)) | |
{ | |
// Find TargetFrameworkVersion of *.*proj file in same folder as package file. | |
var targetFrameworkVersion = GetTargetFrameworkVersion(packageFile); | |
using (FileStream myFileStream = File.OpenRead(packageFile)) | |
{ | |
var packages = (Package[]) serializer.Deserialize(myFileStream); | |
foreach (var package in packages) | |
{ | |
package.PackageFile = packageFile; | |
package.TargetFrameworkVersion = targetFrameworkVersion; | |
list.Add(package); | |
} | |
} | |
} | |
var grouped = list.GroupBy(x => new { x.Id, x.TargetFrameworkVersion}); | |
foreach (var group in grouped) | |
{ | |
List<string> errors = new List<string>(); | |
if (group.GroupBy(x => x.Version).Count() != 1) | |
{ | |
errors.Add("version"); | |
} | |
if (group.GroupBy(x => x.TargetFramework).Count() != 1) | |
{ | |
errors.Add("target framework"); | |
} | |
if(errors.Count > 0) | |
{ | |
Console.WriteLine($"Package {group.Key.Id} TargetFrameworkVersion {group.Key.TargetFrameworkVersion} has different {string.Join(" and ", errors)}" ); | |
foreach (var package in group) | |
{ | |
Console.WriteLine($" Version={package.Version} TargetFramework={package.TargetFramework} PackageFile={package.PackageFile}"); | |
} | |
result = false; | |
} | |
} | |
return result; | |
} | |
private static readonly Regex VersionRegex = new Regex(@"<TargetFrameworkVersion>(?<version>\S*)</TargetFrameworkVersion>", RegexOptions.Compiled|RegexOptions.Singleline); | |
private string GetTargetFrameworkVersion(string packageFile) | |
{ | |
var files = | |
Directory | |
.GetFiles(Path.GetDirectoryName(packageFile), "*.*proj", SearchOption.TopDirectoryOnly); | |
switch (files.Length) | |
{ | |
case 0: | |
throw new ApplicationException("No project file matched " + packageFile); | |
case 1: | |
var projectFile = files[0]; | |
var match = VersionRegex.Matches(File.ReadAllText(projectFile)); | |
if (match.Count == 1) | |
{ | |
return match[0].Groups["version"].Value; | |
} | |
throw new ApplicationException("Unable to extract TargetFrameworkVersion from " + projectFile); | |
default: | |
throw new ApplicationException("Multiple projects matched " + packageFile); | |
} | |
} | |
} | |
[XmlType("package")] | |
public class Package | |
{ | |
[XmlAttribute("id")] | |
public string Id { get; set; } | |
[XmlAttribute("version")] | |
public string Version { get; set; } | |
[XmlAttribute("targetFramework")] | |
public string TargetFramework { get; set; } | |
/// <summary> | |
/// Source file | |
/// </summary> | |
[XmlIgnore] | |
public string PackageFile { get; set; } | |
/// <summary> | |
/// Related *proj file TargetFrameworkVersion | |
/// </summary> | |
[XmlIgnore] | |
public string TargetFrameworkVersion { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment