/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> /// <remarks> /// Override this method to write the report. The <see cref="FilebasedFormatter"/> base /// class will ensure that the file is launched after this method is called, depending on /// the outputElement.launch configuration setting. /// </remarks> protected override void WriteReportCore(BuildCopReport report, LogLevel minimumLogLevel) { string fileName = Configuration.output.fileName; if (string.IsNullOrEmpty(fileName)) { throw new InvalidOperationException("The HTML formatter did not have an output file name specified in its configuration."); } using (MemoryStream memStream = new MemoryStream()) { // Use the XML formatter to create an XML document in memory. XmlFormatter.WriteReport(report, minimumLogLevel, memStream, null); memStream.Flush(); memStream.Position = 0; // Use the XSLT to transform the XML into HTML. XslCompiledTransform transform = new XslCompiledTransform(); string stylesheet = Configuration.output.stylesheet; if (string.IsNullOrEmpty(stylesheet)) { stylesheet = XmlFormatter.DefaultStylesheet; } transform.Load(stylesheet); XmlReader input = XmlReader.Create(memStream); using (FileStream outputStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) { transform.Transform(input, XmlWriter.Create(outputStream)); } } }
public void BuildCopShouldExcludeBuildGroupsFromExplicitConfig() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.enabled = true; buildGroup.name = "TestBuildGroup"; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.excludedFiles = "default"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(MockRule).AssemblyQualifiedName; buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config, new string[] { }); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(0, groupReports.Count); }
public void VerifyMultipleFilesWithGlobalExclude() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildGroup.buildFiles.excludedFiles = "signed"; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.excludedFiles = "default"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(MockRule).AssemblyQualifiedName; buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(1, groupReports.Count); BuildGroupReport groupReport = groupReports[0]; Assert.IsNotNull(groupReport); Assert.AreEqual <string>("TestBuildGroup", groupReport.BuildGroupName); Assert.IsNotNull(groupReport.BuildFileReports); Assert.AreEqual <int>(0, groupReport.BuildFileReports.Count); }
/// <summary> /// Writes the specified BuildCop report as XML to an output stream. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> /// <param name="outputStream">The output stream to which to write the XML.</param> /// <param name="stylesheet">The XSLT stylesheet to apply, an empty string to not use a stylesheet, or <see langword="null"/> to use the default stylesheet.</param> internal static void WriteReport(BuildCopReport report, LogLevel minimumLogLevel, Stream outputStream, string stylesheet) { if (stylesheet == null) { stylesheet = DefaultStylesheet; } using (XmlWriter writer = XmlWriter.Create(outputStream)) { writer.WriteStartDocument(); if (!string.IsNullOrEmpty(stylesheet)) { writer.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"" + stylesheet + "\""); } writer.WriteStartElement("BuildCopReport"); writer.WriteAttributeString("engineVersion", report.EngineVersion); writer.WriteAttributeString("generated", report.GeneratedTime.ToString("r", CultureInfo.InvariantCulture)); writer.WriteAttributeString("minimumLogLevel", minimumLogLevel.ToString()); foreach (BuildGroupReport groupReport in report.BuildGroupReports) { writer.WriteStartElement("BuildGroup"); writer.WriteAttributeString("name", groupReport.BuildGroupName); foreach (BuildFileReport fileReport in groupReport.BuildFileReports) { IList <LogEntry> logEntries = fileReport.FindLogEntries(minimumLogLevel); writer.WriteStartElement("BuildFile"); writer.WriteAttributeString("name", Path.GetFileName(fileReport.FileName)); writer.WriteAttributeString("path", fileReport.FileName); foreach (LogEntry entry in logEntries) { writer.WriteStartElement("Entry"); writer.WriteAttributeString("level", entry.Level.ToString()); writer.WriteAttributeString("rule", entry.Rule); writer.WriteAttributeString("code", entry.Code); writer.WriteStartElement("Message"); writer.WriteString(entry.Message); writer.WriteEndElement(); writer.WriteStartElement("Detail"); writer.WriteString(entry.Detail); writer.WriteEndElement(); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); } }
public void BuildCopShouldExcludeBuildGroupsFromAppConfig() { BuildCopReport report = BuildCopEngine.Execute(new string[] { }); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(0, groupReports.Count); }
public sealed override void WriteReport(BuildCopReport report, LogLevel minimumLogLevel) { WriteReportCore(report, minimumLogLevel); if (Configuration.output.launch) { string fileName = Configuration.output.fileName; Process.Start(fileName); } }
public void BuildCopShouldReportRuleExceptions() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.searchPattern = "DefaultConsoleApplication.csproj"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(ExceptionMockRule).AssemblyQualifiedName; mockRule.RuleChecker = new ExceptionMockRule(mockRule); buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(1, groupReports.Count); BuildGroupReport groupReport = groupReports[0]; Assert.IsNotNull(groupReport); Assert.AreEqual <string>("TestBuildGroup", groupReport.BuildGroupName); Assert.IsNotNull(groupReport.BuildFileReports); Assert.AreEqual <int>(1, groupReport.BuildFileReports.Count); BuildFileReport fileReport = groupReport.BuildFileReports[0]; Assert.IsNotNull(fileReport); Assert.AreEqual <string>(@"BuildFiles\DefaultConsoleApplication.csproj", fileReport.FileName); Assert.IsNotNull(fileReport.LogEntries); Assert.AreEqual <int>(1, fileReport.LogEntries.Count); LogEntry entry = fileReport.LogEntries[0]; Assert.AreEqual <LogLevel>(LogLevel.Exception, entry.Level); Assert.AreEqual <string>("An exception occurred while analysing the build file.", entry.Message); Assert.IsNotNull(entry.Detail); Assert.IsTrue(entry.Detail.Contains("ExceptionMock was configured to throw exceptions.")); }
public void FormattersShouldNotThrowOnFormatting() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.searchPattern = "DefaultConsoleApplication.csproj"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(MockRule).AssemblyQualifiedName; buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); // Execute the known formatters. BaseFormatter formatter; formatter = new ConsoleFormatter(null); formatter.WriteReport(report, LogLevel.Information); formatterElement htmlFileConfiguration = new formatterElement(); htmlFileConfiguration.output.fileName = "TestFormatterOutput.html"; htmlFileConfiguration.output.launch = false; htmlFileConfiguration.output.stylesheet = string.Empty; formatter = new HtmlFormatter(htmlFileConfiguration); formatter.WriteReport(report, LogLevel.Information); formatterElement xmlFileConfiguration = new formatterElement(); xmlFileConfiguration.output.fileName = "TestFormatterOutput.xml"; xmlFileConfiguration.output.launch = false; xmlFileConfiguration.output.stylesheet = string.Empty; formatter = new XmlFormatter(xmlFileConfiguration); formatter.WriteReport(report, LogLevel.Information); formatterElement csvFileConfiguration = new formatterElement(); csvFileConfiguration.output.fileName = "TestFormatterOutput.csv"; csvFileConfiguration.output.launch = false; formatter = new CsvFormatter(csvFileConfiguration); formatter.WriteReport(report, LogLevel.Information); }
public void BuildCopShouldExecuteFormatters() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.searchPattern = "DefaultConsoleApplication.csproj"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(MockRule).AssemblyQualifiedName; mockRule.RuleChecker = new MockRule(mockRule); buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); formatterElement formatter = new formatterElement(); formatter.type = typeof(MockFormatter).AssemblyQualifiedName; formatter.minimumLogLevel = LogLevel.Information; formatter.Formatter = new MockFormatter(formatter); config.formatters.Add(formatter); MockFormatter.LastReport = null; BuildCopEngine.Execute(config); BuildCopReport lastReport = MockFormatter.LastReport; Assert.IsNotNull(lastReport); Assert.AreEqual <string>(typeof(BuildCopEngine).Assembly.GetName().Version.ToString(), lastReport.EngineVersion); Assert.IsTrue(DateTime.Now - lastReport.GeneratedTime < TimeSpan.FromMinutes(1)); IList <BuildGroupReport> groupReports = lastReport.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(1, groupReports.Count); BuildGroupReport groupReport = groupReports[0]; Assert.IsNotNull(groupReport); Assert.AreEqual <string>("TestBuildGroup", groupReport.BuildGroupName); Assert.IsNotNull(groupReport.BuildFileReports); Assert.AreEqual <int>(1, groupReport.BuildFileReports.Count); CheckMockFileReport(groupReport.BuildFileReports[0], @"BuildFiles\DefaultConsoleApplication.csproj"); }
/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> public override void WriteReport(BuildCopReport report, LogLevel minimumLogLevel) { foreach (BuildGroupReport groupReport in report.BuildGroupReports) { SysConsole.WriteLine("Build Group '{0}' - Verification Report", groupReport.BuildGroupName); SysConsole.WriteLine("Minimum Log Level: " + minimumLogLevel.ToString()); int totalEntries = 0; int totalShownEntries = 0; foreach (BuildFileReport fileReport in groupReport.BuildFileReports) { IList <LogEntry> logEntries = fileReport.FindLogEntries(minimumLogLevel); if (logEntries.Count > 0) { SysConsole.WriteLine(Separator); SysConsole.WriteLine(string.Format(CultureInfo.CurrentCulture, "{0}:", Path.GetFileName(fileReport.FileName))); totalEntries += logEntries.Count; int shownEntries = 0; foreach (LogEntry entry in logEntries) { if ((int)entry.Level >= (int)minimumLogLevel) { totalShownEntries++; shownEntries++; SysConsole.WriteLine(); SysConsole.WriteLine("[#{0}] {1}: {2}", shownEntries, entry.Level.ToString(), entry.Message); if (!string.IsNullOrEmpty(entry.Detail)) { SysConsole.WriteLine("Details: {0}", entry.Detail); } } } SysConsole.WriteLine(); SysConsole.WriteLine(string.Format(CultureInfo.CurrentCulture, "{0} of {1} log entries shown for project file.", shownEntries, fileReport.LogEntries.Count)); } } SysConsole.WriteLine(); SysConsole.WriteLine(Separator); SysConsole.WriteLine(string.Format(CultureInfo.CurrentCulture, "Total: {0} of {1} log entries shown in {2} project file(s).", totalEntries, totalShownEntries, groupReport.BuildFileReports.Count)); SysConsole.WriteLine(Separator); } }
/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> /// <remarks> /// Override this method to write the report. The <see cref="FilebasedFormatter"/> base /// class will ensure that the file is launched after this method is called, depending on /// the outputElement.launch configuration setting. /// </remarks> protected override void WriteReportCore(BuildCopReport report, LogLevel minimumLogLevel) { string fileName = Configuration.output.fileName; if (string.IsNullOrEmpty(fileName)) { throw new InvalidOperationException("The XML formatter did not have an output file name specified in its configuration."); } using (FileStream outputStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) { string stylesheet = Configuration.output.stylesheet; if (string.IsNullOrEmpty(stylesheet)) { // Use the default stylesheet if no stylesheet was provided. stylesheet = DefaultStylesheet; } WriteReport(report, minimumLogLevel, outputStream, stylesheet); } }
public void BuildCopShouldExecuteSharedRules() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.searchPattern = "DefaultConsoleApplication.csproj"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.RuleChecker = new MockRule(mockRule); buildGroup.rules.Add(mockRule); ruleElement sharedMockRule = new ruleElement(); sharedMockRule.name = "Mock"; sharedMockRule.type = typeof(MockRule).AssemblyQualifiedName; sharedMockRule.RuleChecker = new MockRule(sharedMockRule); config.sharedRules.Add(sharedMockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(1, groupReports.Count); BuildGroupReport groupReport = groupReports[0]; Assert.IsNotNull(groupReport); Assert.AreEqual <string>("TestBuildGroup", groupReport.BuildGroupName); Assert.IsNotNull(groupReport.BuildFileReports); Assert.AreEqual <int>(1, groupReport.BuildFileReports.Count); CheckMockFileReport(groupReport.BuildFileReports[0], @"BuildFiles\DefaultConsoleApplication.csproj"); }
public void BuildCopShouldExcludeBuildGroupsWithoutRules() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.excludedFiles = "default"; buildGroup.buildFiles.paths.Add(path); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(0, groupReports.Count); }
/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> /// <remarks> /// Override this method to write the report. The <see cref="FilebasedFormatter"/> base /// class will ensure that the file is launched after this method is called, depending on /// the outputElement.launch configuration setting. /// </remarks> protected override void WriteReportCore(BuildCopReport report, LogLevel minimumLogLevel) { string fileName = Configuration.output.fileName; if (string.IsNullOrEmpty(fileName)) { throw new InvalidOperationException("The CSV formatter did not have an output file name specified in its configuration."); } FileStream outputStream = null; try { outputStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read); using (StreamWriter writer = new StreamWriter(outputStream)) { outputStream = null; CsvWriteLine(writer, "Build Group", "Build File", "Log Level", "Rule", "Code", "Message", "Detail"); foreach (BuildGroupReport groupReport in report.BuildGroupReports) { foreach (BuildFileReport fileReport in groupReport.BuildFileReports) { foreach (LogEntry entry in fileReport.FindLogEntries(minimumLogLevel)) { CsvWriteLine(writer, groupReport.BuildGroupName, fileReport.FileName, entry.Level.ToString(), entry.Rule, entry.Code, entry.Message, entry.Detail); } } } } } finally { if (outputStream != null) { outputStream.Dispose(); } } }
public void BuildCopShouldExcludeRulesOnOutputTypeWithProjectTypeGuids() { BuildCopConfiguration config = new BuildCopConfiguration(); buildGroupElement buildGroup = new buildGroupElement(); buildGroup.name = "TestBuildGroup"; buildGroup.enabled = true; buildFilePathElement path = new buildFilePathElement(); path.rootPath = @"BuildFiles"; path.searchPattern = "SignedConsoleApplication.csproj"; buildGroup.buildFiles.paths.Add(path); ruleElement mockRule = new ruleElement(); mockRule.name = "Mock"; mockRule.type = typeof(MockRule).AssemblyQualifiedName; mockRule.excludedOutputTypes = "Dummy;Web"; buildGroup.rules.Add(mockRule); config.buildGroups.Add(buildGroup); BuildCopReport report = BuildCopEngine.Execute(config); Assert.IsNotNull(report); IList <BuildGroupReport> groupReports = report.BuildGroupReports; Assert.IsNotNull(groupReports); Assert.AreEqual <int>(1, groupReports.Count); BuildGroupReport groupReport = groupReports[0]; Assert.IsNotNull(groupReport); Assert.AreEqual <string>("TestBuildGroup", groupReport.BuildGroupName); Assert.IsNotNull(groupReport.BuildFileReports); Assert.AreEqual <int>(1, groupReport.BuildFileReports.Count); Assert.AreEqual <int>(0, groupReport.BuildFileReports[0].LogEntries.Count); }
public void ExecuteShouldTakeAppConfig() { BuildCopReport report = BuildCopEngine.Execute(); }
public override void WriteReport(BuildCopReport report, LogLevel minimumLogLevel) { }
/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> /// <remarks> /// Override this method to write the report. The <see cref="FilebasedFormatter"/> base /// class will ensure that the file is launched after this method is called, depending on /// the outputElement.launch configuration setting. /// </remarks> protected abstract void WriteReportCore(BuildCopReport report, LogLevel minimumLogLevel);
/// <summary> /// Writes the specified BuildCop report. /// </summary> /// <param name="report">The report to write.</param> /// <param name="minimumLogLevel">The minimum log level to write.</param> public abstract void WriteReport(BuildCopReport report, LogLevel minimumLogLevel);
/// <summary> /// Starts analysis using the specified configuration. /// </summary> /// <param name="configuration">The BuildCop configuration to use.</param> /// <param name="buildGroups">The build groups to verify.</param> /// <returns>The report containing the outcome of a verification for a list of build groups.</returns> public static BuildCopReport Execute(BuildCopConfiguration configuration, IList <string> buildGroups) { IList <BuildGroupReport> groupReports = new List <BuildGroupReport>(); IDictionary <string, string> outputTypeMappings = GetOutputTypeMappings(configuration); foreach (buildGroupElement buildGroup in configuration.buildGroups) { bool shouldVerifyBuildGroup = buildGroup.enabled; if (buildGroup.rules.Count == 0) { shouldVerifyBuildGroup = false; } else if (buildGroups != null && !buildGroups.Contains(buildGroup.name)) { shouldVerifyBuildGroup = false; } if (shouldVerifyBuildGroup) { IList <BuildFileReport> fileReports = new List <BuildFileReport>(); // Determine build files. IList <BuildFile> buildFiles = GetBuildFiles(buildGroup.buildFiles); // Determine rules. IList <ruleElement> rules = new List <ruleElement>(); foreach (ruleElement ruleDefinition in buildGroup.rules) { ////BaseRule rule = CreateRule(ruleDefinition, configuration.sharedRules); rules.Add(ruleDefinition); } // Run rules on all build files. foreach (BuildFile buildFile in buildFiles) { List <LogEntry> allEntries = new List <LogEntry>(); try { buildFile.Parse(); foreach (ruleElement rule in rules) { if (!ShouldExcludeFile(buildFile.FileName, rule.excludedFiles)) { if (!ShouldExcludeOutputType(buildFile.OutputType, buildFile.ProjectTypeGuids, outputTypeMappings, rule.excludedOutputTypes)) { if (string.IsNullOrEmpty(rule.type.Trim())) { // Shared rules entry foreach (var sharedRule in configuration.sharedRules) { if (sharedRule.name == rule.name) { IList <LogEntry> ruleEntries = sharedRule.RuleChecker.Check(buildFile); allEntries.AddRange(ruleEntries); } } } else { IList <LogEntry> ruleEntries = rule.RuleChecker.Check(buildFile); allEntries.AddRange(ruleEntries); } } } } } catch (Exception exc) { LogEntry entry = CreateExceptionLogEntry(exc); allEntries.Add(entry); } BuildFileReport fileReport = new BuildFileReport(buildFile.FileName, allEntries); fileReports.Add(fileReport); } groupReports.Add(new BuildGroupReport(buildGroup.name, fileReports)); } } BuildCopReport report = new BuildCopReport(groupReports); // Write reports to formatters. foreach (formatterElement formatterDefinition in configuration.formatters) { formatterDefinition.Formatter.WriteReport(report, formatterDefinition.minimumLogLevel); } return(report); }