blob: 59c8e554a12ee1d75a4c33f5c98a7d403e1548c9 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2011 Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wayne Beaton - initial API and implementation
*******************************************************************************/
/**
* This file provides a listing of the output generated by the download
* directory scan tool. For a given project, it lists all the third-party
* JAR files found, along with their location, and corresponding CQ (if
* available). If a CQ cannot be determined for a potential third-party
* library, the entry is highlighted.
*
* The input for this script is provided by dashboard/downloads/scan_all.php;
* this script is currently run on the build server every Friday. See comments
* on scan_all.php.
*/
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/common.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/debug.php");
trace_file_info(__FILE__);
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php");
$App = new App();
$Nav = new Nav();
$Menu = new Menu();
if ($App->devmode) {
$base = $_SERVER['DOCUMENT_ROOT'] . '/projects/tests/data/ip-scans';
} else {
$base = '/home/data/httpd/writable/projects/ip-scans/';
mustBeCommitter();
include($App->getProjectCommon());
}
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/util/summary.php");
function getProjectScans() {
global $base;
global $projectNamePattern;
$scans = array();
if (!$dh = opendir($base)) return $scans;
while (($file = readdir($dh)) !== false) {
if (preg_match("/^($projectNamePattern).xml$/", $file, $matches)) {
$scans[$matches[1]] = $file;
}
}
closedir($dh);
ksort($scans);
return $scans;
}
function generateReport($id) {
global $base;
if (!$id) return null;
$file = "$base/$id.xml";
if (!file_exists($file)) {
echo "<p>Cannot find the data file. Please try again later.
If this problem persists, please contact
<a href=\"mailto:emo@eclipse.org\">EMO</a>.</p>";
return;
}
$scan = simplexml_load_file($file);
if (!$scan) {
echo "<p>We experienced a problem while attempting
to parse the data file. Please try again later.
If this problem persists, please contact
<a href=\"mailto:emo@eclipse.org\">EMO</a>.</p>";
return;
}
$date = date("Y-m-d h:m", filemtime($file));
echo "<p>This report is based on information extracted on $date.</p>";
echo "<p>This report is intended for use by Eclipse committers only;
it is not intended for use by the general public.</p>";
echo "<p>Note that this scan report is intended to assist Eclipse projects
to identify potential errors in IP tracking. The scan tools does
its best to identify Java JAR files and categorize them as either
artefacts developed by the project or third-party libraries. The
matching algorithm is not perfect as there is much variability in
how JAR files are packaged and distributed. Many of the \"hits\"
displayed on this page may be bogus. It may also fail to identify
whether or not, for example, a \"piggyback\" is required.
Ultimately, Eclipse committers are responsible for ensuring that
intellectual property is appropriately tracked. This tool is
intended to assist in that tracking; it is not a replacement
for the due diligence.</p>";
if (!$scan->project) {
echo "<p>Nothing to report; no files found in project downloads.</p>";
return;
}
foreach ($scan->project as $project) {
$projectId = $project['id'];
echo "<h3>$projectId</h3>";
dumpIncludes($project);
dumpBundles($project);
dumpMissing($project);
}
}
function dumpIncludes($project) {
echo "<h4>Eclipse Projects</h4>";
$ids = array();
foreach($project->includes as $include) {
$ids[] = (string)$include['id'];
}
if (!$ids) {
echo "<p>No bundles from other Eclipse projects were found.</p>";
return;
}
echo "<p>Bundles from the following Eclipse projects were found amoung your project
downloads. Use this information to confirm your understanding of what is being
distributed by your project. Please report any errors you find to
<a href=\"mailto:emo@eclipse.org\">EMO</a>.</p>";
echo "<div style=\"margin-left:25px\">";
echo "<ul>";
sort($ids);
foreach($ids as $id) {
echo "<li>$id</li>";
}
echo "</ul>";
echo "</div>";
}
function dumpBundles($project) {
echo "<h4>Third-party Bundles</h4>";
$bundles = array();
$test = array();
foreach ($project->bundle as $bundle) {
if (isPossibleTestBundle($bundle)) {
$test[(string)$bundle['name']] = $bundle;
} else {
$bundles[(string)$bundle['name']] = $bundle;
}
}
echo "<p>The following potential third-party libraries were found in the project
downloads. There may be some incorrectly identified JAR files/bundles in this
list (especially those that do not follow bundle versioning conventions).</p>";
echo "<p>We cannot find the corresponding CQ for those bundles displayed in red.
This does not necessarily mean that there is no CQ, only that we cannot determine
the relationship. Please report any errors you find to
<a href=\"mailto:emo@eclipse.org\">EMO</a>.</p>";
echo "<p>Click on the JAR/bundle name to toggle a listing of file paths showing
where this file is found.</p>";
dumpBundleList($bundles);
if ($test) {
echo "<p>The following libraries may be test bundles. We have grouped them here
for convenience.</p>";
dumpBundleList($test);
}
}
/**
* Answers true if the bundle might possibly be a test JAR, or false otherwise.
*
* A bundle is considered a test JAR if we cannot identify a CQ, and
* <b>all</b> of the paths contain the word 'test'.
*
* @param unknown_type $bundle
* @return boolean
*/
function isPossibleTestBundle(&$bundle) {
if ($bundle->cq) return false;
foreach($bundle->location as $location) {
$path = $location['path'];
if (!preg_match('/test/', $path)) return false;
}
return true;
}
function dumpBundleList(&$bundles) {
if (!$bundles) {
echo "<p>No bundles found.</p>";
return;
}
ksort($bundles);
echo "<div style=\"margin-left:25px\">";
foreach($bundles as $bundle) {
dumpBundle($bundle);
}
echo "</div>";
}
function dumpBundle($bundle) {
$name = $bundle['name'];
if ($cq = $bundle->cq) {
$id = $cq['id'];
$name = "$name (<a href=\"https://dev.eclipse.org/ipzilla/show_bug.cgi?id=$id\" target=\"cq\">CQ $id</a>)";
} else {
$name = "<span style=\"color:red;font-weight:bold\">$name (No CQ found)</span>";
}
echo "<div class=\"slideup_toggle\">";
echo "<p>$name</p>";
echo "<div class=\"slideup\">";
echo "<ul>";
foreach($bundle->location as $location) {
$path = $location['path'];
echo "<li>$path</li>";
}
echo "</ul>";
echo "</div>";
echo "</div>";
}
function dumpMissing($project) {
echo "<h4>Summary of Missing CQs</h4>";
$bundles = array();
foreach ($project->bundle as $bundle) {
if ($bundle->cq) continue;
$bundles[(string)$bundle['name']] = $bundle;
}
if (!$bundles) {
echo "<p>No missing CQs found.</p>";
return;
}
echo "<div style=\"margin-left:25px\">";
ksort($bundles);
foreach($bundles as $bundle) {
dumpBundle($bundle);
}
echo "</div>";
}
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/Project.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/CQ.class.php");
$scans = getProjectScans();
$id = $App->getHttpParameter('id');
if (!isset($scans[$id])) $id = null;
ob_start();
$pageKeywords = "";
$pageTitle = "Project Downloads";
$pageAuthor = "Wayne Beaton";
?>
<div id="midcolumn">
<h1><?= $pageTitle ?></h1>
<div class="homeitem">
<p>This tool shows the results from automated scans of Eclipse project
directories.</p>
<form method="get">
<?php
foreach ($_GET as $key => $value) {
if ($key == 'id') continue;
echo "<input type=\"hidden\" name=\"$key\" value=\"$value\"";
}
?>
<p>Select a project:
<select name="id">
<?php
foreach($scans as $project => $file) {
$selected = $id == $project ? ' selected="true"' : '';
echo "<option value=\"$project\"$selected>$project</option>";
}
?>
</select>
<input type="submit" value="Go!"/>
</p>
</form>
<p>The mapping of project to download directory that we use to
discover this information can be found
<a href="downloads_source.php">here</a>.</p>
<?php echo generateReport($id); ?>
</div>
</div>
<?php
$html = ob_get_contents();
ob_end_clean();
$App->generatePage($theme, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html);
echo get_trace_html();
?>