| <?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; |
| } |