TeamCity整合Source Monitor報表

Source Monitor是用來分析程式碼度量的工具,先到官網下載

安裝後的預設路徑為C:\Program Files (x86)\SourceMonitor

先淮備一個用來產生報告的設定檔SourceMonitorCommands.xml

<?xml version=”1.0” encoding=”utf-8”?>
<sourcemonitor_commands>
<write_log>true</write_log>
<command>
<project_file>SourceMonitor.smp</project_file>
<checkpoint_name>Baseline</checkpoint_name>
<project_language>C#</project_language>
<!– 要分析專案的相對路徑 –>
<source_directory>..</source_directory>
<source_subdirectory_list>
<exclude_subdirectories>true</exclude_subdirectories>
<source_subtree>bin\</source_subtree>
<source_subdirectory>obj\</source_subdirectory>
</source_subdirectory_list>
<parse_utf8_files>True</parse_utf8_files>
<ignore_headers_footers>True</ignore_headers_footers>
<export>
<!– 最後輸出的檔名 –>
<export_file>SourceMonitorReport.xml</export_file>
<export_type>2</export_type>
</export>
</command>
</sourcemonitor_commands>

因為輸出的是XML格式,所以需要透過XSL轉成HTML格式
先下載轉換的工具msxsl.exe

SourceMonitor.xsl
<?xml version=”1.0” encoding=”utf-8” ?>
<xsl:stylesheet version=”1.0” xmlns:xsl=”http://www.w3.org/1999/XSL/Transform" xmlns=”http://www.w3.org/TR/xhtml1/strict">
<xsl:output method=”html”/>

<xsl:template match=”/“>
<html>
<head>
<style type=”text/css”>
/
Web20 Table Style
written by Netway Media, http://www.netway-media.com
/
table
{
border-collapse: collapse;
border: 1px solid #666666;
font: normal 11px verdana, arial, helvetica, sans-serif;
color: #363636;
background: #f6f6f6;
text-align: left;
}
caption
{
text-align: center;
font: bold 16px arial, helvetica, sans-serif;
background: transparent;
padding: 6px 4px 8px 0px;
color: #CC00FF;
text-transform: uppercase;
}
thead, tfoot
{
background: url(bg1.png) repeat-x;
text-align: left;
height: 30px;
}
thead th, tfoot th
{
padding: 5px;
}
table a
{
color: #333333;
text-decoration: none;
}
table a:hover
{
text-decoration: underline;
}
tr.odd
{
background: #f1f1f1;
}
tbody th, tbody td
{
padding: 5px;
padding-left: 10px;
}
td.sectionheader
{
color: Navy;
font-size: 20px;
font-weigth: bold;
text-align: center;
}
</style>
</head>
<body>
<xsl:apply-templates select=”//SourceMonitorComplexitySummary” />
</body>
</html>
</xsl:template>

<!– The most complex methods –>
<xsl:template match=”SourceMonitorComplexitySummary”>
<table class=”section-table” cellpadding=”2” cellspacing=”0” border=”0” width=”98%”>
<!–<colgroup>
<col width=”300px” />
<col width=”50px” />
<col />
<col width=”50px” />
</colgroup>–>
<tr>
<td class=”sectionheader” colspan=”4”>
SourceMonitor - <xsl:value-of select=”count(MostComplexMethods/Method)” /> Most Complex Methods
</td>
</tr>
<tr>
<th class=”header-label”>
Complexity
</th>
<th class=”header-label”>
File
</th>
<th class=”header-label”>
Method
</th>
<th class=”header-label”>
Line
</th>
</tr>
<xsl:apply-templates select=”MostComplexMethods/Method” />
</table>

<br/>

<!– The most deeply nested code blocks –>
<table class=”section-table” cellpadding=”2” cellspacing=”0” border=”0” width=”98%”>
<!–<colgroup>
<col width=”50px”/>
<col />
<col width=”50px” />
</colgroup>–>
<tr>
<td class=”sectionheader” colspan=”4”>
SourceMonitor - <xsl:value-of select=”count(MostDeeplyNestedCode/Block)” /> Most Deeply Nested Code Blocks
</td>
</tr>
<tr>
<th class=”header-label”>
Depth
</th>
<th class=”header-label”>
File
</th>
<th class=”header-label”>
Line
</th>
</tr>
<xsl:apply-templates select=”MostDeeplyNestedCode/Block” />
</table>
</xsl:template>

