using System; using System.IO; using System.Collections.Generic; using Microsoft.DotNet.ProjectModel; using System.Linq; namespace MultiProjectValidator { public class Program { public static int Main(string[] args) { string rootPath = null; try { rootPath = ParseAndValidateArgs(args); } catch { return 1; } List projects = null; try { projects = ProjectLoader.Load(rootPath); } catch(Exception e) { Console.WriteLine("Failed to load projects from path: " + rootPath); return 1; } var analyzer = ProjectAnalyzer.Create(projects); var analysisResults = analyzer.DoAnalysis(); var failed = analysisResults.Where((a) => !a.Passed).Any(); PrintAnalysisResults(analysisResults); return failed ? 1 : 0; } private static void PrintAnalysisResults(List analysisResults) { Console.WriteLine("Project Validation Results"); var failedCount = analysisResults.Where((a) => !a.Passed).Count(); var passedCount = analysisResults.Where((a) => a.Passed).Count(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{passedCount} Successful Analysis Rules"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"{failedCount} Failed Analysis Rules"); if (failedCount != 0) { Console.WriteLine("Failure Messages"); foreach(var result in analysisResults) { if (!result.Passed) { foreach(var message in result.Messages) { Console.WriteLine(message); } } } } Console.ForegroundColor = ConsoleColor.White; } private static bool AnyAnalysisFailed(List analysisResults) { foreach (var result in analysisResults) { if (!result.Passed) { return true; } } return false; } private static string ParseAndValidateArgs(string[] args) { if (args.Length != 1) { PrintHelp(); throw new Exception(); } string rootPath = args[0]; if (!Directory.Exists(rootPath)) { Console.WriteLine("Root Directory does not exist: " + rootPath); throw new Exception(); } return rootPath; } private static void PrintHelp() { var help = @" Multi-Project Validator Description: This tool recursively searches for project.json's from the given root path. It then applies a set of analysis rules, determines whether they pass/fail and then sets exit code to reflect. Note: Ensure all analyzed project.json have been restored prior to running this tool. Usage: pjvalidate [root path of recursive search]"; Console.WriteLine(help); } } }