public async Task <Dictionary <string, ProjectAnalysisResult> > AnalyzeSolution( string solutionFilename, List <string> projects, string targetFramework = DEFAULT_TARGET) { try { var analyzerResults = await RunCoderlyzerAnalysis(solutionFilename); var analysisActions = AnalyzeActions(projects, targetFramework, analyzerResults, solutionFilename); var solutionAnalysisResult = AnalyzeProjects( solutionFilename, projects, analyzerResults, analysisActions, isIncremental: false, targetFramework); return(solutionAnalysisResult); } catch (OutOfMemoryException e) { _logger.LogError("Analyze solution {0} with error {1}", solutionFilename, e); MemoryUtils.LogMemoryConsumption(_logger); throw e; } finally { CommonUtils.RunGarbageCollection(_logger, "PortingAssistantAnalysisHandler.AnalyzeSolution"); } }
private Dictionary <string, ProjectAnalysisResult> AnalyzeProjects( string solutionFileName, List <string> projects, List <AnalyzerResult> analyzerResult, List <ProjectResult> analysisActions, bool isIncremental = false, string targetFramework = DEFAULT_TARGET) { _logger.LogInformation("Memory Consumption before AnalyzeProjects: "); MemoryUtils.LogMemoryConsumption(_logger); var results = projects .Select((project) => new KeyValuePair <string, ProjectAnalysisResult>( project, AnalyzeProject( project, solutionFileName, analyzerResult, analysisActions, isIncremental, targetFramework))) .Where(p => p.Value != null) .ToDictionary(p => p.Key, p => p.Value); _logger.LogInformation("Memory Consumption after AnalyzeProjects: "); MemoryUtils.LogMemoryConsumption(_logger); return(results); }
public async Task <Dictionary <string, ProjectAnalysisResult> > AnalyzeSolutionIncremental( string solutionFilename, List <string> projects, string targetFramework = DEFAULT_TARGET) { try { var analyzerResults = await RunCoderlyzerAnalysis(solutionFilename); var analysisActions = AnalyzeActions(projects, targetFramework, analyzerResults, solutionFilename); var solutionAnalysisResult = AnalyzeProjects( solutionFilename, projects, analyzerResults, analysisActions, isIncremental: true, targetFramework); var projectActions = projects .Select((project) => new KeyValuePair <string, ProjectActions> (project, analysisActions.FirstOrDefault(p => p.ProjectFile == project)?.ProjectActions ?? new ProjectActions())) .Where(p => p.Value != null) .ToDictionary(p => p.Key, p => p.Value); return(solutionAnalysisResult); } catch (OutOfMemoryException e) { _logger.LogError("Analyze solution {0} with error {1}", solutionFilename, e); MemoryUtils.LogMemoryConsumption(_logger); throw e; } finally { CommonUtils.RunGarbageCollection(_logger, "PortingAssistantAnalysisHandler.AnalyzeSolutionIncremental"); } }
public Dictionary <PackageVersionPair, Task <PackageDetails> > GetNugetPackages(List <PackageVersionPair> packageVersions, string pathToSolution, bool isIncremental = false, bool incrementalRefresh = false) { _logger.LogInformation("Memory usage before GetNugetPackages: "); MemoryUtils.LogMemoryConsumption(_logger); var packageVersionsToQuery = new List <PackageVersionPair>(); var tasks = packageVersions.Select(packageVersion => { var isNewCompatibilityTask = _compatibilityTaskCompletionSources.TryAdd(packageVersion, new TaskCompletionSource <PackageDetails>()); if (isNewCompatibilityTask) { packageVersionsToQuery.Add(packageVersion); } var packageVersionPairResult = _compatibilityTaskCompletionSources[packageVersion]; return(new Tuple <PackageVersionPair, Task <PackageDetails> >(packageVersion, packageVersionPairResult.Task)); }).ToDictionary(t => t.Item1, t => t.Item2); _logger.LogInformation("Checking compatibility for {0} packages", packageVersionsToQuery.Count); Process(packageVersionsToQuery, pathToSolution, isIncremental, incrementalRefresh); _logger.LogInformation("Memory usage after GetNugetPackages: "); MemoryUtils.LogMemoryConsumption(_logger); return(tasks); }
private async Task <List <AnalyzerResult> > RunCoderlyzerAnalysis(string solutionFilename) { MemoryUtils.LogSystemInfo(_logger); MemoryUtils.LogSolutiontSize(_logger, solutionFilename); _logger.LogInformation("Memory usage before RunCoderlyzerAnalysis: "); MemoryUtils.LogMemoryConsumption(_logger); var configuration = GetAnalyzerConfiguration(); var analyzer = CodeAnalyzerFactory.GetAnalyzer(configuration, _logger); var analyzerResults = await analyzer.AnalyzeSolution(solutionFilename); _logger.LogInformation("Memory usage after RunCoderlyzerAnalysis: "); MemoryUtils.LogMemoryConsumption(_logger); return(analyzerResults); }
private List <ProjectResult> AnalyzeActions(List <string> projects, string targetFramework, List <AnalyzerResult> analyzerResults, string pathToSolution) { _logger.LogInformation("Memory Consumption before AnalyzeActions: "); MemoryUtils.LogMemoryConsumption(_logger); List <PortCoreConfiguration> configs = new List <PortCoreConfiguration>(); var anaylyzedProjects = projects.Where(p => { var project = analyzerResults.Find((a) => a.ProjectResult?.ProjectFilePath != null && a.ProjectResult.ProjectFilePath.Equals(p)); return(project != null); }).ToList(); foreach (var proj in anaylyzedProjects) { PortCoreConfiguration projectConfiguration = new PortCoreConfiguration() { ProjectPath = proj, UseDefaultRules = true, TargetVersions = new List <string> { targetFramework }, PortCode = false, PortProject = false }; configs.Add(projectConfiguration); } var solutionPort = new SolutionPort(pathToSolution, analyzerResults, configs, _logger); var projectResults = solutionPort.Run().ProjectResults.ToList(); _logger.LogInformation("Memory Consumption after AnalyzeActions: "); MemoryUtils.LogMemoryConsumption(_logger); return(projectResults); }
public static async Task <CompatibilityResult> IsCompatibleAsync(Task <PackageDetails> packageDetails, PackageVersionPair packageVersionPair, ILogger _logger, string target = "netcoreapp3.1") { if (packageDetails == null || packageVersionPair == null) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } try { await packageDetails; if (!packageDetails.IsCompletedSuccessfully) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } var foundTarget = packageDetails.Result.Targets.GetValueOrDefault(target, null); if (foundTarget == null) { return(new CompatibilityResult { Compatibility = Compatibility.INCOMPATIBLE, CompatibleVersions = new List <string>() }); } if (!NuGetVersion.TryParse(packageVersionPair.Version, out var version)) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } var compatibleVersions = foundTarget.Where(v => { if (!NuGetVersion.TryParse(v, out var semversion)) { return(false); } return(semversion.CompareTo(version) > 0); }).ToList(); var compatibility = foundTarget.Any(v => { if (!NuGetVersion.TryParse(v, out var semversion)) { return(false); } return(version.CompareTo(semversion) == 0); }) ? Compatibility.COMPATIBLE : Compatibility.INCOMPATIBLE; compatibleVersions.Sort((a, b) => NuGetVersion.Parse(a).CompareTo(NuGetVersion.Parse(b))); return(new CompatibilityResult { Compatibility = compatibility, CompatibleVersions = compatibleVersions }); } catch (OutOfMemoryException e) { _logger.LogError("parse package version {0} {1} with error {2}", packageVersionPair.PackageId, packageVersionPair.Version, e); MemoryUtils.LogMemoryConsumption(_logger); return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } catch (Exception e) { _logger.LogError("parse package version {0} {1} with error {2}", packageVersionPair.PackageId, packageVersionPair.Version, e); return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } }
private async void ProcessCompatibility(IEnumerable <PackageVersionPair> packageVersions, Dictionary <PackageVersionPair, TaskCompletionSource <PackageDetails> > compatibilityTaskCompletionSources, string pathToSolution, bool isIncremental, bool incrementalRefresh) { var packageVersionsFound = new HashSet <PackageVersionPair>(); var packageVersionsWithErrors = new HashSet <PackageVersionPair>(); var packageVersionsGroupedByPackageId = packageVersions .GroupBy(pv => pv.PackageId) .ToDictionary(pvGroup => pvGroup.Key, pvGroup => pvGroup.ToList()); foreach (var groupedPackageVersions in packageVersionsGroupedByPackageId) { var packageToDownload = groupedPackageVersions.Key.ToLower(); var fileToDownload = GetDownloadFilePath(CompatibilityCheckerType, packageToDownload); try { string tempDirectoryPath = GetTempDirectory(pathToSolution); PackageDetails packageDetails = null; if (isIncremental) { if (incrementalRefresh || !IsPackageInFile(fileToDownload, tempDirectoryPath)) { _logger.LogInformation("Downloading {0} from {1}", fileToDownload, CompatibilityCheckerType); packageDetails = await GetPackageDetailFromS3(fileToDownload, _httpService); _logger.LogInformation("Caching {0} from {1} to Temp", fileToDownload, CompatibilityCheckerType); CachePackageDetailsToFile(fileToDownload, packageDetails, tempDirectoryPath); } else { _logger.LogInformation("Fetching {0} from {1} from Temp", fileToDownload, CompatibilityCheckerType); packageDetails = GetPackageDetailFromFile(fileToDownload, tempDirectoryPath); } } else { packageDetails = await GetPackageDetailFromS3(fileToDownload, _httpService); } if (packageDetails.Name == null || !string.Equals(packageDetails.Name.Trim().ToLower(), packageToDownload.Trim().ToLower(), StringComparison.OrdinalIgnoreCase)) { throw new PackageDownloadMismatchException( actualPackage: packageDetails.Name, expectedPackage: packageToDownload); } foreach (var packageVersion in groupedPackageVersions.Value) { if (compatibilityTaskCompletionSources.TryGetValue(packageVersion, out var taskCompletionSource)) { taskCompletionSource.SetResult(packageDetails); packageVersionsFound.Add(packageVersion); } } } catch (OutOfMemoryException ex) { _logger.LogError("Failed when downloading and parsing {0} from {1}, {2}", fileToDownload, CompatibilityCheckerType, ex); MemoryUtils.LogSolutiontSize(_logger, pathToSolution); MemoryUtils.LogMemoryConsumption(_logger); } catch (Exception ex) { if (ex.Message.Contains("404")) { _logger.LogInformation($"Encountered {ex.GetType()} while downloading and parsing {fileToDownload} " + $"from {CompatibilityCheckerType}, but it was ignored. " + $"ErrorMessage: {ex.Message}."); // filter all 404 errors ex = null; } else { _logger.LogError("Failed when downloading and parsing {0} from {1}, {2}", fileToDownload, CompatibilityCheckerType, ex); } foreach (var packageVersion in groupedPackageVersions.Value) { if (compatibilityTaskCompletionSources.TryGetValue(packageVersion, out var taskCompletionSource)) { taskCompletionSource.SetException(new PortingAssistantClientException(ExceptionMessage.PackageNotFound(packageVersion), ex)); packageVersionsWithErrors.Add(packageVersion); } } } } foreach (var packageVersion in packageVersions) { if (packageVersionsFound.Contains(packageVersion) || packageVersionsWithErrors.Contains(packageVersion)) { continue; } if (compatibilityTaskCompletionSources.TryGetValue(packageVersion, out var taskCompletionSource)) { var errorMessage = $"Could not find package {packageVersion} in external source; try checking an internal source."; _logger.LogInformation(errorMessage); var innerException = new PackageNotFoundException(errorMessage); taskCompletionSource.TrySetException(new PortingAssistantClientException(ExceptionMessage.PackageNotFound(packageVersion), innerException)); } } }
public static async Task <CompatibilityResult> IsCompatibleAsync(Task <PackageDetails> packageDetails, PackageVersionPair packageVersionPair, ILogger _logger, string target = "net6.0") { if (packageDetails == null || packageVersionPair == null) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } try { await packageDetails; if (!packageDetails.IsCompletedSuccessfully) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } var compatibleVersionsForTargetFramework = packageDetails.Result.Targets.GetValueOrDefault(target, null); if (compatibleVersionsForTargetFramework == null) { return(new CompatibilityResult { Compatibility = Compatibility.INCOMPATIBLE, CompatibleVersions = new List <string>() }); } if (!NuGetVersion.TryParse(packageVersionPair.Version, out var version)) { return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } var compatibleVersionsToRecommend = version.FindGreaterCompatibleVersions(compatibleVersionsForTargetFramework).ToList(); compatibleVersionsToRecommend.Sort((a, b) => NuGetVersion.Parse(a).CompareTo(NuGetVersion.Parse(b))); Compatibility compatibility; var maxCompatibleVersion = NugetVersionHelper.GetMaxVersion(compatibleVersionsForTargetFramework); if (maxCompatibleVersion != null && !maxCompatibleVersion.IsZeroVersion() && version.IsGreaterThan(maxCompatibleVersion)) { compatibility = version.HasSameMajorAs(maxCompatibleVersion) ? Compatibility.COMPATIBLE : Compatibility.INCOMPATIBLE; } else { compatibility = version.HasLowerOrEqualCompatibleVersion(compatibleVersionsForTargetFramework) ? Compatibility.COMPATIBLE : Compatibility.INCOMPATIBLE; } return(new CompatibilityResult { Compatibility = compatibility, CompatibleVersions = compatibleVersionsToRecommend }); } catch (OutOfMemoryException e) { _logger.LogError("parse package version {0} {1} with error {2}", packageVersionPair.PackageId, packageVersionPair.Version, e); MemoryUtils.LogMemoryConsumption(_logger); return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } catch (Exception e) { _logger.LogError("parse package version {0} {1} with error {2}", packageVersionPair.PackageId, packageVersionPair.Version, e); return(new CompatibilityResult { Compatibility = Compatibility.UNKNOWN, CompatibleVersions = new List <string>() }); } }