Skip to content

Commit

Permalink
PT-4042: Add MatchVersions target (#25)
Browse files Browse the repository at this point in the history
* feat: Add MatchVersions target

* refactor: Decrease complexity
  • Loading branch information
ksavosteev authored Sep 30, 2021
1 parent 2bdd682 commit 349bbcf
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
146 changes: 146 additions & 0 deletions PlatformTools/Build.MatchVerisons.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Nuke.Common;
using Nuke.Common.ProjectModel;
using Nuke.Common.Utilities;
using PlatformTools;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Modularity;

namespace VirtoCommerce.Build
{
internal partial class Build
{
private Regex _moduleNameRegEx = new Regex(@"(VirtoCommerce.+)Module", RegexOptions.Compiled);

public Target MatchVersions => _ => _
.Executes(() =>
{
var allPackages = new List<PackageItem>();
var allProjects = Solution.GetProjects("*");

foreach (var project in allProjects)
{
var packagesInfo = GetProjectPackages(project);
allPackages.AddRange(packagesInfo);
}

var errors = new List<string>();

var platformErrors = ValdatePlatformVersion(allPackages);
errors.AddRange(platformErrors);

var dependencyVerionErrors = ValidateModuleDependenciesVersions(allPackages);
errors.AddRange(dependencyVerionErrors);

var missedDependenciesErrors = ValidateForMissedDependencies(allPackages);
errors.AddRange(missedDependenciesErrors);

if (errors.Any())
{
ControlFlow.Fail(errors.Join(Environment.NewLine));
}
});

/// <summary>
/// Get list of VirtoCommerce packages (platform and module)
/// </summary>
private IEnumerable<PackageItem> GetProjectPackages(Project project)
{
var msBuildProject = project.GetMSBuildProject();

// find all VirtoCommerce references
return msBuildProject.Items
.Where(x => x.ItemType == "PackageReference"
&& (x.EvaluatedInclude.StartsWith("VirtoCommerce.Platform.") || _moduleNameRegEx.IsMatch(x.EvaluatedInclude)))
.Select(x =>
{
var versionMetadata = x.Metadata.FirstOrDefault(x => x.Name == "Version");
if (versionMetadata == null)
{
return null;
}

var name = x.EvaluatedInclude;

return new PackageItem
{
Name = name,
Version = versionMetadata.EvaluatedValue,
ProjectName = project.Name,
IsPlatformPackage = name.StartsWith("VirtoCommerce.Platform.")
};
})
.Where(x => x != null);
}

/// <summary>
/// Check match between manifest platform version and platform packages
/// </summary>
private IEnumerable<string> ValdatePlatformVersion(IEnumerable<PackageItem> packages)
{
return packages
.Where(package => package.IsPlatformPackage && SemanticVersion.Parse(package.Version) != SemanticVersion.Parse(ModuleManifest.PlatformVersion))
.Select(x =>
$"Mismatched platform dependency version found. Platform version: {ModuleManifest.PlatformVersion}, Platform package name: {x.Name}, platform package version: {x.Version}, project name: {x.ProjectName}");
}

/// <summary>
/// Check dependencies for module packages versions mismatch
/// </summary>
private IEnumerable<string> ValidateModuleDependenciesVersions(IEnumerable<PackageItem> packages)
{
var result = new List<string>();

if (ModuleManifest.Dependencies.IsNullOrEmpty())
{
return result;
}

foreach (var dependency in ModuleManifest.Dependencies)
{
var errors = packages
.Where(package => !package.IsPlatformPackage
&& HasNameMatch(package.Name, dependency.Id)
&& SemanticVersion.Parse(package.Version) != SemanticVersion.Parse(dependency.Version))
.Select(package =>
$"Mismatched dependency version found. Dependency: {dependency.Id}, version: {dependency.Version}, Project package version: {package.Version}, project name: {package.ProjectName}");

result.AddRange(errors);
}

return result;
}

/// <summary>
/// Check project packages for missed dependency in manifest
/// </summary>
private IEnumerable<string> ValidateForMissedDependencies(IEnumerable<PackageItem> packages)
{
var result = new List<string>();

if (ModuleManifest.Dependencies.IsNullOrEmpty())
{
return result;
}

foreach (var packageGroup in packages.Where(x => !x.IsPlatformPackage).GroupBy(x => x.Name))
{
if (!ModuleManifest.Dependencies.Any(dependency => HasNameMatch(packageGroup.Key, dependency.Id)))
{
result.Add($"Dependency in module.manifest is missing. Package name: {packageGroup.Key}");
}
}

return result;
}

private bool HasNameMatch(string packageName, string dependencyName)
{
var match = _moduleNameRegEx.Match(packageName);
return match.Groups.Values.Any(x => x.Value == dependencyName);
}
}
}
16 changes: 16 additions & 0 deletions PlatformTools/PackageItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace PlatformTools
{
internal class PackageItem
{
public string Name { get; set; }

public string ProjectName { get; set; }

public string Version { get; set; }

/// <summary>
/// Whether or not the package is a module package or a platfrom package
/// </summary>
public bool IsPlatformPackage { get; set; }
}
}

0 comments on commit 349bbcf

Please sign in to comment.