Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- First phpuc 0.3.0 bugfix release for different artifact locations

  added.

git-svn-id: svn://phpunit.de/phpunit/phpUnderControl/tags/0.3.1@2216 c4a080f7-5c17-0410-a942-8af0f0140c7b
  • Loading branch information...
commit 1aa767bea88eed6104e838a76a8936c877d8f709 0 parents
@manuelpichler manuelpichler authored
Showing with 17,899 additions and 0 deletions.
  1. +36 −0 CHANGELOG
  2. +107 −0 bin/clearSetup.php
  3. +40 −0 bin/phpuc.bat
  4. +53 −0 bin/phpuc.php
  5. +42 −0 build.xml
  6. +185 −0 data/css/SyntaxHighlighter.css
  7. +328 −0 data/css/php-under-control.css
  8. +42 −0 data/footer.jsp
  9. +74 −0 data/header.jsp
  10. BIN  data/images/php-under-control/error.png
  11. BIN  data/images/php-under-control/failed.png
  12. BIN  data/images/php-under-control/header-center.png
  13. BIN  data/images/php-under-control/header-left-logo.png
  14. BIN  data/images/php-under-control/info.png
  15. BIN  data/images/php-under-control/skipped.png
  16. BIN  data/images/php-under-control/success.png
  17. BIN  data/images/php-under-control/tab-active.png
  18. BIN  data/images/php-under-control/tab-inactive.png
  19. BIN  data/images/php-under-control/warning.png
  20. +542 −0 data/index.jsp
  21. +10 −0 data/js/shBrushPhp.js
  22. +161 −0 data/js/shCore.js
  23. +105 −0 data/main.jsp
  24. +128 −0 data/metrics.cewolf.jsp
  25. +93 −0 data/metrics.jsp
  26. +42 −0 data/phpcs.jsp
  27. +42 −0 data/phpunit-pmd.jsp
  28. +39 −0 data/phpunit.jsp
  29. +66 −0 data/xsl/buildresults.xsl
  30. +102 −0 data/xsl/errors.xsl
  31. +82 −0 data/xsl/header.xsl
  32. +509 −0 data/xsl/modifications.xsl
  33. +174 −0 data/xsl/phpcs-details.xsl
  34. +104 −0 data/xsl/phpcs.xsl
  35. +98 −0 data/xsl/phpdoc.xsl
  36. +60 −0 data/xsl/phphelper.xsl
  37. +294 −0 data/xsl/phpunit-details.xsl
  38. +257 −0 data/xsl/phpunit-pmd-details.xsl
  39. +99 −0 data/xsl/phpunit-pmd.xsl
  40. +266 −0 data/xsl/phpunit.xsl
  41. +129 −0 docs/build.xml
  42. +169 −0 docs/config.xml
  43. +727 −0 docs/layout.svg
  44. BIN  docs/layout/header.png
  45. BIN  docs/layout/kore-header.png
  46. BIN  docs/layout/tabs.png
  47. +724 −0 docs/phpUnderControl-kore.svg
  48. +210 −0 example/src/Math.php
  49. +110 −0 example/tests/MathTest.php
  50. +40 −0 lib/ezc/autoload/base_autoload.php
  51. +122 −0 lib/ezc/autoload/graph_autoload.php
  52. +690 −0 package.xml
  53. +155 −0 src/Commands/AbstractCommand.php
  54. +103 −0 src/Commands/ExampleCommand.php
  55. +73 −0 src/Commands/GraphCommand.php
  56. +129 −0 src/Commands/InstallCommand.php
  57. +71 −0 src/Commands/ProjectCommand.php
  58. +174 −0 src/Console/ConsoleArgs.php
  59. +70 −0 src/Console/ConsoleExtensionI.php
  60. +526 −0 src/Console/ConsoleInput.php
  61. +296 −0 src/Console/ConsoleInputDefinition.php
  62. +211 −0 src/Console/ConsoleOutput.php
  63. +212 −0 src/Data/BuildFile.php
  64. +224 −0 src/Data/BuildTarget.php
  65. +185 −0 src/Data/ConfigArtifactsPublisher.php
  66. +153 −0 src/Data/ConfigExecutePublisher.php
  67. +161 −0 src/Data/ConfigFile.php
  68. +329 −0 src/Data/ConfigProject.php
  69. +68 −0 src/Data/ConfigPublisherI.php
  70. +133 −0 src/Data/LogFile.php
  71. +103 −0 src/Data/LogFileIterator.php
  72. +62 −0 src/Exceptions/ConsoleException.php
  73. +62 −0 src/Exceptions/ErrorException.php
  74. +62 −0 src/Exceptions/ExecuteException.php
  75. +62 −0 src/Exceptions/ValidateException.php
  76. +89 −0 src/Graph/ChartFactory.php
  77. +87 −0 src/Graph/ChartI.php
  78. +92 −0 src/Graph/DotChart.php
  79. +116 −0 src/Graph/GraphPalette.php
  80. +338 −0 src/Graph/Input/AbstractInput.php
  81. +117 −0 src/Graph/Input/BuildBreakdownInput.php
  82. +122 −0 src/Graph/Input/BuildBreakdownTimelineInput.php
  83. +108 −0 src/Graph/Input/CodeViolationInput.php
  84. +113 −0 src/Graph/Input/InputI.php
  85. +115 −0 src/Graph/Input/InputIterator.php
  86. +90 −0 src/Graph/Input/InputLoader.php
  87. +119 −0 src/Graph/Input/InputRule.php
  88. +106 −0 src/Graph/Input/TestCodeRatioInput.php
  89. +106 −0 src/Graph/Input/UnitCoverageInput.php
  90. +92 −0 src/Graph/Input/UnitTestInput.php
  91. +175 −0 src/Graph/LineChart.php
  92. +139 −0 src/Graph/PieChart.php
  93. +165 −0 src/PhpUnderControl.php
  94. +203 −0 src/Tasks/AbstractPearTask.php
  95. +144 −0 src/Tasks/AbstractTask.php
  96. +115 −0 src/Tasks/CreateFileTask.php
  97. +179 −0 src/Tasks/CruiseControlTask.php
  98. +141 −0 src/Tasks/ExampleTask.php
  99. +134 −0 src/Tasks/GenerateGraphTask.php
  100. +97 −0 src/Tasks/GraphTask.php
  101. +145 −0 src/Tasks/ModifyFileTask.php
  102. +166 −0 src/Tasks/PhpCodeSnifferTask.php
  103. +121 −0 src/Tasks/PhpDocumentorTask.php
  104. +204 −0 src/Tasks/PhpUnitTask.php
  105. +153 −0 src/Tasks/ProjectTask.php
  106. +106 −0 src/Tasks/TaskI.php
  107. +106 −0 src/Util/Autoloader.php
  108. +263 −0 src/Util/FileUtil.php
  109. +72 −0 src/Util/PhpFileFilterIterator.php
  110. +20 −0 template/project.xml
  111. +230 −0 tests/AbstractTest.php
  112. +100 −0 tests/AllTests.php
  113. +94 −0 tests/Console/ConsoleAllTests.php
  114. +248 −0 tests/Console/ConsoleArgsTest.php
  115. +88 −0 tests/Data/AbstractConfigTest.php
  116. +168 −0 tests/Data/BuildFileTest.php
  117. +175 −0 tests/Data/BuildTargetTest.php
  118. +140 −0 tests/Data/ConfigFileTest.php
  119. +94 −0 tests/Data/ConfigProjectTest.php
  120. +100 −0 tests/Data/DataAllTests.php
  121. +163 −0 tests/Tasks/AbstractPearTaskTest.php
  122. +179 −0 tests/Tasks/CruiseControlTaskTest.php
  123. +136 −0 tests/Tasks/PhpCodeSnifferTaskTest.php
  124. +195 −0 tests/Tasks/ProjectTaskTest.php
  125. +98 −0 tests/Tasks/TasksAllTests.php
  126. +214 −0 tests/Util/FileUtilTest.php
  127. +94 −0 tests/Util/UtilAllTests.php
