blob: 0d51ef6096bdc8ee17e1889698b7df3deb6a9fac [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2016, 2018 Eclipse Foundation and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
require_once dirname(__FILE__) . '/../classes/database.inc';
require_once dirname(__FILE__) . '/../classes/common.php';
require_once dirname(__FILE__) . '/../classes/debug.php';
require_once dirname(__FILE__) . '/../classes/Project.class.php';
$width = isset($_GET['width']) ? max((int)$_GET['width'],40) : 80;
$textRenderer = isset($_GET['asciidoc']) ? new AsciiDocRenderer($width) : new PlainTextRender($width);
function getDefaultFileHeader($licenses) {
global $width;
return renderAsHeaderComment(License::getDefaultFileHeader($licenses), $width);
}
function getAlternativeFileHeader($licenses) {
global $width;
return renderAsHeaderComment(License::getAlternativeFileHeader($licenses), $width);
}
function renderNoticeFile($id) {
global $textRenderer;
generateNoticeFileContent($id, $textRenderer);
}
function generateNoticeFileContent($id, $render) {
$project = Project::getProject($id);
$licenses = License::getLicensesForProject($project->getId());
$render
->title("Notices for " . $project->getFormalName())
->paragraph(
"This content is produced and maintained by the
{$project->getFormalName()} project.")
->unorderedList(array("Project home: {$project->getUrl()}"))
->section("Trademarks")
->paragraph(getTrademarksStatement($project))
->section("Copyright")
->paragraph("All content is the property of the respective authors "
."or their employers. For more information regarding authorship "
."of content, please consult the listed source code repository logs.")
->section("Declared Project Licenses")
->paragraph(valueOrDefaultWhenEmpty(License::getLicensesStatement($licenses), "[Provide license information here]"))
->paragraph("SPDX-License-Identifier: " . valueOrDefaultWhenEmpty(License::getSPDXExpression($licenses), "[Provide SPDX expression here]"))
->section("Source Code")
->paragraph("The project maintains the following source code repositories:")
->unorderedList($project->getSourceRepositories());
$render
->section("Cryptography")
->paragraph(
"Content may contain encryption software.
The country in which you are currently may have restrictions on
the import, possession, and use, and/or re-export to another country,
of encryption software. BEFORE using any encryption software, please
check the country's laws, regulations and policies concerning the import,
possession, or use, and re-export of encryption software, to see if
this is permitted.")
->end();
}
function getTrademarksStatement(Project $project) {
$unregistered = array();
$registered = array();
foreach($project->getTrademarks() as $each) {
switch ($each['type']) {
case 'T' : $unregistered[] = "{$each['name']}{$each['demarcation']}"; break;
case 'R' : $registered[] = "{$each['name']}{$each['demarcation']}"; break;
}
}
$trademarks = array();
if ($unregistered) {
$content = implodeWithConjunction($unregistered, 'and');
$content .= count($unregistered) == 1 ? ' is a trademark' : ' are trademarks';
$content .= ' of the Eclipse Foundation.';
$trademarks[] = $content;
}
if ($registered) {
$content = implodeWithConjunction($registered, 'and');
$content .= count($registered) == 1 ? ' is a registered trademark' : ' are registered trademarks';
$content .= ' of the Eclipse Foundation.';
$trademarks[] = $content;
}
if ($trademarks) {
return join(' ', $trademarks);
}
return "No trademarks.";
}
function renderContributingFile($id) {
global $textRenderer;
generateContributingFileContent($id, $textRenderer);
}
function generateContributingFileContent($id, $render) {
$project = Project::getProject($id);
$render
->title("Contributing to " . $project->getFormalName())
->paragraph("Thanks for your interest in this project.")
->section("Project description")
->paragraph($project->getDescription())
->unorderedList(array($project->getUrl()))
->section("Terms of Use")
->paragraph("This repository is subject to the Terms of Use of the Eclipse Foundation")
->unorderedList(array("https://www.eclipse.org/legal/termsofuse.php"))
->section("Developer resources")
->paragraph("Information regarding source code management, builds, coding standards, and more.")
->unorderedList(array($project->getUrl() . "/developer"))
->paragraph("The project maintains the following source code repositories")
->unorderedList($project->getSourceRepositories());
$links = array();
// @formatter:off
$render
->section("Eclipse Development Process")
->paragraph("This Eclipse Foundation open project is governed by the
Eclipse Foundation Development Process and operates under the terms
of the Eclipse IP Policy.");
$links[] = "https://eclipse.org/projects/dev_process";
$links[] = "https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf";
// @formatter:on
// We include a statement regarding contributions under the specification
// process when the project is involved in specification work. For now,
// we consider a project to be under the specification process if the
// project is a specification project. This should be more generally
// expanded to include projects that implement specifications. We don't
// track this in an easily queriable manner. Ideally, I believe, we should
// include projects that are of interest to a working group that implements
// a specification process. e.g. (in Java to be concise),
//
// project.getWorkingGroups().findAny(wg -> wg.hasSpecificationProjects())
//
if ($project->isSpecificationProject()) {
// FIXME Hack: hard coded content specific to Jakarta EE.
if (strcmp('Jakarta EE', $project->getSpecificationWorkingGroupName()) == 0) {
// @formatter:off
$render
->paragraph(
"The Jakarta EE Specification Committee has adopted the Jakarta EE
Specification Process (JESP) in accordance with the Eclipse Foundation
Specification Process v1.2 (EFSP) to ensure that the specification process
is complied with by all Jakarta EE specification projects.");
// @formatter:on
$links[] = "https://jakarta.ee/about/jesp/";
} else {
// @formatter:off
$render
->section("Specifications")
->paragraph(
"This specification project operates under the terms of the Eclipse Foundation
Specification process.");
// @formatter:on
$links[] = "https://www.eclipse.org/projects/efsp/";
}
$links[] = "https://www.eclipse.org/legal/efsp_non_assert.php";
}
$render->unorderedList($links);
$render
->section("Eclipse Contributor Agreement")
->paragraph(
"In order to be able to contribute to Eclipse Foundation projects
you must electronically sign the Eclipse Contributor Agreement (ECA).")
->unorderedList(array("https://www.eclipse.org/legal/ECA.php"))
->paragraph(
"The ECA provides the Eclipse Foundation with a permanent record
that you agree that each of your contributions will comply with
the commitments documented in the Developer Certificate of Origin (DCO).
Having an ECA on file associated with the email address matching the
\"Author\" field of your contribution's Git commits fulfils the
DCO's requirement that you sign-off on your contributions.")
->paragraph(
"For more information, please see the Eclipse Committer Handbook:
https://www.eclipse.org/projects/handbook/#resources-commit")
->section("Contact")
->paragraph("Contact the project developers via the project's \"dev\" list.")
->unorderedList(array($project->getDevListUrl()))
->end();
}
function renderSecurityFile($id) {
global $textRenderer;
generateSecurityFileContent($id, $textRenderer);
}
function generateSecurityFileContent($id, $render) {
$project = Project::getProject($id);
$rows = array();
$sql = "
select
name, date
from ProjectReleases
where project=':id:'
order by date desc
limit 3";
$args = array(":id:" => $id);
$max = 3;
query('dashboard',$sql, $args, function($row) use (&$rows, &$max) {
if ($max-- == 1) {
$row['name'] = "< {$row['name']}";
$row['supported'] = 'No';
} else {
$row['supported'] = 'Yes';
}
$rows[] = $row;
});
$render
->title("Security Policy")
->paragraph("This project implements the Eclipse Foundation Security Policy")
->unorderedList(array("https://www.eclipse.org/security"));
if ($rows) {
$render
->section("Supported Versions")
->paragraph("These versions of {$project->getName()} are currently being supported with security updates.")
->table(array("name" => "Version", "date" => "Released", "supported" => "Supported"), $rows);
}
$render
->section("Reporting a Vulnerability")
->paragraph("Please report vulnerabilities to the Eclipse Foundation Security Team at security@eclipse.org")
->end();
}
function getColumnWidths($header, $rows) {
$widths = array();
foreach($header as $key => $value) {
$values = array(mb_strlen($value));
foreach($rows as $row) $values[] = mb_strlen($row[$key]);
$widths[$key] = max($values);
}
return $widths;
}
/**
* A very simple class for rendering structured content
* in plaintext.
*/
class PlainTextRender {
var $width;
function __construct($width) {
$this->width = $width;
}
function title($text) {
$this->section($text, 1);
return $this;
}
function getHeaderCharacter() {
return "#";
}
function section($text, $level=2) {
for($index=0;$index<$level;$index++) echo $this->getHeaderCharacter();
echo " ";
echo $text;
echo "\n\n";
return $this;
}
function paragraph($text, $alternate = 'The project team should provide something interesting here.') {
echo wordwrap($this->normalize($text != null ? $text : $alternate), $this->width);
echo "\n\n";
return $this;
}
private function normalize($text) {
$text = trim(html_entity_decode(strip_tags($text)));
return preg_replace('/\s+/', ' ', $text);
}
function unorderedList($values, $each = 'doNothing') {
foreach($values as $value) {
if (!$value) continue;
echo "* ";
$lines = explode("\n",wordwrap(call_user_func($each, $value), $this->width-3));
echo implode("\n ", $lines);
echo "\n";
}
echo "\n";
return $this;
}
function table($header, $rows) {
$widths = getColumnWidths($header, $rows);
echo "| ";
foreach($header as $key=>$value) {
echo str_pad($value, $widths[$key]);
echo " | ";
}
echo "\n";
echo "| ";
foreach($header as $key=>$value) {
echo str_pad("", $widths[$key],"-");
echo " | ";
}
echo "\n";
foreach($rows as $row) {
echo "| ";
foreach($header as $key=>$value) {
echo mb_str_pad($row[$key], $widths[$key]);
echo " | ";
}
echo "\n";
}
echo "\n";
return $this;
}
function end() {}
}
class AsciiDocRenderer extends PlainTextRender {
/**
* {@inheritDoc}
* @see PlainTextRender::getHeaderCharacter()
*/
public function getHeaderCharacter() {
return "=";
}
function table($header, $rows) {
$columns = implode(',', array_fill(0, count($header), 1));
echo "[cols=\"{$columns}\"]\n";
echo "|===\n";
foreach($header as $key=>$value) {
echo "| ";
echo $value;
}
echo "\n\n";
foreach($rows as $row) {
foreach($header as $key=>$value) {
echo "| ";
echo $row[$key];
echo "\n";
}
echo "\n";
}
echo "|===\n\n";
return $this;
}
}
function doNothing($value) {
return $value;
}
function valueOrDefaultWhenEmpty($value, $default) {
return !empty($value) ? $value : $default;
}