public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (!package.IsSatellitePackage()) { IEnumerable<string> allXmlFiles = from file in package.GetLibFiles() select file.Path into path where path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase) select path; foreach (IPackageFile current in package.GetLibFiles()) { string assemblyPath = current.Path; // TODO: Does this need to check for just managed code? if (assemblyPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { string docFilePath = Path.ChangeExtension(assemblyPath, ".xml"); if (!allXmlFiles.Contains(docFilePath, StringComparer.OrdinalIgnoreCase)) { yield return PackageIssueFactory.AssemblyHasNoDocFile(assemblyPath); } } } } yield break; }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile currentFile in package.GetFiles()) { string extension = Path.GetExtension(currentFile.Path); if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string assemblyPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension); var isManagedCode = false; var isStrongNameSigned = false; int hresult = 0; try { using (Stream packageFileStream = currentFile.GetStream()) { var _assemblyBytes = new byte[packageFileStream.Length]; packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length); using (var fileStream = new FileStream(assemblyPath, FileMode.Create)) { packageFileStream.Seek(0, SeekOrigin.Begin); packageFileStream.CopyTo(fileStream); fileStream.Flush(true); } if (AssemblyHelpers.IsAssemblyManaged(assemblyPath)) { isManagedCode = true; var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")); bool verificationForced; hresult = clrStrongName.StrongNameSignatureVerificationEx(assemblyPath, true, out verificationForced); if (hresult == 0) { isStrongNameSigned = true; } } } } catch (Exception ex) { logger.LogError("Error while verifying strong name signature for {0}: {1}", currentFile.Path, ex.Message); } finally { if (File.Exists(assemblyPath)) { File.Delete(assemblyPath); } } if (isManagedCode && !isStrongNameSigned) { yield return PackageIssueFactory.AssemblyNotStrongNameSigned(currentFile.Path, hresult); } } } yield break; }
public IEnumerable<PackageVerifierIssue> AnalyzePackage(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { IEnumerable<PackageVerifierIssue> packageIssues = new List<PackageVerifierIssue>(); foreach (var rule in Rules) { var issues = rule.Validate(packageRepo, package, logger).ToList(); packageIssues = packageIssues.Concat(issues); } return packageIssues; }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { SemanticVersion semanticVersion; if (SemanticVersion.TryParseStrict(package.Version.ToString(), out semanticVersion)) { yield break; } else { yield return PackageIssueFactory.NotSemanticVersion(package.Version); } }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile currentFile in package.GetFiles()) { string extension = Path.GetExtension(currentFile.Path); if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string assemblyPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension); try { using (Stream packageFileStream = currentFile.GetStream()) { var _assemblyBytes = new byte[packageFileStream.Length]; packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length); using (var fileStream = new FileStream(assemblyPath, FileMode.Create)) { packageFileStream.Seek(0, SeekOrigin.Begin); packageFileStream.CopyTo(fileStream); fileStream.Flush(true); } if (AssemblyHelpers.IsAssemblyManaged(assemblyPath)) { var assemblyDefinition = AssemblyDefinition.ReadAssembly(assemblyPath); var asmAttrs = assemblyDefinition.CustomAttributes; if (!HasAttrWithArg(asmAttrs, typeof(AssemblyFileVersionAttribute).FullName)) { yield return PackageIssueFactory.AssemblyMissingFileVersionAttribute(currentFile.Path); } if (!HasAttrWithArg(asmAttrs, typeof(AssemblyInformationalVersionAttribute).FullName)) { yield return PackageIssueFactory.AssemblyMissingInformationalVersionAttribute(currentFile.Path); } } } } finally { if (File.Exists(assemblyPath)) { File.Delete(assemblyPath); } } } } yield break; }
private void CleanUpFolder(string path, IPackageVerifierLogger logger) { try { if (Directory.Exists(path)) { Directory.Delete(path, recursive: true); } } catch (Exception ex) { logger.LogWarning("Couldn't clean temp unzip folder: " + ex.Message); } }
private static void PrintPackageIssue(IPackageVerifierLogger logger, IssueReport issue) { var issueInfo = issue.PackageIssue.IssueId; if (issue.PackageIssue.Instance != null) { issueInfo += " @ " + issue.PackageIssue.Instance; } logger.Log(issue.IssueLevel, "{0}: {1}", issueInfo, issue.PackageIssue.Issue); if (issue.IgnoreJustification != null) { logger.Log(issue.IssueLevel, "Justification: {0}", issue.IgnoreJustification); } }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile current in package.GetFiles()) { string extension = Path.GetExtension(current.Path); if (PowerShellScriptIsSignedRule.PowerShellExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { if (!VerifySigned(current)) { yield return PackageIssueFactory.PowerShellScriptNotSigned(current.Path); } } } yield break; }
private static void PrintPackageIssue(IPackageVerifierLogger logger, IssueReport issue) { // TODO: Support this: https://confluence.jetbrains.com/display/TCD8/Build+Script+Interaction+with+TeamCity var issueInfo = issue.PackageIssue.IssueId; if (issue.PackageIssue.Instance != null) { issueInfo += " @ " + issue.PackageIssue.Instance; } logger.Log(issue.IssueLevel, "{0}: {1}", issueInfo, issue.PackageIssue.Issue); if (issue.IgnoreJustification != null) { logger.Log(issue.IssueLevel, "Justification: {0}", issue.IgnoreJustification); } }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (package.IsSatellitePackage()) { if (package.Summary.Contains("{")) { yield return PackageIssueFactory.Satellite_PackageSummaryNotLocalized(); } if (package.Title.Contains("{")) { yield return PackageIssueFactory.Satellite_PackageTitleNotLocalized(); } if (package.Description.Contains("{")) { yield return PackageIssueFactory.Satellite_PackageDescriptionNotLocalized(); } } yield break; }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { string packagePath = packageRepo.Source + "\\" + package.Id + "." + package.Version.ToString() + ".nupkg"; string nupkgWithoutExt = Path.Combine(Path.GetDirectoryName(packagePath), Path.GetFileNameWithoutExtension(packagePath)); try { UnzipPackage(nupkgWithoutExt); foreach (IPackageFile current in package.GetFiles()) { //string packagePath = package.FileSystem.Root + "\\" + Id + "." + Version + ".nupkg" string extension = Path.GetExtension(current.Path); // TODO: Need to add more extensions? if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string pathOfFileToScan = Path.Combine(nupkgWithoutExt, current.Path); var realAssemblyPath = pathOfFileToScan; if (!File.Exists(realAssemblyPath)) { realAssemblyPath = pathOfFileToScan.Replace("+", "%2B").Replace("#", "%23"); if (!File.Exists(realAssemblyPath)) { logger.LogError("The assembly '{0}' in this package can't be found (a bug in this tool, most likely).", current.Path); continue; } } bool isAuthenticodeSigned = WinTrust.IsAuthenticodeSigned(realAssemblyPath); if (!isAuthenticodeSigned) { yield return PackageIssueFactory.PEFileNotAuthenticodeSigned(current.Path); } } } } finally { CleanUpFolder(nupkgWithoutExt, logger); } yield break; }
public IEnumerable<PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (string.IsNullOrEmpty(package.Copyright)) { yield return PackageIssueFactory.RequiredCopyright(); } if (package.LicenseUrl == null) { yield return PackageIssueFactory.RequiredLicenseUrl(); } if (package.IconUrl == null) { yield return PackageIssueFactory.RequiredIconUrl(); } if (string.IsNullOrEmpty(package.Tags)) { yield return PackageIssueFactory.RequiredTags(); } if (string.IsNullOrEmpty(package.Title)) { yield return PackageIssueFactory.RequiredTitle(); } if (string.IsNullOrEmpty(package.Summary)) { yield return PackageIssueFactory.RequiredSummary(); } if (package.ProjectUrl == null) { yield return PackageIssueFactory.RequiredProjectUrl(); } if (!package.RequireLicenseAcceptance) { yield return PackageIssueFactory.RequiredRequireLicenseAcceptanceTrue(); } yield break; }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { SemanticVersion semanticVersion; if (SemanticVersion.TryParseStrict(package.Version.ToString(), out semanticVersion)) { yield break; } else { yield return(PackageIssueFactory.NotSemanticVersion(package.Version)); } }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile current in package.GetFiles()) { string extension = Path.GetExtension(current.Path); if (PowerShellScriptIsSignedRule.PowerShellExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { if (!VerifySigned(current)) { yield return(PackageIssueFactory.PowerShellScriptNotSigned(current.Path)); } } } yield break; }
private static int Execute( IDictionary <string, PackageSet> packageSets, IEnumerable <FileInfo> nupkgs, List <string> excludedRuleNames, IPackageVerifierLogger logger, IgnoreAssistanceMode ignoreAssistanceMode) { var allRules = typeof(Program).Assembly.GetTypes() .Where(t => typeof(IPackageVerifierRule).IsAssignableFrom(t) && !t.IsAbstract) .ToDictionary( t => t.Name, t => { var rule = (IPackageVerifierRule)Activator.CreateInstance(t); if (rule is CompositeRule compositeRule) { return(compositeRule.GetRules()); } else { return(new[] { rule }); } }); var packages = nupkgs.ToDictionary(file => { var reader = new PackageArchiveReader(file.FullName); return((IPackageMetadata) new PackageBuilder(reader.GetNuspec(), basePath: null)); }); var processedPackages = new HashSet <IPackageMetadata>(); var totalErrors = 0; var totalWarnings = 0; var ignoreAssistanceData = new Dictionary <string, PackageVerifierOptions>( StringComparer.OrdinalIgnoreCase); PackageSet defaultPackageSet = null; IEnumerable <IPackageVerifierRule> defaultRuleSet = null; IEnumerable <IssueIgnore> defaultIssuesToIgnore = null; foreach (var packageSet in packageSets) { logger.LogInfo( "Processing package set '{0}' with {1} package(s)", packageSet.Key, packageSet.Value.Packages?.Count ?? 0); var packageSetRuleInfo = packageSet.Value.Rules; var packageSetRules = packageSetRuleInfo.SelectMany( ruleId => allRules.SingleOrDefault( rule => string.Equals(rule.Key, ruleId, StringComparison.OrdinalIgnoreCase)).Value) .Where(rule => !excludedRuleNames.Contains(rule.GetType().Name)); if (string.Equals(packageSet.Key, "Default", StringComparison.OrdinalIgnoreCase)) { defaultPackageSet = packageSet.Value; defaultRuleSet = packageSetRules; defaultIssuesToIgnore = GetIgnoresFromFile(packageSet.Value.Packages); continue; } var analyzer = new PackageAnalyzer(); foreach (var ruleInstance in packageSetRules) { analyzer.Rules.Add(ruleInstance); } var issuesToIgnore = GetIgnoresFromFile(packageSet.Value.Packages); var issueProcessor = new IssueProcessor(issuesToIgnore); if (packageSet.Value.Packages != null) { foreach (var packageInfo in packageSet.Value.Packages) { var packageId = packageInfo.Key; var packagesWithId = packages.Where(p => p.Key.Id.Equals(packageId)); if (!packagesWithId.Any()) { logger.LogError("Couldn't find package '{0}' in the repo", packageId); totalErrors++; continue; } foreach (var packagePair in packagesWithId) { var package = packagePair.Key; logger.LogInfo("Analyzing {0} ({1})", package.Id, package.Version); List <PackageVerifierIssue> issues; using (var context = new PackageAnalysisContext { PackageFileInfo = packagePair.Value, Metadata = package, Logger = logger, Options = packageInfo.Value, }) { issues = analyzer.AnalyzePackage(context).ToList(); } var packageErrorsAndWarnings = ProcessPackageIssues( ignoreAssistanceMode, logger, issueProcessor, ignoreAssistanceData, package, issues); totalErrors += packageErrorsAndWarnings.Item1; totalWarnings += packageErrorsAndWarnings.Item2; processedPackages.Add(package); } } } foreach (var issue in issueProcessor.RemainingIssuesToIgnore) { // TODO: Don't show this for rules that we don't run. logger.LogWarning( "Unnecessary exclusion in {0}{3}Issue: {1}{3}Instance: {2}{3}", issue.PackageId, issue.IssueId, issue.Instance, Environment.NewLine); } } var unlistedPackages = packages.Keys.Except(processedPackages); if (unlistedPackages.Any()) { // For unlisted packages we run the rules from 'Default' package set if present // or we run all rules (because we have no idea what exactly to run) var analyzer = new PackageAnalyzer(); var unlistedPackageRules = defaultRuleSet ?? allRules.Values.SelectMany(f => f).Where(r => !excludedRuleNames.Contains(r.GetType().Name)); foreach (var ruleInstance in unlistedPackageRules) { analyzer.Rules.Add(ruleInstance); } var issueProcessor = new IssueProcessor(issuesToIgnore: defaultIssuesToIgnore); foreach (var unlistedPackage in unlistedPackages) { logger.LogInfo("Analyzing {0} ({1})", unlistedPackage.Id, unlistedPackage.Version); List <PackageVerifierIssue> issues; PackageVerifierOptions packageOptions = null; defaultPackageSet?.Packages?.TryGetValue(unlistedPackage.Id, out packageOptions); using (var context = new PackageAnalysisContext { PackageFileInfo = packages[unlistedPackage], Metadata = unlistedPackage, Logger = logger, Options = packageOptions, }) { issues = analyzer.AnalyzePackage(context).ToList(); } var packageErrorsAndWarnings = ProcessPackageIssues( ignoreAssistanceMode, logger, issueProcessor, ignoreAssistanceData, unlistedPackage, issues); totalErrors += packageErrorsAndWarnings.Item1; totalWarnings += packageErrorsAndWarnings.Item2; } foreach (var issue in issueProcessor.RemainingIssuesToIgnore) { // TODO: Don't show this for rules that we don't run. logger.LogWarning( "Unnecessary exclusion in {0}{3}Issue: {1}{3}Instance: {2}{3}", issue.PackageId, issue.IssueId, issue.Instance, Environment.NewLine); } } if (ignoreAssistanceMode != IgnoreAssistanceMode.None && ignoreAssistanceData.Any()) { Console.WriteLine("Showing JSON for ignore content:"); Console.WriteLine(JsonConvert.SerializeObject(ignoreAssistanceData, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })); Console.WriteLine(); } var errorLevel = LogLevel.Normal; if (totalWarnings > 0) { errorLevel = LogLevel.Warning; } if (totalErrors > 0) { errorLevel = LogLevel.Error; } logger.Log( errorLevel, "SUMMARY: {0} error(s) and {1} warning(s) found", totalErrors, totalWarnings); return((totalErrors + totalWarnings > 0) ? ReturnErrorsOrWarnings : ReturnOk); }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile currentFile in package.GetFiles()) { string extension = Path.GetExtension(currentFile.Path); if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string assemblyPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension); var isManagedCode = false; var isStrongNameSigned = false; int hresult = 0; try { using (Stream packageFileStream = currentFile.GetStream()) { var _assemblyBytes = new byte[packageFileStream.Length]; packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length); using (var fileStream = new FileStream(assemblyPath, FileMode.Create)) { packageFileStream.Seek(0, SeekOrigin.Begin); packageFileStream.CopyTo(fileStream); fileStream.Flush(true); } if (AssemblyHelpers.IsAssemblyManaged(assemblyPath)) { isManagedCode = true; var clrStrongName = (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject(new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), new Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")); bool verificationForced; hresult = clrStrongName.StrongNameSignatureVerificationEx(assemblyPath, true, out verificationForced); if (hresult == 0) { isStrongNameSigned = true; } } } } catch (Exception ex) { logger.LogError("Error while verifying strong name signature for {0}: {1}", currentFile.Path, ex.Message); } finally { if (File.Exists(assemblyPath)) { File.Delete(assemblyPath); } } if (isManagedCode && !isStrongNameSigned) { yield return(PackageIssueFactory.AssemblyNotStrongNameSigned(currentFile.Path, hresult)); } } } yield break; }
public static void Log(this IPackageVerifierLogger logger, LogLevel logLevel, string message, params object[] args) { logger.Log(logLevel, string.Format(message, args)); }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { foreach (IPackageFile currentFile in package.GetFiles()) { string extension = Path.GetExtension(currentFile.Path); if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string assemblyPath = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), extension); try { using (Stream packageFileStream = currentFile.GetStream()) { var _assemblyBytes = new byte[packageFileStream.Length]; packageFileStream.Read(_assemblyBytes, 0, _assemblyBytes.Length); using (var fileStream = new FileStream(assemblyPath, FileMode.Create)) { packageFileStream.Seek(0, SeekOrigin.Begin); packageFileStream.CopyTo(fileStream); fileStream.Flush(true); } if (AssemblyHelpers.IsAssemblyManaged(assemblyPath)) { var assemblyDefinition = AssemblyDefinition.ReadAssembly(assemblyPath); var asmAttrs = assemblyDefinition.CustomAttributes; if (!HasServicingAttribute(asmAttrs)) { yield return(PackageIssueFactory.AssemblyMissingServicingAttribute(currentFile.Path)); } } } } finally { if (File.Exists(assemblyPath)) { File.Delete(assemblyPath); } } } } yield break; }
public IEnumerable <PackageVerifierIssue> AnalyzePackage(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { IEnumerable <PackageVerifierIssue> packageIssues = new List <PackageVerifierIssue>(); foreach (var rule in Rules) { var issues = rule.Validate(packageRepo, package, logger).ToList(); packageIssues = packageIssues.Concat(issues); } return(packageIssues); }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { string packagePath = packageRepo.Source + "\\" + package.Id + "." + package.Version.ToString() + ".nupkg"; string nupkgWithoutExt = Path.Combine(Path.GetDirectoryName(packagePath), Path.GetFileNameWithoutExtension(packagePath)); try { UnzipPackage(nupkgWithoutExt); foreach (IPackageFile current in package.GetFiles()) { //string packagePath = package.FileSystem.Root + "\\" + Id + "." + Version + ".nupkg" string extension = Path.GetExtension(current.Path); // TODO: Need to add more extensions? if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase) || extension.Equals(".exe", StringComparison.OrdinalIgnoreCase)) { string pathOfFileToScan = Path.Combine(nupkgWithoutExt, current.Path); var realAssemblyPath = pathOfFileToScan; if (!File.Exists(realAssemblyPath)) { realAssemblyPath = pathOfFileToScan.Replace("+", "%2B").Replace("#", "%23"); if (!File.Exists(realAssemblyPath)) { logger.LogError("The assembly '{0}' in this package can't be found (a bug in this tool, most likely).", current.Path); continue; } } bool isAuthenticodeSigned = WinTrust.IsAuthenticodeSigned(realAssemblyPath); if (!isAuthenticodeSigned) { yield return(PackageIssueFactory.PEFileNotAuthenticodeSigned(current.Path)); } } } } finally { CleanUpFolder(nupkgWithoutExt, logger); } yield break; }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (package.IsSatellitePackage()) { if (package.Summary.Contains("{")) { yield return(PackageIssueFactory.Satellite_PackageSummaryNotLocalized()); } if (package.Title.Contains("{")) { yield return(PackageIssueFactory.Satellite_PackageTitleNotLocalized()); } if (package.Description.Contains("{")) { yield return(PackageIssueFactory.Satellite_PackageDescriptionNotLocalized()); } } yield break; }
public static void LogNormal(this IPackageVerifierLogger logger, string message, params object[] args) { logger.Log(LogLevel.Normal, message, args); }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (!package.IsSatellitePackage()) { IEnumerable <string> allXmlFiles = from file in package.GetLibFiles() select file.Path into path where path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase) select path; foreach (IPackageFile current in package.GetLibFiles()) { string assemblyPath = current.Path; // TODO: Does this need to check for just managed code? if (assemblyPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { string docFilePath = Path.ChangeExtension(assemblyPath, ".xml"); if (!allXmlFiles.Contains(docFilePath, StringComparer.OrdinalIgnoreCase)) { yield return(PackageIssueFactory.AssemblyHasNoDocFile(assemblyPath)); } } } } yield break; }
private static Tuple <int, int> ProcessPackageIssues( IgnoreAssistanceMode ignoreAssistanceMode, IPackageVerifierLogger logger, IssueProcessor issueProcessor, Dictionary <string, PackageVerifierOptions> ignoreAssistanceData, IPackageMetadata package, List <PackageVerifierIssue> issues) { var issuesToReport = issues.Select(issue => issueProcessor.GetIssueReport(issue, package)).ToList(); if (issuesToReport.Count > 0) { var warnings = issuesToReport.Where(issueReport => issueReport.IssueLevel == LogLevel.Warning).ToList(); var errors = issuesToReport.Where(issueReport => issueReport.IssueLevel == LogLevel.Error).ToList(); var errorLevel = LogLevel.Info; if (warnings.Count > 0) { errorLevel = LogLevel.Warning; } if (errors.Count > 0) { errorLevel = LogLevel.Error; } logger.Log( errorLevel, "{0} error(s) and {1} warning(s) found with package {2} ({3})", errors.Count, warnings.Count, package.Id, package.Version); foreach (var issueToReport in issuesToReport) { // If requested, track ignores to assist if (ignoreAssistanceMode == IgnoreAssistanceMode.ShowAll || (ignoreAssistanceMode == IgnoreAssistanceMode.ShowNew && issueToReport.IgnoreJustification == null)) { if (!ignoreAssistanceData.TryGetValue(package.Id, out var options)) { options = new PackageVerifierOptions(); ignoreAssistanceData.Add(package.Id, options); } if (!options.Exclusions.TryGetValue(issueToReport.PackageIssue.IssueId, out var packageRuleInfo)) { packageRuleInfo = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); options.Exclusions.Add(issueToReport.PackageIssue.IssueId, packageRuleInfo); } if (packageRuleInfo.ContainsKey(issueToReport.PackageIssue.Instance ?? "*")) { Console.WriteLine("ALERT!!!!!!!!!!!!! Already added key {0}", issueToReport.PackageIssue.Instance); } else { packageRuleInfo.Add(issueToReport.PackageIssue.Instance ?? "*", issueToReport.IgnoreJustification ?? "Enter justification"); } } PrintPackageIssue(logger, issueToReport); } return(new Tuple <int, int>(errors.Count, warnings.Count)); } logger.LogInfo("No issues found with package {0} ({1})", package.Id, package.Version); return(new Tuple <int, int>(0, 0)); }
public IEnumerable <PackageVerifierIssue> Validate(IPackageRepository packageRepo, IPackage package, IPackageVerifierLogger logger) { if (string.IsNullOrEmpty(package.Copyright)) { yield return(PackageIssueFactory.RequiredCopyright()); } if (package.LicenseUrl == null) { yield return(PackageIssueFactory.RequiredLicenseUrl()); } if (package.IconUrl == null) { yield return(PackageIssueFactory.RequiredIconUrl()); } if (string.IsNullOrEmpty(package.Tags)) { yield return(PackageIssueFactory.RequiredTags()); } if (string.IsNullOrEmpty(package.Title)) { yield return(PackageIssueFactory.RequiredTitle()); } if (string.IsNullOrEmpty(package.Summary)) { yield return(PackageIssueFactory.RequiredSummary()); } if (package.ProjectUrl == null) { yield return(PackageIssueFactory.RequiredProjectUrl()); } if (!package.RequireLicenseAcceptance) { yield return(PackageIssueFactory.RequiredRequireLicenseAcceptanceTrue()); } yield break; }