36 CHANGELOG
@@ -0,0 +1,36 @@
+phpUnderControl 0.3.1
+- Bugfix for different artifact locations.
+
+phpUnderControl 0.3.0
+
+Core
+- New console input class added.
+- New dynamic command/option layer for console started.
+- New ezcGraph based metrics view integrated.
+- Changed from static to dynamic autoloading.
+
+phpUnderControl 0.2.2
+---------------------
+
+Core
+- Default body background color set.
+- Documented example for the CruiseControl config.xml file and an ant build.xml
+ file for the phpUnderControl project added.
+
+phpUnderControl 0.2.1
+---------------------
+
+Core
+- Three new metric views added. Thanks to Sebastian for this great idea.
+ 1) Unit Tests vs. Number of Failing Unit Tests.
+ 2) Executable Lines of Code vs. Code Coverage in Percent.
+ 3) Classes/Methods vs. Number of Tested Classes/Methods
+- Dependency to latest PHP_CodeSniffer version 1.0.0RC3 increased.
+- CruiseControl config.xml file abstration implemented.
+- Source refactored to make the command line stuff testable.
+- Many code cleanups and documentation fixes.
+
+Tests
+- Test cases for the cli tool added.
+- Test cases for the build file abstraction added.
+- Test cases for some tasks added.
107 bin/clearSetup.php
@@ -0,0 +1,107 @@
+#!/usr/bin/env php
+<?php
+/**
+ * This file is part of phpUnderControl.
+ *
+ * Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Manuel Pichler <mapi@phpundercontrol.org>
+ * @copyright 2007-2008 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id: phpuc.php 2010 2008-01-02 12:24:48Z mapi $
+ * @link http://www.phpundercontrol.org/
+ */
+
+if ( stripos( PHP_OS, 'WIN' ) === false )
+{
+ $rmcmd = 'rm -rf';
+ $copycmd = 'cp -rf';
+ $installDir = '/opt/cruisecontrol';
+}
+else
+{
+ $rmcmd = 'rmdir /S /Q';
+ $copycmd = 'xcopy /S /E /I';
+ $installDir = 'c:\Programme\CruiseControl';
+}
+if ( count( $GLOBALS['argv'] ) > 1 )
+{
+ $installDir = $GLOBALS['argv'][1];
+}
+
+$config = new DOMDocument( '1.0', 'UTF-8' );
+$config->formatOutput = true;
+$config->preserveWhiteSpace = false;
+$config->load( $installDir . '/config.xml' );
+
+$xpath = new DOMXPath( $config );
+$result = $xpath->query( '//project[@name="php-under-control"]' );
+
+if ( $result->length > 0 )
+{
+ $node = $result->item( 0 );
+ $node->parentNode->removeChild( $node );
+
+ $config->save( $installDir . '/config.xml' );
+}
+
+$projectDir = sprintf(
+ "%s%sprojects%sphp-under-control",
+ $installDir,
+ DIRECTORY_SEPARATOR,
+ DIRECTORY_SEPARATOR
+);
+if ( file_exists( $projectDir ) && is_dir( $projectDir ) )
+{
+ system( "{$rmcmd} {$projectDir}" );
+}
+
+$webappsOrig = sprintf(
+ "%s%swebapps%scruisecontrol.orig",
+ $installDir,
+ DIRECTORY_SEPARATOR,
+ DIRECTORY_SEPARATOR
+);
+if ( file_exists( $webappsOrig ) && is_dir( $webappsOrig ) )
+{
+ $webapps = sprintf(
+ "%s%swebapps%scruisecontrol",
+ $installDir,
+ DIRECTORY_SEPARATOR,
+ DIRECTORY_SEPARATOR
+ );
+
+ system( "{$rmcmd} {$webapps}" );
+
+ system( "{$copycmd} {$webappsOrig} {$webapps}" );
+}
40 bin/phpuc.bat
@@ -0,0 +1,40 @@
+@echo off
+REM This file is part of phpUnderControl.
+REM
+REM Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+REM All rights reserved.
+REM
+REM Redistribution and use in source and binary forms, with or without
+REM modification, are permitted provided that the following conditions
+REM are met:
+REM
+REM * Redistributions of source code must retain the above copyright
+REM notice, this list of conditions and the following disclaimer.
+REM
+REM * Redistributions in binary form must reproduce the above copyright
+REM notice, this list of conditions and the following disclaimer in
+REM the documentation and/or other materials provided with the
+REM distribution.
+REM
+REM * Neither the name of Manuel Pichler nor the names of his
+REM contributors may be used to endorse or promote products derived
+REM from this software without specific prior written permission.
+REM
+REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+REM "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+REM LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+REM FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+REM COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+REM INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+REM BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+REM LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
+REM LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+REM ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+REM POSSIBILITY OF SUCH DAMAGE.
+REM
+REM $Id$
+REM
+
+set PHPBIN="@php_bin@"
+"@php_bin@" "@bin_dir@\phpuc" %*
53 bin/phpuc.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+<?php
+/**
+ * This file is part of phpUnderControl.
+ *
+ * Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Manuel Pichler <mapi@phpundercontrol.org>
+ * @copyright 2007-2008 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id:phpuc.php 2195 2008-01-18 14:02:18Z mapi $
+ * @link http://www.phpundercontrol.org/
+ */
+
+if ( strpos( '@php_dir@', '@php_dir' ) === 0 )
+{
+ require_once dirname( __FILE__ ) . '/../src/PhpUnderControl.php';
+}
+else
+{
+ require_once '@php_dir@/phpUnderControl/PhpUnderControl.php';
+}
+phpucPhpUnderControl::main();
42 build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="phpUnderControl" basedir="." default="build">
+
+ <property name="output.dir" value="${basedir}/build" />
+
+ <target name="update">
+ <exec executable="svn">
+ <arg line="up"/>
+ </exec>
+ </target>
+
+ <target name="test">
+ <mkdir dir="${output.dir}/logs"/>
+ <mkdir dir="${output.dir}/coverage"/>
+ <exec dir="tests" executable="phpunit">
+ <arg line="--log-pmd ${output.dir}/logs/pmd.xml
+ --log-metrics ${output.dir}/logs/metrics.xml
+ --coverage-xml ${output.dir}/logs/coverage.xml
+ --coverage-html ${output.dir}/coverage
+ phpucAllTests AllTests.php"/>
+ </exec>
+ </target>
+
+ <target name="phpdoc">
+ <mkdir dir="${output.dir}/api"/>
+ <exec dir="src" executable="phpdoc">
+ <arg line="-ct type -ue on -t ${output.dir}/api -d ."/>
+ </exec>
+ </target>
+
+ <target name="sniff">
+ <mkdir dir="${output.dir}/logs"/>
+ <exec dir="src" executable="phpcs" output="${output.dir}/logs/codesniffer.xml">
+ <arg line="--report=checkstyle --standard=MapiSource ." />
+ </exec>
+ </target>
+
+ <target name="build">
+
+ </target>
+
+</project>
185 data/css/SyntaxHighlighter.css
@@ -0,0 +1,185 @@
+.dp-highlighter
+{
+ font-family: "Consolas", "Courier New", Courier, mono, serif;
+ font-size: 12px;
+ background-color: #E7E5DC;
+ width: 99%;
+ overflow: auto;
+ margin: 18px 0 18px 0 !important;
+ padding-top: 1px; /* adds a little border on top when controls are hidden */
+}
+
+/* clear styles */
+.dp-highlighter ol,
+.dp-highlighter ol li,
+.dp-highlighter ol li span
+{
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+
+.dp-highlighter a,
+.dp-highlighter a:hover
+{
+ background: none;
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+
+.dp-highlighter .bar
+{
+ padding-left: 45px;
+}
+
+.dp-highlighter.collapsed .bar,
+.dp-highlighter.nogutter .bar
+{
+ padding-left: 0px;
+}
+
+.dp-highlighter ol
+{
+ list-style: decimal; /* for ie */
+ background-color: #fff;
+ margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
+ padding: 0px;
+ color: #5C5C5C;
+}
+
+.dp-highlighter.nogutter ol,
+.dp-highlighter.nogutter ol li
+{
+ list-style: none !important;
+ margin-left: 0px !important;
+}
+
+.dp-highlighter ol li,
+.dp-highlighter .columns div
+{
+ list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
+ list-style-position: outside !important;
+ border-left: 3px solid #6CE26C;
+ background-color: #F8F8F8;
+ color: #5C5C5C;
+ padding: 0 3px 0 10px !important;
+ margin: 0 !important;
+ line-height: 14px;
+}
+
+.dp-highlighter.nogutter ol li,
+.dp-highlighter.nogutter .columns div
+{
+ border: 0;
+}
+
+.dp-highlighter .columns
+{
+ background-color: #F8F8F8;
+ color: gray;
+ overflow: hidden;
+ width: 100%;
+}
+
+.dp-highlighter .columns div
+{
+ padding-bottom: 5px;
+}
+
+.dp-highlighter ol li.alt
+{
+ background-color: #FFF;
+ color: inherit;
+}
+
+.dp-highlighter ol li span
+{
+ color: black;
+ background-color: inherit;
+}
+
+/* Adjust some properties when collapsed */
+
+.dp-highlighter.collapsed ol
+{
+ margin: 0px;
+}
+
+.dp-highlighter.collapsed ol li
+{
+ display: none;
+}
+
+/* Additional modifications when in print-view */
+
+.dp-highlighter.printing
+{
+ border: none;
+}
+
+.dp-highlighter.printing .tools
+{
+ display: none !important;
+}
+
+.dp-highlighter.printing li
+{
+ display: list-item !important;
+}
+
+/* Styles for the tools */
+
+.dp-highlighter .tools
+{
+ padding: 3px 8px 3px 10px;
+ font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
+ color: silver;
+ background-color: #f8f8f8;
+ padding-bottom: 10px;
+ border-left: 3px solid #6CE26C;
+}
+
+.dp-highlighter.nogutter .tools
+{
+ border-left: 0;
+}
+
+.dp-highlighter.collapsed .tools
+{
+ border-bottom: 0;
+}
+
+.dp-highlighter .tools a
+{
+ font-size: 9px;
+ color: #a0a0a0;
+ background-color: inherit;
+ text-decoration: none;
+ margin-right: 10px;
+}
+
+.dp-highlighter .tools a:hover
+{
+ color: red;
+ background-color: inherit;
+ text-decoration: underline;
+}
+
+/* About dialog styles */
+
+.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
+.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
+.dp-about td { padding: 10px; vertical-align: top; }
+.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
+.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
+.dp-about .para { margin: 0 0 4px 0; }
+.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
+.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }
+
+/* Language specific styles */
+
+.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
+.dp-highlighter .string { color: blue; background-color: inherit; }
+.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
+.dp-highlighter .preprocessor { color: gray; background-color: inherit; }
328 data/css/php-under-control.css
@@ -0,0 +1,328 @@
+/**
+ * This file is part of phpUnderControl.
+ *
+ * Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Manuel Pichler <mapi@phpundercontrol.org>
+ * @copyright 2007-2008 Manuel Pichler. All rights reserved.
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @link http://www.phpunit.de/wiki/phpUnderControl
+ */
+body {
+ background-color: #fff;
+ color: #2e3436;
+ font-family: arial, helvetica, sans-serif;
+ font-size: 11px;
+ margin: 0;
+ padding: 0;
+}
+
+a {
+ color: #437610;
+}
+
+* {
+ border: 0;
+ margin: 0;
+ padding: 0;
+}
+
+div#container {
+ background: transparent url('../images/php-under-control/header-right.png') right top no-repeat;
+ position: relative;
+ width: 100%;
+}
+
+/**
+ * Header/Headline styles
+ */
+div#container h1 {
+ background: transparent url('../images/php-under-control/header-center.png') left top repeat-x;
+ color: #eeeeec;
+ font-size: 16px;
+ position: relative;
+}
+
+div#container h1 a {
+ background: transparent url('../images/php-under-control/header-left-logo.png') left top repeat-x;
+ display: block;
+ height: 79px;
+ text-indent: -9999px;
+ width: 180px;
+}
+
+/**
+ * Header form styles
+ */
+div#container form#cc-project,div#container form#cc-build {
+ position: absolute;
+ top: 25px;
+ padding: 0;
+}
+
+div#container form fieldset {
+ border: 0 none;
+ margin: 0;
+ padding: 5px;
+ width: 165px;
+}
+
+div#container form fieldset legend a {
+ color: #eeeeec;
+ display: block;
+ font-weight: bold;
+ margin-left: 8px;
+ text-decoration: none;
+}
+
+div#container form fieldset select {
+ border: 1px solid #2e3436;
+ font-size: 11px;
+ margin: 0;
+ padding: 0;
+ width: 150px;
+}
+
+div#container form#cc-project {
+ right: 400px;
+}
+
+div#container form#cc-build {
+ right: 200px;
+}
+
+div#container h2#cc-build-status {
+ color: #babdb6;
+ display: block;
+ font-size: 11px;
+ font-style: italic;
+ font-weight: normal;
+ position: absolute;
+ right: 20px;
+ text-align: right;
+ top: 25px;
+}
+
+/**
+ * Navigation styles
+ */
+div#container table img {
+ display: none;
+}
+
+div#container table div {
+ background: transparent url('../images/php-under-control/tab-inactive.png') 0 0 repeat-x;
+ background-color: #babdb6;
+ height: 21px;
+}
+
+div#container .tab-table {
+ float: left;
+ border: 0 none;
+}
+
+div#container .tab-table .tabs,.tab-table .tabs-selected {
+ background: transparent;
+ border: 0 none;
+ padding: 0;
+}
+
+div#container .tab-table .tabs a,.tab-table .tabs-selected {
+ border-right: 1px solid #d4d6d1;
+ color: #eeeeec;
+ display: block;
+ font-size: 11px;
+ line-height: 21px;
+ text-align: center;
+ text-decoration: none;
+ width: 90px;
+}
+
+div#container .tab-table .tabs a:hover,.tab-table .tabs-selected {
+ background: transparent url('../images/php-under-control/tab-active.png') 0 0 repeat-x;
+}
+
+/**
+ * Content area styles
+ */
+div#container table td {
+ background-color: #fff;
+}
+
+div#container table.result {
+ border: 0 none;
+ border-collapse: collapse;
+ margin: 10px 1% 15px 1%;
+ width: 98%;
+}
+
+div#container table.result thead th {
+ border-bottom: 1px solid #babdb6;
+ color: #555753;
+ font-size: 13px;
+ line-height: 20px;
+ text-align: left;
+ text-indent: 5px;
+ white-space: nowrap;
+}
+
+div#container table.result thead th a {
+ color: #555753;
+ text-decoration: none;
+}
+
+div#container table.result thead th a:hover {
+ text-decoration: underline;
+}
+
+div#container table.result tbody td {
+ font-size: 11px;
+ line-height: 15px;
+ padding-left: 5px;
+}
+
+div#container table.result tbody tr.oddrow td {
+ background-color: #eeeeec;
+}
+
+div#container table.result tbody th {
+ border-bottom: 1px solid #babdb6;
+ color: #555753;
+ font-size: 12px;
+ line-height: 20px;
+ text-align: left;
+ text-indent: 5px;
+ white-space: nowrap;
+}
+
+div#container table.result tbody tr.error th {
+
+}
+
+div#container table.result tbody tr.failure th {
+
+}
+
+div#container table.result tbody td.info,div#container table.result tbody td.error,div#container table.result tbody td.failure,div#container table.result tbody td.warning,div#container table.result tbody td.success
+{
+ background: transparent none 4px 50% no-repeat;
+ line-height: 16px;
+ padding-left: 24px;
+}
+
+div#container table.result tbody td.info {
+ background-image: url('../images/php-under-control/info.png');
+}
+
+div#container table.result tbody td.failure {
+ background-image: url('../images/php-under-control/failed.png');
+}
+
+div#container table.result tbody td.error {
+ background-image: url('../images/php-under-control/error.png');
+}
+
+div#container table.result tbody td.warning {
+ background-image: url('../images/php-under-control/warning.png');
+}
+
+div#container table.result tbody td.success {
+ background-image: url('../images/php-under-control/success.png');
+}
+
+div#container table.result tbody td input.button {
+ border: 1px solid #555753;
+ color: #2e3436;
+ font-size: 11px;
+ padding: 1px 10px;
+}
+
+div#container pre.code-fragment,div#container .testresults-output {
+ background-color: #fff;
+ border: 1px solid #d3d7cf;
+ margin: 1px 0;
+}
+
+div#container h2 {
+ color: #555753;
+ font-size: 16px;
+ font-weight: bold;
+ margin: 8px 0 4px 20px;
+}
+
+div#container h3 {
+ color: #a40000;
+}
+
+div#container dl {
+ margin: 4px 0 8px 20px;
+ font-size: 12px;
+}
+
+div#container dl dt {
+ float: left;
+ width: 180px;
+}
+
+div#container dl dd {
+ margin-bottom: 3px;
+}
+
+div#container a.failure {
+ color: #c00;
+}
+
+div#container table iframe.chart {
+ border: 0 none;
+ height: 250px;
+ margin: 10px;
+ width: 390px;
+}
+
+div.dp-highlighter {
+ margin: 0 0 18px 0 !important;
+ width: 100%;
+}
+
+div#container table div.dp-highlighter,div#container table div.dp-highlighter div
+ {
+ background: inherit;
+ height: inherit;
+}
+
+div#footer {
+ color: #555753;
+ margin: 12px;
+ text-align: center;
+}
42 data/footer.jsp
@@ -0,0 +1,42 @@
+<%--********************************************************************************
+ * This file is part of phpUnderControl.
+ *
+ * Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************--%>
+<%@ page language="java" pageEncoding="UTF-8"%>
+<div id="footer">
+ <a href="http://www.phpundercontrol.org">phpUnderControl - SVN</a>
+ is Copyright (C) 2007-2008
+ by <a href="http://www.manuel-pichler.de/">Manuel Pichler</a> hosted
+ on <a href="http://www.phpunit.de/">phpunit.de</a>.
+</div>
74 data/header.jsp
@@ -0,0 +1,74 @@
+<%--********************************************************************************
+ * CruiseControl, a Continuous Integration Toolkit
+ * Copyright (c) 2001, ThoughtWorks, Inc.
+ * 200 E. Randolph, 25th Floor
+ * Chicago, IL 60601 USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * + Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * + Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************--%>
+<%@page import="java.io.File, java.util.Arrays"%>
+<%@ taglib uri="/WEB-INF/cruisecontrol-jsp11.tld" prefix="cruisecontrol"%>
+
+ <cruisecontrol:link id="baseUrl" />
+ <h1>
+ <a href="index">
+ phpUnderControl
+ </a>
+ </h1>
+
+ <form action="index" id="cc-project">
+ <fieldset>
+ <legend><a href="index">Project:</a></legend>
+ <select name="projecttarget" onchange="self.location.href = this.form.projecttarget.options[this.form.projecttarget.selectedIndex].value">
+ <cruisecontrol:projectnav>
+ <option <%=selected%> value="<%=projecturl%>"><%=linktext%></option>
+ </cruisecontrol:projectnav>
+ </select>
+ </fieldset>
+ </form>
+
+
+ <form method="GET" action="<%=baseUrl%>" id="cc-build">
+ <fieldset>
+ <legend><a href="<%=baseUrl%>">Build:</a></legend>
+
+ <select name="log" onchange="form.submit()">
+ <option>More builds</option>
+ <cruisecontrol:nav startingBuildNumber="1">
+ <option value="<%=logfile%>"><%= linktext %></option>
+ </cruisecontrol:nav>
+ </select>
+ </fieldset>
+ </form>
+
+ <h2 id="cc-build-status">
+ <cruisecontrol:currentbuildstatus/>
+ </h2>
BIN  data/images/php-under-control/error.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/failed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/header-center.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/header-left-logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/info.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/skipped.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/success.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/tab-active.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/tab-inactive.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  data/images/php-under-control/warning.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
542 data/index.jsp
@@ -0,0 +1,542 @@
+<%--********************************************************************************
+* CruiseControl, a Continuous Integration Toolkit
+* Copyright (c) 2001, ThoughtWorks, Inc.
+* 200 E. Randolph, 25th Floor
+* Chicago, IL 60601 USA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* + Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* + Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+*
+* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
+* names of its contributors may be used to endorse or promote
+* products derived from this software without specific prior
+* written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+********************************************************************************--%>
+<%@ page errorPage="/error.jsp" contentType="text/html; charset=UTF-8"%>
+<%@ taglib uri="/WEB-INF/cruisecontrol-jsp11.tld" prefix="cruisecontrol"%>
+<%@ page import="net.sourceforge.cruisecontrol.*" %>
+<%@ page import="java.io.IOException" %>
+<%@ page import="java.net.InetAddress" %>
+<%@ page import="java.net.URL" %>
+<%@ page import="java.text.DateFormat" %>
+<%@ page import="java.io.File" %>
+<%@ page import="java.util.Arrays" %>
+<%@ page import="java.text.ParseException" %>
+<%@ page import="java.io.BufferedReader" %>
+<%@ page import="java.io.FileReader" %>
+<%@ page import="java.util.HashMap" %>
+<%@ page import="java.util.Date" %>
+<%@ page import="java.util.Comparator" %>
+<%@ page import="java.util.Map" %>
+
+
+<%
+ final DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, request.getLocale());
+ final DateFormat dateOnlyFormat = DateFormat.getDateInstance(DateFormat.SHORT, request.getLocale());
+ final DateFormat timeOnlyFormat = DateFormat.getTimeInstance(DateFormat.SHORT, request.getLocale());
+
+ final Date now = new Date();
+ final String dateNow = dateTimeFormat.format(now);
+%>
+
+<%
+ class SortableStatus implements Comparable {
+ private ProjectState state;
+ private String importance;
+ private int sortOrder;
+
+ public SortableStatus(ProjectState state, String importance, int sortOrder) {
+ this.state = state;
+ this.importance = importance;
+ this.sortOrder = sortOrder;
+ }
+
+ public String toString() {
+ return state != null ? state.getName() : "?";
+ }
+
+ public int getSortOrder() {
+ return sortOrder;
+ }
+
+ public int compareTo(Object other) {
+ SortableStatus that = (SortableStatus) other;
+ return this.sortOrder - that.sortOrder;
+ }
+
+ public String getImportance() {
+ return importance;
+ }
+ }
+
+ class StatusCollection {
+ private Map statuses = new HashMap();
+ private SortableStatus unknown = new SortableStatus(null, "dull", -1);
+
+ public void add(ProjectState state, String importance) {
+ statuses.put(state.getDescription(), new SortableStatus(state, importance, statuses.size()));
+ }
+
+ public SortableStatus get(String statusDescription) {
+ Object status = statuses.get(statusDescription);
+ if (status != null) {
+ return (SortableStatus) status;
+ }
+ return unknown;
+ }
+ }
+
+%>
+
+<%
+ final StatusCollection statuses = new StatusCollection();
+ statuses.add(ProjectState.PUBLISHING, "important");
+ statuses.add(ProjectState.MODIFICATIONSET, "important");
+ statuses.add(ProjectState.BUILDING, "important");
+ statuses.add(ProjectState.MERGING_LOGS, "important");
+ statuses.add(ProjectState.QUEUED, "normal");
+ statuses.add(ProjectState.WAITING, "dull");
+ statuses.add(ProjectState.IDLE, "dull");
+ statuses.add(ProjectState.PAUSED, "dull");
+ statuses.add(ProjectState.STOPPED, "dull");
+%>
+<cruisecontrol:jmxbase id="jmxBase"/>
+<%
+ String name = System.getProperty("ccname", "");
+ String hostname = InetAddress.getLocalHost().getHostName();
+ boolean jmxEnabled = true;
+ URL jmxURLPrefix = new URL(jmxBase, "invoke?operation=build&objectname=CruiseControl+Project%3Aname%3D");
+
+ final String statusFileName = application.getInitParameter("currentBuildStatusFile");
+
+ String baseURL = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ + request.getContextPath() + "/";
+ String thisURL = request.getRequestURI();
+
+ String sort = request.getParameter("sort");
+ if(sort == null){
+ sort = "none";
+ }
+%>
+
+
+<%
+ class Info implements Comparable {
+ public static final int ONE_DAY = 1000 * 60 * 60 * 24;
+
+ private BuildInfo latest;
+ private BuildInfo lastSuccessful;
+ private SortableStatus status;
+ private Date statusSince;
+ private String project;
+ private String statusDescription;
+
+ public Info(File logsDir, String project) throws ParseException, IOException {
+ this.project = project;
+
+ File projectLogDir = new File(logsDir, project);
+ LogFile latestLogFile = LogFile.getLatestLogFile(projectLogDir);
+ LogFile latestSuccessfulLogFile = LogFile.getLatestSuccessfulLogFile(projectLogDir);
+
+
+ if (latestLogFile != null) {
+ latest = new BuildInfo(latestLogFile);
+ }
+ if (latestSuccessfulLogFile != null) {
+ lastSuccessful = new BuildInfo(latestSuccessfulLogFile);
+ }
+
+ File statusFile = new File(projectLogDir, statusFileName);
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(statusFile));
+ statusDescription = reader.readLine().replaceAll(" since", "");
+
+ status = statuses.get(statusDescription);
+ statusSince = new Date(statusFile.lastModified());
+ }
+ catch (Exception e) {
+ status = statuses.unknown;
+ statusSince = now;
+ }
+ finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+ public String getLastBuildTime() {
+ return getTime(latest);
+ }
+
+ public String getLastSuccessfulBuildTime() {
+ return getTime(lastSuccessful);
+ }
+
+ private String getTime(BuildInfo build) {
+ return build != null ? format(build.getBuildDate()) : "";
+ }
+
+ public String format(Date date) {
+ if (date == null) {
+ return "";
+ }
+
+ if ((now.getTime() < date.getTime())) {
+ return dateTimeFormat.format(date);
+ }
+
+ if ((now.getTime() - date.getTime()) < ONE_DAY) {
+ return timeOnlyFormat.format(date);
+ }
+
+ return dateOnlyFormat.format(date);
+ }
+
+ public String getStatusSince() {
+ return statusSince != null ? format(statusSince) : "?";
+ }
+
+ public boolean failed() {
+ return latest == null || ! latest.isSuccessful();
+ }
+
+ public SortableStatus getStatus() {
+ return status;
+ }
+
+ public int compareTo(Object other) {
+ Info that = (Info) other;
+
+ int order = this.status.compareTo(that.status);
+ if (order != 0) {
+ return order;
+ }
+
+ return (int) (this.statusSince.getTime() - that.statusSince.getTime());
+ }
+
+ public String getLabel() {
+ return lastSuccessful != null ? lastSuccessful.getLabel() : " ";
+ }
+ }
+
+%>
+
+<%
+ final Map sortOrders = new HashMap();
+
+ sortOrders.put("project", new Comparator() {
+ public int compare(Object a, Object b) {
+ Info infoA = (Info) a;
+ Info infoB = (Info) b;
+ return infoA.project.compareTo(infoB.project);
+ }
+ });
+
+ sortOrders.put("status", new Comparator() {
+ public int compare(Object a, Object b) {
+ Info infoA = (Info) a;
+ Info infoB = (Info) b;
+ return infoA.compareTo(infoB);
+ }
+ });
+
+ sortOrders.put("label", new Comparator() {
+ public int compare(Object a, Object b) {
+ Info infoA = (Info) a;
+ Info infoB = (Info) b;
+ return infoA.getLabel().compareTo(infoB.getLabel());
+ }
+ });
+
+ sortOrders.put("last failure", new Comparator() {
+ public int compare(Object a, Object b) {
+ Info infoA = (Info) a;
+ Info infoB = (Info) b;
+
+ if (infoA.latest == null) {
+ return 1;
+ }
+
+ if (infoB.latest == null) {
+ return -1;
+ }
+
+ if (infoA.failed() != infoB.failed()) {
+ return infoA.failed() ? -1 : 1;
+ }
+
+ return infoB.latest.compareTo(infoA.latest);
+ }
+ });
+
+ sortOrders.put("last successful", new Comparator() {
+ public int compare(Object a, Object b) {
+ Info infoA = (Info) a;
+ Info infoB = (Info) b;
+
+ if (infoA.lastSuccessful == null) {
+ return 1;
+ }
+ if (infoB.lastSuccessful == null) {
+ return -1;
+ }
+
+ return infoB.lastSuccessful.compareTo(infoA.lastSuccessful);
+ }
+ });
+%>
+
+<html>
+<head>
+ <title><%= name%> phpUnderControl - SVN at <%= hostname %></title>
+
+ <base href="<%=baseURL%>"/>
+ <link type="application/rss+xml" rel="alternate" href="rss" title="RSS"/>
+ <link type="text/css" rel="stylesheet" href="css/php-under-control.css"/>
+ <META HTTP-EQUIV="Refresh" CONTENT="10" URL="<%=thisURL%>?sort=<%=sort%>">
+ <style type="text/css">
+ thead td {
+ padding: 2 5
+ }
+
+ .data {
+ padding: 2 5
+ }
+
+ .date {
+ text-align: right;
+ }
+
+ .status-important {
+ font-weight: bold;
+ }
+
+ .status-normal {
+ }
+
+ .status-dull {
+ font-style: italic;
+ }
+
+ .failure {
+ background-color: #fff;
+ color: red;
+ font-weight: bold
+ }
+
+ .currently-failing {
+ color: red;
+ font-weight: bold
+ }
+
+ .currently-passing {
+ color: gray;
+ }
+
+ a.sort {
+ color: firebrick;
+ }
+
+ a.sorted {
+ color: darkblue;
+ }
+
+ .dateNow {
+ font-size: 15px;
+ font-style: italic;
+ }
+
+ .odd-row {
+ background-color: #CCCCCC;
+ }
+
+ /*.even-row {
+ background-color: #FFFFCC;
+ }*/
+
+ .header-row {
+ background-color: white;
+ color: darkblue;
+ }
+</style>
+
+ <script language="JavaScript">
+ function callServer(url, projectName) {
+ document.getElementById('serverData').innerHTML = '<iframe src="' + url + '" width="0" height="0" frameborder="0"></iframe>';
+ alert('Scheduling build for ' + projectName);
+ }
+
+ function checkIframe(stylesheetURL) {
+ if (top != self) {//We are being framed!
+
+ //For Internet Explorer
+ if (document.createStyleSheet) {
+ document.createStyleSheet(stylesheetURL);
+
+ }
+ else { //Non-ie browsers
+
+ var styles = "@import url('" + stylesheetURL + "');";
+
+ var newSS = document.createElement('link');
+
+ newSS.rel = 'stylesheet';
+
+ newSS.href = 'data:text/css,' + escape(styles);
+
+ document.getElementsByTagName("head")[0].appendChild(newSS);
+
+ }
+ }
+ }
+ </script>
+</head>
+
+
+<body onload="checkIframe('<%=baseURL + "css/php-under-control.css"%>')">
+ <div id="container">
+ <cruisecontrol:link id="baseUrl" />
+ <h1>
+ <a href="<%=baseUrl%>">
+ phpUnderControl
+ </a>
+ </h1>
+ <h1 style="padding: 3px 0;" class="white" align="center">
+ <%= name%> phpUnderControl at <%= hostname %><span class="dateNow">[<%= dateNow %>]</span>
+ </h1>
+ <div id="serverData" class="hidden"></div>
+ <form>
+ <table style="width:65%;margin: 20px auto" align="center">
+ <tbody>
+
+ <tr><td colspan="2">&nbsp;</td></tr>
+ <tr>
+ <td class="header-row"><img border="0" src="images/bluestripestop.gif"/></td>
+ <td class="header-row" align="right"><img border="0" src="images/bluestripestopright.gif"/></td>
+ </tr>
+
+
+ <tr><td colspan="2">
+ <table class="result">
+ <%
+ String logDirPath = application.getInitParameter("logDir");
+ if (logDirPath == null) {
+ %><tr><td>You need to provide a value for the context parameter <code>&quot;logDir&quot;</code></td></tr><%
+ }
+ else {
+ java.io.File logDir = new java.io.File(logDirPath);
+ if (logDir.isDirectory() == false) {
+ %><tr><td>Context parameter logDir needs to be set to a directory. Currently set to &quot;<%=logDirPath%>
+ &quot;</td></tr><%
+ }
+ else {
+ String[] projectDirs = logDir.list(new java.io.FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return (new File(dir, name).isDirectory());
+ }
+ });
+
+ if (projectDirs.length == 0) {
+ %><tr><td>no project directories found under <%=logDirPath%></td></tr><%
+ }
+ else {
+ %>
+ <thead class="index-header">
+ <tr>
+ <th><a class='<%= "project".equals(sort) ? "sort" : "sorted" %>' href="<%=thisURL%>?sort=project">Project</a></th>
+ <th><a class="<%= "status".equals(sort) ? "sort" : "sorted" %>" href="<%=thisURL%>?sort=status">Status <em>(since)</em></a></th>
+ <th><a class="<%= "last failure".equals(sort) ? "sort" : "sorted" %>" href="<%=thisURL%>?sort=last failure">Last failure</a></th>
+ <th><a class="<%= "last successful".equals(sort) ? "sort" : "sorted" %>" href="<%=thisURL%>?sort=last successful">Last successful</a></th>
+ <th>Label</th>
+ <% if (jmxEnabled) { %>
+ <th></th>
+ <% } //end if jmxEnabled %>
+ </tr>
+ </thead>
+
+
+ <tbody>
+ <%
+ Info[] info = new Info[projectDirs.length];
+ for (int i = 0; i < info.length; i++) {
+ info[i] = new Info(logDir, projectDirs[i]);
+ }
+
+ Comparator order = (Comparator) sortOrders.get(sort);
+ if (order == null) {
+ Arrays.sort(info);
+ }
+ else {
+ Arrays.sort(info, order);
+ }
+
+ for (int i = 0; i < info.length; i++) {
+ %>
+ <tr class="<%= (i % 2 == 1) ? "even-row" : "odd-row" %> ">
+ <td class="data"><a href="buildresults/<%=info[i].project%>"><%=info[i].project%></a></td>
+ <td class="data date status-<%= info[i].getStatus().getImportance() %>"><%= info[i].getStatus()%> <em>(<%= info[i].getStatusSince() %>)</em></td>
+ <td style="background-color: #fff;" class="data date failure"><%= (info[i].failed()) ? info[i].getLastBuildTime() : "" %></td>
+ <td class="data date"><%= info[i].getLastSuccessfulBuildTime() %></td>
+ <td class="data"><%= info[i].getLabel()%></td>
+
+ <% if (jmxEnabled) { %>
+ <td class="data"><input id="<%= "force_" + info[i].project %>" type="button"
+ onclick="callServer('<%= jmxURLPrefix.toExternalForm() + info[i].project %>', '<%=info[i].project%>')"
+ class="button" value="Build"/></td>
+ <% } %>
+ </tr>
+
+ </tbody>
+ <%
+ }
+ }
+ }
+ }
+ %></table>
+
+
+ </td></tr>
+ <tr>
+ <td bgcolor="#FFFFFF"><img border="0" src="images/bluestripesbottom.gif"/></td>
+ <td align="right" bgcolor="#FFFFFF"><img border="0" src="images/bluestripesbottomright.gif"/></td>
+ </tr>
+ <tr><td colspan="2">&nbsp;</td></tr>
+
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="2" align="right"><a href="rss"><img border="0" src="images/rss.png"/></a></td>
+ </tr>
+ </tfoot>
+ </table>
+</form>
+</div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
+
10 data/js/shBrushPhp.js
@@ -0,0 +1,10 @@
+/*
+ * JsMin
+ * Javascript Compressor
+ * http://www.crockford.com/
+ * http://www.smallsharptools.com/
+*/
+
+dp.sh.Brushes.Php=function()
+{var funcs='abs acos acosh addcslashes addslashes '+'array_change_key_case array_chunk array_combine array_count_values array_diff '+'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+'array_push array_rand array_reduce array_reverse array_search array_shift '+'array_slice array_splice array_sum array_udiff array_udiff_assoc '+'array_udiff_uassoc array_uintersect array_uintersect_assoc '+'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+'parse_ini_file parse_str parse_url passthru pathinfo readlink realpath rewind rewinddir rmdir '+'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+'strtoupper strtr strval substr substr_compare';var keywords='and or xor __FILE__ __LINE__ array as break case '+'cfunction class const continue declare default die do else '+'elseif empty enddeclare endfor endforeach endif endswitch endwhile '+'extends for foreach function include include_once global if '+'new old_function return static switch use require require_once '+'var while __FUNCTION__ __CLASS__ '+'__METHOD__ abstract interface public implements extends private protected throw';this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:'comment'},{regex:dp.sh.RegexLib.MultiLineCComments,css:'comment'},{regex:dp.sh.RegexLib.DoubleQuotedString,css:'string'},{regex:dp.sh.RegexLib.SingleQuotedString,css:'string'},{regex:new RegExp('\\$\\w+','g'),css:'vars'},{regex:new RegExp(this.GetKeywords(funcs),'gmi'),css:'func'},{regex:new RegExp(this.GetKeywords(keywords),'gm'),css:'keyword'}];this.CssClass='dp-c';}
+dp.sh.Brushes.Php.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Php.Aliases=['php'];
161 data/js/shCore.js
@@ -0,0 +1,161 @@
+/*
+ * JsMin
+ * Javascript Compressor
+ * http://www.crockford.com/
+ * http://www.smallsharptools.com/
+*/
+
+var dp={sh:{Toolbar:{},Utils:{},RegexLib:{},Brushes:{},Strings:{AboutDialog:'<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/syntaxhighlighter</a></p>&copy;2004-2007 Alex Gorbatchev.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>'},ClipboardSwf:null,Version:'1.5.1'}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:'+ expand source',check:function(highlighter){return highlighter.collapse;},func:function(sender,highlighter)
+{sender.parentNode.removeChild(sender);highlighter.div.className=highlighter.div.className.replace('collapsed','');}},ViewSource:{label:'view plain',func:function(sender,highlighter)
+{var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/</g,'&lt;');var wnd=window.open('','_blank','width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0');wnd.document.write('<textarea style="width:99%;height:99%">'+code+'</textarea>');wnd.document.close();}},CopyToClipboard:{label:'copy to clipboard',check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null;},func:function(sender,highlighter)
+{var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');if(window.clipboardData)
+{window.clipboardData.setData('text',code);}
+else if(dp.sh.ClipboardSwf!=null)
+{var flashcopier=highlighter.flashCopier;if(flashcopier==null)
+{flashcopier=document.createElement('div');highlighter.flashCopier=flashcopier;highlighter.div.appendChild(flashcopier);}
+flashcopier.innerHTML='<embed src="'+dp.sh.ClipboardSwf+'" FlashVars="clipboard='+encodeURIComponent(code)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';}
+alert('The code is in your clipboard now');}},PrintSource:{label:'print',func:function(sender,highlighter)
+{var iframe=document.createElement('IFRAME');var doc=null;iframe.style.cssText='position:absolute;width:0px;height:0px;left:-500px;top:-500px;';document.body.appendChild(iframe);doc=iframe.contentWindow.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write('<div class="'+highlighter.div.className.replace('collapsed','')+' printing">'+highlighter.div.innerHTML+'</div>');doc.close();iframe.contentWindow.focus();iframe.contentWindow.print();alert('Printing...');document.body.removeChild(iframe);}},About:{label:'?',func:function(highlighter)
+{var wnd=window.open('','_blank','dialog,width=300,height=150,scrollbars=0');var doc=wnd.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write(dp.sh.Strings.AboutDialog.replace('{V}',dp.sh.Version));doc.close();wnd.focus();}}};dp.sh.Toolbar.Create=function(highlighter)
+{var div=document.createElement('DIV');div.className='tools';for(var name in dp.sh.Toolbar.Commands)
+{var cmd=dp.sh.Toolbar.Commands[name];if(cmd.check!=null&&!cmd.check(highlighter))
+continue;div.innerHTML+='<a href="#" onclick="dp.sh.Toolbar.Command(\''+name+'\',this);return false;">'+cmd.label+'</a>';}
+return div;}
+dp.sh.Toolbar.Command=function(name,sender)
+{var n=sender;while(n!=null&&n.className.indexOf('dp-highlighter')==-1)
+n=n.parentNode;if(n!=null)
+dp.sh.Toolbar.Commands[name].func(sender,n.highlighter);}
+dp.sh.Utils.CopyStyles=function(destDoc,sourceDoc)
+{var links=sourceDoc.getElementsByTagName('link');for(var i=0;i<links.length;i++)
+if(links[i].rel.toLowerCase()=='stylesheet')
+destDoc.write('<link type="text/css" rel="stylesheet" href="'+links[i].href+'"></link>');}
+dp.sh.Utils.FixForBlogger=function(str)
+{return(dp.sh.isBloggerMode==true)?str.replace(/<br\s*\/?>|&lt;br\s*\/?&gt;/gi,'\n'):str;}
+dp.sh.RegexLib={MultiLineCComments:new RegExp('/\\*[\\s\\S]*?\\*/','gm'),SingleLineCComments:new RegExp('//.*$','gm'),SingleLinePerlComments:new RegExp('#.*$','gm'),DoubleQuotedString:new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g'),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'",'g')};dp.sh.Match=function(value,index,css)
+{this.value=value;this.index=index;this.length=value.length;this.css=css;}
+dp.sh.Highlighter=function()
+{this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true;}
+dp.sh.Highlighter.SortCallback=function(m1,m2)
+{if(m1.index<m2.index)
+return-1;else if(m1.index>m2.index)
+return 1;else
+{if(m1.length<m2.length)
+return-1;else if(m1.length>m2.length)
+return 1;}
+return 0;}
+dp.sh.Highlighter.prototype.CreateElement=function(name)
+{var result=document.createElement(name);result.highlighter=this;return result;}
+dp.sh.Highlighter.prototype.GetMatches=function(regex,css)
+{var index=0;var match=null;while((match=regex.exec(this.code))!=null)
+this.matches[this.matches.length]=new dp.sh.Match(match[0],match.index,css);}
+dp.sh.Highlighter.prototype.AddBit=function(str,css)
+{if(str==null||str.length==0)
+return;var span=this.CreateElement('SPAN');str=str.replace(/ /g,'&nbsp;');str=str.replace(/</g,'&lt;');str=str.replace(/\n/gm,'&nbsp;<br>');if(css!=null)
+{if((/br/gi).test(str))
+{var lines=str.split('&nbsp;<br>');for(var i=0;i<lines.length;i++)
+{span=this.CreateElement('SPAN');span.className=css;span.innerHTML=lines[i];this.div.appendChild(span);if(i+1<lines.length)
+this.div.appendChild(this.CreateElement('BR'));}}
+else
+{span.className=css;span.innerHTML=str;this.div.appendChild(span);}}
+else
+{span.innerHTML=str;this.div.appendChild(span);}}
+dp.sh.Highlighter.prototype.IsInside=function(match)
+{if(match==null||match.length==0)
+return false;for(var i=0;i<this.matches.length;i++)
+{var c=this.matches[i];if(c==null)
+continue;if((match.index>c.index)&&(match.index<c.index+c.length))
+return true;}
+return false;}
+dp.sh.Highlighter.prototype.ProcessRegexList=function()
+{for(var i=0;i<this.regexList.length;i++)
+this.GetMatches(this.regexList[i].regex,this.regexList[i].css);}
+dp.sh.Highlighter.prototype.ProcessSmartTabs=function(code)
+{var lines=code.split('\n');var result='';var tabSize=4;var tab='\t';function InsertSpaces(line,pos,count)
+{var left=line.substr(0,pos);var right=line.substr(pos+1,line.length);var spaces='';for(var i=0;i<count;i++)
+spaces+=' ';return left+spaces+right;}
+function ProcessLine(line,tabSize)
+{if(line.indexOf(tab)==-1)
+return line;var pos=0;while((pos=line.indexOf(tab))!=-1)
+{var spaces=tabSize-pos%tabSize;line=InsertSpaces(line,pos,spaces);}
+return line;}
+for(var i=0;i<lines.length;i++)
+result+=ProcessLine(lines[i],tabSize)+'\n';return result;}
+dp.sh.Highlighter.prototype.SwitchToList=function()
+{var html=this.div.innerHTML.replace(/<(br)\/?>/gi,'\n');var lines=html.split('\n');if(this.addControls==true)
+this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns)
+{var div=this.CreateElement('div');var columns=this.CreateElement('div');var showEvery=10;var i=1;while(i<=150)
+{if(i%showEvery==0)
+{div.innerHTML+=i;i+=(i+'').length;}
+else
+{div.innerHTML+='&middot;';i++;}}
+columns.className='columns';columns.appendChild(div);this.bar.appendChild(columns);}
+for(var i=0,lineIndex=this.firstLine;i<lines.length-1;i++,lineIndex++)
+{var li=this.CreateElement('LI');var span=this.CreateElement('SPAN');li.className=(i%2==0)?'alt':'';span.innerHTML=lines[i]+'&nbsp;';li.appendChild(span);this.ol.appendChild(li);}
+this.div.innerHTML='';}
+dp.sh.Highlighter.prototype.Highlight=function(code)
+{function Trim(str)
+{return str.replace(/^\s*(.*?)[\s\n]*$/g,'$1');}
+function Chop(str)
+{return str.replace(/\n*$/,'').replace(/^\n*/,'');}
+function Unindent(str)
+{var lines=dp.sh.Utils.FixForBlogger(str).split('\n');var indents=new Array();var regex=new RegExp('^\\s*','g');var min=1000;for(var i=0;i<lines.length&&min>0;i++)
+{if(Trim(lines[i]).length==0)
+continue;var matches=regex.exec(lines[i]);if(matches!=null&&matches.length>0)
+min=Math.min(matches[0].length,min);}
+if(min>0)
+for(var i=0;i<lines.length;i++)
+lines[i]=lines[i].substr(min);return lines.join('\n');}
+function Copy(string,pos1,pos2)
+{return string.substr(pos1,pos2-pos1);}
+var pos=0;if(code==null)
+code='';this.originalCode=code;this.code=Chop(Unindent(code));this.div=this.CreateElement('DIV');this.bar=this.CreateElement('DIV');this.ol=this.CreateElement('OL');this.matches=new Array();this.div.className='dp-highlighter';this.div.highlighter=this;this.bar.className='bar';this.ol.start=this.firstLine;if(this.CssClass!=null)
+this.ol.className=this.CssClass;if(this.collapse)
+this.div.className+=' collapsed';if(this.noGutter)
+this.div.className+=' nogutter';if(this.tabsToSpaces==true)
+this.code=this.ProcessSmartTabs(this.code);this.ProcessRegexList();if(this.matches.length==0)
+{this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);return;}
+this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var i=0;i<this.matches.length;i++)
+if(this.IsInside(this.matches[i]))
+this.matches[i]=null;for(var i=0;i<this.matches.length;i++)
+{var match=this.matches[i];if(match==null||match.length==0)
+continue;this.AddBit(Copy(this.code,pos,match.index),null);this.AddBit(match.value,match.css);pos=match.index+match.length;}
+this.AddBit(this.code.substr(pos),null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);}
+dp.sh.Highlighter.prototype.GetKeywords=function(str)
+{return'\\b'+str.replace(/ /g,'\\b|\\b')+'\\b';}
+dp.sh.BloggerMode=function()
+{dp.sh.isBloggerMode=true;}
+dp.sh.HighlightAll=function(name,showGutter,showControls,collapseAll,firstLine,showColumns)
+{function FindValue()
+{var a=arguments;for(var i=0;i<a.length;i++)
+{if(a[i]==null)
+continue;if(typeof(a[i])=='string'&&a[i]!='')
+return a[i]+'';if(typeof(a[i])=='object'&&a[i].value!='')
+return a[i].value+'';}
+return null;}
+function IsOptionSet(value,list)
+{for(var i=0;i<list.length;i++)
+if(list[i]==value)
+return true;return false;}
+function GetOptionValue(name,list,defaultValue)
+{var regex=new RegExp('^'+name+'\\[(\\w+)\\]$','gi');var matches=null;for(var i=0;i<list.length;i++)
+if((matches=regex.exec(list[i]))!=null)
+return matches[1];return defaultValue;}
+function FindTagsByName(list,name,tagName)
+{var tags=document.getElementsByTagName(tagName);for(var i=0;i<tags.length;i++)
+if(tags[i].getAttribute('name')==name)
+list.push(tags[i]);}
+var elements=[];var highlighter=null;var registered={};var propertyName='innerHTML';FindTagsByName(elements,name,'pre');FindTagsByName(elements,name,'textarea');if(elements.length==0)
+return;for(var brush in dp.sh.Brushes)
+{var aliases=dp.sh.Brushes[brush].Aliases;if(aliases==null)
+continue;for(var i=0;i<aliases.length;i++)
+registered[aliases[i]]=brush;}
+for(var i=0;i<elements.length;i++)
+{var element=elements[i];var options=FindValue(element.attributes['class'],element.className,element.attributes['language'],element.language);var language='';if(options==null)
+continue;options=options.split(':');language=options[0].toLowerCase();if(registered[language]==null)
+continue;highlighter=new dp.sh.Brushes[registered[language]]();element.style.display='none';highlighter.noGutter=(showGutter==null)?IsOptionSet('nogutter',options):!showGutter;highlighter.addControls=(showControls==null)?!IsOptionSet('nocontrols',options):showControls;highlighter.collapse=(collapseAll==null)?IsOptionSet('collapse',options):collapseAll;highlighter.showColumns=(showColumns==null)?IsOptionSet('showcolumns',options):showColumns;var headNode=document.getElementsByTagName('head')[0];if(highlighter.Style&&headNode)
+{var styleNode=document.createElement('style');styleNode.setAttribute('type','text/css');if(styleNode.styleSheet)
+{styleNode.styleSheet.cssText=highlighter.Style;}
+else
+{var textNode=document.createTextNode(highlighter.Style);styleNode.appendChild(textNode);}
+headNode.appendChild(styleNode);}
+highlighter.firstLine=(firstLine==null)?parseInt(GetOptionValue('firstline',options,1)):firstLine;highlighter.Highlight(element[propertyName]);highlighter.source=element;element.parentNode.insertBefore(highlighter.div,element);}}
105 data/main.jsp
@@ -0,0 +1,105 @@
+<%--********************************************************************************
+ * CruiseControl, a Continuous Integration Toolkit
+ * Copyright (c) 2001, ThoughtWorks, Inc.
+ * 200 E. Randolph, 25th Floor
+ * Chicago, IL 60601 USA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * + Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * + Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************--%>
+<%@page contentType="text/html; charset=utf-8"%>
+<%@page errorPage="/error.jsp"%>
+<%@ taglib uri="/WEB-INF/cruisecontrol-jsp11.tld" prefix="cruisecontrol"%>
+<%
+ String rmiPort = System.getProperty("cruisecontrol.rmiport");
+ boolean rmiEnabled = rmiPort != null;
+
+ String ccname = System.getProperty("ccname", "");
+ String project = request.getPathInfo().substring(1);
+%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+ <head>
+ <title><%= ccname%> phpUnderControl - SVN - Build Results</title>
+ <base href="<%=request.getScheme()%>://<%=request.getServerName()%>:<%=request.getServerPort()%><%=request.getContextPath()%>/" />
+ <link type="text/css" rel="stylesheet" href="css/SyntaxHighlighter.css"/>
+ <link type="text/css" rel="stylesheet" href="css/php-under-control.css"/>
+ <link type="application/rss+xml" rel="alternate" href="<%= request.getContextPath() %>/rss/<%= project %>" title="RSS"/>
+ </head>
+ <body>
+ <div id="container">
+ <%@ include file="header.jsp" %>
+ <cruisecontrol:tabsheet>
+ <tr>
+ <td>
+ <cruisecontrol:tab name="buildResults" label="Overview" >
+ <%@ include file="buildresults.jsp" %>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:tab name="testResults" label="Tests" >
+ <%@ include file="phpunit.jsp" %>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:loglink id="logs_url"/>
+ <cruisecontrol:tab name="log" url="<%=logs_url%>" label="XML Log File" />
+
+ <cruisecontrol:tab name="metrics" label="Metrics" >
+ <%@ include file="metrics.jsp" %>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:tab name="coverage" label="Coverage">
+ <cruisecontrol:artifactsLink>
+ <iframe src="<%= artifacts_url %>/coverage/index.html" width="100%" height="550" frameborder="0" />
+ </iframe>
+ </cruisecontrol:artifactsLink>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:tab name="documentation" label="Documentation">
+ <cruisecontrol:artifactsLink>
+ <iframe src="<%= artifacts_url %>/api/index.html" width="100%" height="550" frameborder="0" />
+ </iframe>
+ </cruisecontrol:artifactsLink>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:tab name="phpcs" label="CodeSniffer">
+ <%@ include file="phpcs.jsp" %>
+ </cruisecontrol:tab>
+
+ <cruisecontrol:tab name="pmd" label="PHPUnit PMD">
+ <%@ include file="phpunit-pmd.jsp" %>
+ </cruisecontrol:tab>
+ </td>
+ </tr>
+ </cruisecontrol:tabsheet>
+ </div>
+ <%@ include file="footer.jsp" %>
+ </body>
+</html>
128 data/metrics.cewolf.jsp
@@ -0,0 +1,128 @@
+<%--********************************************************************************
+ * This file is part of phpUnderControl.
+ *
+ * Copyright (c) 2007-2008, Manuel Pichler <mapi@phpundercontrol.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Manuel Pichler nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************--%>
+<%@ page language="java" pageEncoding="UTF-8"%>
+<%@ taglib uri="/WEB-INF/lib/cewolf.jar" prefix="cewolf" %>
+<%--
+Displays the number of broken and successful builds
+--%>
+<jsp:useBean id="pieData" class="net.sourceforge.cruisecontrol.chart.PieChartData" />
+<cewolf:chart id="pie" title="Breakdown of build types" type="pie" >
+ <cewolf:data>
+ <cewolf:producer id="pieData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+</cewolf:chart>
+<cewolf:img chartid="pie" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
+
+
+<jsp:useBean id="chartData" class="net.sourceforge.cruisecontrol.chart.TimeChartData" />
+<cewolf:chart id="chart" title="Breakdown of build types" type="timeseries" xaxislabel="date" yaxislabel="time">
+ <cewolf:data>
+ <cewolf:producer id="chartData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+ <cewolf:chartpostprocessor id="chartData" />
+</cewolf:chart>
+<cewolf:img chartid="chart" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
+
+
+<jsp:useBean id="coverageData" class="net.sourceforge.cruisecontrol.chart.XPathChartData" />
+<%
+ coverageData.add("Lines of code", "sum(/cruisecontrol/coverage/project/file/metrics/@loc)");
+ coverageData.add("Non comment lines", "sum(/cruisecontrol/coverage/project/file/metrics/@ncloc)");
+ coverageData.add("Executable lines", "count(/cruisecontrol/coverage/project/file/line)");
+ coverageData.add("Covered lines", "count(/cruisecontrol/coverage/project/file/line[@count != 0])");
+%>
+<cewolf:chart id="coverageChart" title="Unit coverage" type="timeseries" xaxislabel="date" yaxislabel="lines">
+ <cewolf:data>
+ <cewolf:producer id="coverageData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+ <cewolf:chartpostprocessor id="coverageData" />
+</cewolf:chart>
+<cewolf:img chartid="coverageChart" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
+
+<jsp:useBean id="unitTestData" class="net.sourceforge.cruisecontrol.chart.XPathChartData" />
+<%
+ unitTestData.add("Total", "count(/cruisecontrol/testsuites//testcase)");
+ unitTestData.add("Failures", "count(/cruisecontrol/testsuites//testcase[failure])");
+%>
+<cewolf:chart id="unitTestChart" title="Unit Tests" type="timeseries" xaxislabel="date" yaxislabel="tests">
+ <cewolf:data>
+ <cewolf:producer id="unitTestData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+ <cewolf:chartpostprocessor id="unitTestData" />
+</cewolf:chart>
+<cewolf:img chartid="unitTestChart" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
+
+
+<jsp:useBean id="numData" class="net.sourceforge.cruisecontrol.chart.XPathChartData" />
+<%
+ numData.add("Classes", "count(/cruisecontrol/coverage/project/file/class)");
+ numData.add("Test Classes", "count(/cruisecontrol/testsuites//testsuite[testcase])");
+ numData.add("Methods", "count(/cruisecontrol/coverage/project/file/line[@type='method'])");
+ numData.add("Test Methods", "count(/cruisecontrol/testsuites//testsuite/testcase)");
+%>
+<cewolf:chart id="numChart" title="Test - Code ratio" type="timeseries" xaxislabel="date" yaxislabel="classes / methods">
+ <cewolf:data>
+ <cewolf:producer id="numData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+ <cewolf:chartpostprocessor id="numData" />
+</cewolf:chart>
+<cewolf:img chartid="numChart" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
+
+<jsp:useBean id="xpathData" class="net.sourceforge.cruisecontrol.chart.XPathChartData" />
+<%
+ xpathData.add("PHP CodeSniffer", "count(/cruisecontrol/checkstyle/file/error)");
+ xpathData.add("PHPUnit PMD", "count(/cruisecontrol/pmd/file/violation)");
+ xpathData.add("PHPdoc", "count(/cruisecontrol/build//target[@name='php-documentor']/task[@name='exec']/message[contains(text(), 'WARNING in') or contains(text(), 'WARNING:') or contains(text(), 'ERROR in') or contains(text(), 'ERROR:')])");
+%>
+<cewolf:chart id="chart" title="Coding violations" type="timeseries" xaxislabel="date" yaxislabel="violations">
+ <cewolf:data>
+ <cewolf:producer id="xpathData">
+ <cewolf:param name="buildInfo" value="<%=build_info%>" />
+ </cewolf:producer>
+ </cewolf:data>
+ <cewolf:chartpostprocessor id="xpathData" />
+</cewolf:chart>
+<cewolf:img chartid="chart" renderer="cewolf" width="450" height="280" style="display:inline;margin:0 15px 15px 15px;"/>
93 data/metrics.jsp
@@ -0,0 +1,93 @@
+<%--********************************************************************************
+ * This file is part of phpUnderControl.