<!– Complex Method List –>
<xsl:template match=”MostComplexMethods/Method”>
<tr>
<xsl:if test=”position() mod 2 = 1”>
<xsl:attribute name=”class”>section-oddrow odd</xsl:attribute>
</xsl:if>
<td>
<xsl:value-of select=”Complexity” />
</td>
<td >
<xsl:value-of select=”File” />
</td>
<td>
<xsl:value-of select=”Name”/>
</td>
<td>
<xsl:value-of select=”Line” />
</td>
</tr>
</xsl:template>

<!– Deeply Nested Blocks List –>
<xsl:template match=”MostDeeplyNestedCode/Block”>
<tr>
<xsl:if test=”position() mod 2 = 1”>
<xsl:attribute name=”class”>section-oddrow odd</xsl:attribute>
</xsl:if>
<td>
<xsl:value-of select=”Depth” />
</td>
<td>
<xsl:value-of select=”File” />
</td>
<td>
<xsl:value-of select=”Line” />
</td>
</tr>
</xsl:template>

</xsl:stylesheet>


SourceMonitorSummaryGeneration.xsl
<?xml version=”1.0” encoding=”UTF-8” ?>
<xsl:stylesheet version=”1.0” xmlns:xsl=”http://www.w3.org/1999/XSL/Transform">

<!— SourceMonitor Summary Xml File Generation created by Eden Ridgway –>
<xsl:output method=”xml”/>

<xsl:template match=”/“>
<xsl:apply-templates select=”/sourcemonitor_metrics” />
</xsl:template>

<!– Transform the results into a simpler more intuitive and summarised format –>
<xsl:template match=”sourcemonitor_metrics”>
<SourceMonitorComplexitySummary>
<MostComplexMethods>
<xsl:call-template name=”MostComplexMethods”/>
</MostComplexMethods>

<LinePerMethod>
<xsl:call-template name=”LinesPerMethod”/>
</LinePerMethod>

<MostDeeplyNestedCode>
<xsl:call-template name=”MostDeeplyNestedCode”/>
</MostDeeplyNestedCode>

</SourceMonitorComplexitySummary>
</xsl:template>

<!– Complexity Metrics –>
<xsl:template name=”MostComplexMethods”>
<xsl:for-each select=”.//file”>
<xsl:sort select=”metrics/metric[@id=’M10’]” order=”descending” data-type=”number” />

<xsl:choose>
<xsl:when test=”position() &lt; 16”>
<Method>
<File><xsl:value-of select=”@file_name”/></File>
<Name><xsl:value-of select=”metrics/metric[@id=’M9’]”/></Name>
<Line><xsl:value-of select=”metrics/metric[@id=’M8’]”/></Line>
<Complexity><xsl:value-of select=”metrics/metric[@id=’M10’]”/></Complexity>
</Method>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>

<!– Complexity Metrics –>
<xsl:template name=”LinesPerMethod”>
<xsl:for-each select=”.//file”>
<xsl:sort select=”metrics/metric[@id=’M5’]” order=”descending” data-type=”number” />

<xsl:choose>
<xsl:when test=”position() &lt; 16”>
<Method>
<File><xsl:value-of select=”@file_name”/></File>
<Lines><xsl:value-of select=”metrics/metric[@id=’M5’]”/></Lines>
</Method>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>

<!– Nesting Metrics –>
<xsl:template name=”MostDeeplyNestedCode”>
<xsl:for-each select=”.//file”>
<xsl:sort select=”metrics/metric[@id=’M12’]” order=”descending” data-type=”text” />

<xsl:choose>
<xsl:when test=”position() &lt; 16”>
<Block>
<File><xsl:value-of select=”@file_name”/></File>
<Depth><xsl:value-of select=”metrics/metric[@id=’M12’]”/></Depth>
<Line><xsl:value-of select=”metrics/metric[@id=’M11’]”/></Line>
</Block>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>


透過批次檔得到HTML格式
SourceMonitor.exe /C SourceMonitorCommands.xml
msxsl.exe SourceMonitorReport.xml SourceMonitorSummaryGeneration.xsl -o SourceMonitorSummaryGeneration.xml
msxsl.exe SourceMonitorSummaryGeneration.xml SourceMonitor.xsl -o SourceMonitorResult.html

在TeamCity上面利用Command Line的Build Step來產出檔案
方便請見所以建立一個SourceMonitor的資料夾,把相關的執行檔和設定檔都放進去

新增一個建置報告
給一個用來識別的名稱和輸入產生的檔案

在一般設定中的Artifact Paths加入輸出的檔案
設定正確的話,建置後就可以看到這個報表了