Cmdlets/src/XpandPwsh.Cmdlets/InvokeParallel/Check-ReferenceConflict.cs
using System;
using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; using System.Reactive.Linq; using System.Reactive.Threading.Tasks; using System.Reflection; using System.Threading.Tasks; using XpandPwsh.CmdLets; namespace XpandPwsh.Cmdlets.InvokeParallel{ [Cmdlet(VerbsCommon.Get, "ReferenceConflict")] [CmdletBinding] public class GetReferenceConflict : PSCmdlet{ [Parameter] public string Path{ get; set; } protected override void ProcessRecord(){ base.ProcessRecord(); if (Path == null) Path = Environment.CurrentDirectory; var multipleVersions = GetReferencedAssembliesWithMultipleVersions(Path).ToArray(); // var maxNameLength = multipleVersions.SelectMany(t => t).Max(t => t.assembly.Name.Length); foreach (var x1 in multipleVersions.Select(tuples => new { tuples.Key,Conflicts = tuples.Select(tuple => new{Assembly = tuple.assembly, Reference = tuple.referenceASsembly}) })) WriteObject(x1); // return; // foreach (var group in multipleVersions) // { // WriteObject($"Possible conflicts for {group.Key}:" ); // foreach (var reference in group) // { // WriteObject($" {reference.assembly.Name.PadRight(maxNameLength)} references {reference.referenceASsembly.FullName}"); // } // } } public static IEnumerable<IGrouping<string, (AssemblyName assembly, AssemblyName referenceASsembly)>> GetReferencedAssembliesWithMultipleVersions(string path){ var assemblies = GetAllAssemblies(path); var references = GetReferencesFromAllAssemblies(assemblies); return references .GroupBy(r => r.referenceASsembly.Name) .Where(r => r.Select(t => t.referenceASsembly.FullName).Distinct().Count() > 1); } private static IEnumerable<(AssemblyName assembly, AssemblyName referenceASsembly)> GetReferencesFromAllAssemblies(IEnumerable<Assembly> assemblies){ return assemblies.SelectMany(GetReferencedAssemblies); } private static IEnumerable<(AssemblyName assembly, AssemblyName referenceASsembly)> GetReferencedAssemblies(Assembly asm){ return asm.GetReferencedAssemblies().Select(refAsm => (asm.GetName(), refAsm)); } private static IEnumerable<Assembly> GetAllAssemblies(string path){ return GetFileNames(path, "*.dll", "*.exe") .Select(TryLoadAssembly) .Where(asm => asm != null); } private static IEnumerable<string> GetFileNames(string path, params string[] extensions){ return extensions.SelectMany(ext => Directory.GetFiles(path, ext, SearchOption.AllDirectories)); } private static Assembly TryLoadAssembly(string filename){ try{ return Assembly.LoadFile(filename); } catch (BadImageFormatException){ return null; } } // public static void Main(string[] args){ // foreach (var path in GetPathsFromArgs(args)){ // var references = AssemblyReference.GetReferencedAssembliesWithMultipleVersions(path); // OutputConflicts(Console.Out, references); // } // } // private static List<string> GetPathsFromArgs(string[] args){ // var paths = new List<string>(); // // foreach (var arg in args) // if (arg.StartsWith("-")){ // if (arg.StartsWith("--")){ // // Long option. // } // } // else if (arg.StartsWith("/")){ // // Windows option. // } // else{ // paths.Add(arg); // } // // if (paths.Count == 0) paths.Add(Directory.GetCurrentDirectory()); // // return paths; // } } } |