Пример #1
0
        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");
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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>()
                });
            }
        }
Пример #8
0
        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));
                }
            }
        }
Пример #9
0
        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>()
                });
            }
        }