updated spdx-license handling to include metadata
issue https://github.com/composer/composer/issues/3744 summary of changes - replaced bin script "fetch-spdx-identifiers" by "update-spdx-licenses" - "update-spdx-licenses" uses "Composer/Util/SpdxLicensesUpdater" to update "spdx-licenses.json" file with license identifier, fullname and osi-approved-status - dropped "spdx-identifiers.json" (identifiers only) - dropped "SpdxLicenseIdentifier", it's just "SpdxLicense" now - modified "ShowCommand" to output the license with metadata and removed some unused method arguments (cleanup)main
parent
f10c714751
commit
74a077dd3d
@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$identifiers = new SPDXLicenseIdentifiersOnline;
|
||||
$printer = new JsonPrinter;
|
||||
$printer->printStringArray($identifiers->getStrings());
|
||||
|
||||
/**
|
||||
* SPDX Identifier List from the registry.
|
||||
*/
|
||||
class SPDXLicenseIdentifiersOnline
|
||||
{
|
||||
const REGISTRY = 'http://www.spdx.org/licenses/';
|
||||
const EXPRESSION = '//*[@typeof="spdx:License"]/code[@property="spdx:licenseId"]/text()';
|
||||
|
||||
private $identifiers;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStrings()
|
||||
{
|
||||
if ($this->identifiers) {
|
||||
return $this->identifiers;
|
||||
}
|
||||
$this->identifiers = $this->importNodesFromURL(
|
||||
self::REGISTRY,
|
||||
self::EXPRESSION
|
||||
);
|
||||
|
||||
return $this->identifiers;
|
||||
}
|
||||
|
||||
private function importNodesFromURL($url, $expressionTextNodes)
|
||||
{
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTMLFile($url);
|
||||
$xp = new DOMXPath($doc);
|
||||
$codes = $xp->query($expressionTextNodes);
|
||||
if (!$codes) {
|
||||
throw new \Exception(sprintf('XPath query failed: %s', $expressionTextNodes));
|
||||
}
|
||||
if ($codes->length < 20) {
|
||||
throw new \Exception('Obtaining the license table failed, there can not be less than 20 identifiers.');
|
||||
}
|
||||
$identifiers = array();
|
||||
foreach ($codes as $code) {
|
||||
$identifiers[] = $code->nodeValue;
|
||||
}
|
||||
|
||||
return $identifiers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an array the way this script needs it.
|
||||
*/
|
||||
class JsonPrinter
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param array $array
|
||||
*/
|
||||
public function printStringArray(array $array)
|
||||
{
|
||||
$lines = array('');
|
||||
$line = &$lines[0];
|
||||
$last = count($array) - 1;
|
||||
foreach ($array as $item => $code) {
|
||||
$code = sprintf('"%s"%s', trim($code), $item === $last ? '' : ', ');
|
||||
$length = strlen($line) + strlen($code) - 1;
|
||||
if ($length > 76) {
|
||||
$line = rtrim($line);
|
||||
unset($line);
|
||||
$lines[] = $code;
|
||||
$line = &$lines[count($lines) - 1];
|
||||
} else {
|
||||
$line .= $code;
|
||||
}
|
||||
}
|
||||
$json = sprintf("[%s]", implode("\n ", $lines));
|
||||
$json = str_replace(array("[\"", "\"]"), array("[\n \"", "\"\n]"), $json);
|
||||
echo $json;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../src/bootstrap.php';
|
||||
|
||||
use Composer\Util\SpdxLicensesUpdater;
|
||||
|
||||
$licenses = new SpdxLicensesUpdater;
|
||||
$licenses->update();
|
@ -1,59 +0,0 @@
|
||||
[
|
||||
"Glide", "Abstyles", "AFL-1.1", "AFL-1.2", "AFL-2.0", "AFL-2.1", "AFL-3.0",
|
||||
"AMPAS", "APL-1.0", "Adobe-Glyph", "APAFML", "Adobe-2006", "AGPL-1.0",
|
||||
"Afmparse", "Aladdin", "ADSL", "AMDPLPA", "ANTLR-PD", "Apache-1.0",
|
||||
"Apache-1.1", "Apache-2.0", "AML", "APSL-1.0", "APSL-1.1", "APSL-1.2",
|
||||
"APSL-2.0", "Artistic-1.0", "Artistic-1.0-Perl", "Artistic-1.0-cl8",
|
||||
"Artistic-2.0", "AAL", "Bahyph", "Barr", "Beerware", "BitTorrent-1.0",
|
||||
"BitTorrent-1.1", "BSL-1.0", "Borceux", "BSD-2-Clause",
|
||||
"BSD-2-Clause-FreeBSD", "BSD-2-Clause-NetBSD", "BSD-3-Clause",
|
||||
"BSD-3-Clause-Clear", "BSD-4-Clause", "BSD-Protection",
|
||||
"BSD-3-Clause-Attribution", "BSD-4-Clause-UC", "bzip2-1.0.5", "bzip2-1.0.6",
|
||||
"Caldera", "CECILL-1.0", "CECILL-1.1", "CECILL-2.0", "CECILL-B", "CECILL-C",
|
||||
"ClArtistic", "MIT-CMU", "CNRI-Python", "CNRI-Python-GPL-Compatible",
|
||||
"CPOL-1.02", "CDDL-1.0", "CDDL-1.1", "CPAL-1.0", "CPL-1.0", "CATOSL-1.1",
|
||||
"Condor-1.1", "CC-BY-1.0", "CC-BY-2.0", "CC-BY-2.5", "CC-BY-3.0",
|
||||
"CC-BY-4.0", "CC-BY-ND-1.0", "CC-BY-ND-2.0", "CC-BY-ND-2.5", "CC-BY-ND-3.0",
|
||||
"CC-BY-ND-4.0", "CC-BY-NC-1.0", "CC-BY-NC-2.0", "CC-BY-NC-2.5",
|
||||
"CC-BY-NC-3.0", "CC-BY-NC-4.0", "CC-BY-NC-ND-1.0", "CC-BY-NC-ND-2.0",
|
||||
"CC-BY-NC-ND-2.5", "CC-BY-NC-ND-3.0", "CC-BY-NC-ND-4.0", "CC-BY-NC-SA-1.0",
|
||||
"CC-BY-NC-SA-2.0", "CC-BY-NC-SA-2.5", "CC-BY-NC-SA-3.0", "CC-BY-NC-SA-4.0",
|
||||
"CC-BY-SA-1.0", "CC-BY-SA-2.0", "CC-BY-SA-2.5", "CC-BY-SA-3.0",
|
||||
"CC-BY-SA-4.0", "CC0-1.0", "Crossword", "CUA-OPL-1.0", "Cube", "D-FSL-1.0",
|
||||
"diffmark", "WTFPL", "DOC", "Dotseqn", "DSDP", "dvipdfm", "EPL-1.0",
|
||||
"eCos-2.0", "ECL-1.0", "ECL-2.0", "eGenix", "EFL-1.0", "EFL-2.0",
|
||||
"MIT-advertising", "MIT-enna", "Entessa", "ErlPL-1.1", "EUDatagrid",
|
||||
"EUPL-1.0", "EUPL-1.1", "Eurosym", "Fair", "MIT-feh", "Frameworx-1.0",
|
||||
"FTL", "FSFUL", "FSFULLR", "Giftware", "GL2PS", "Glulxe", "AGPL-3.0",
|
||||
"GFDL-1.1", "GFDL-1.2", "GFDL-1.3", "GPL-1.0", "GPL-1.0+", "GPL-2.0",
|
||||
"GPL-2.0+", "GPL-2.0-with-autoconf-exception",
|
||||
"GPL-2.0-with-bison-exception", "GPL-2.0-with-classpath-exception",
|
||||
"GPL-2.0-with-font-exception", "GPL-2.0-with-GCC-exception", "GPL-3.0",
|
||||
"GPL-3.0+", "GPL-3.0-with-autoconf-exception", "GPL-3.0-with-GCC-exception",
|
||||
"LGPL-2.1", "LGPL-2.1+", "LGPL-3.0", "LGPL-3.0+", "LGPL-2.0", "LGPL-2.0+",
|
||||
"gnuplot", "gSOAP-1.3b", "HaskellReport", "HPND", "IBM-pibs", "IPL-1.0",
|
||||
"ImageMagick", "iMatix", "Imlib2", "IJG", "Intel-ACPI", "Intel", "IPA",
|
||||
"ISC", "JasPer-2.0", "JSON", "LPPL-1.3a", "LPPL-1.0", "LPPL-1.1",
|
||||
"LPPL-1.2", "LPPL-1.3c", "Latex2e", "BSD-3-Clause-LBNL", "Leptonica",
|
||||
"Libpng", "libtiff", "LPL-1.02", "LPL-1.0", "MakeIndex", "MTLL", "MS-PL",
|
||||
"MS-RL", "MirOS", "MITNFA", "MIT", "Motosoto", "MPL-1.0", "MPL-1.1",
|
||||
"MPL-2.0", "MPL-2.0-no-copyleft-exception", "mpich2", "Multics", "Mup",
|
||||
"NASA-1.3", "Naumen", "NBPL-1.0", "NetCDF", "NGPL", "NOSL", "NPL-1.0",
|
||||
"NPL-1.1", "Newsletr", "NLPL", "Nokia", "NPOSL-3.0", "Noweb", "NRL", "NTP",
|
||||
"Nunit", "OCLC-2.0", "ODbL-1.0", "PDDL-1.0", "OGTSL", "OLDAP-2.2.2",
|
||||
"OLDAP-1.1", "OLDAP-1.2", "OLDAP-1.3", "OLDAP-1.4", "OLDAP-2.0",
|
||||
"OLDAP-2.0.1", "OLDAP-2.1", "OLDAP-2.2", "OLDAP-2.2.1", "OLDAP-2.3",
|
||||
"OLDAP-2.4", "OLDAP-2.5", "OLDAP-2.6", "OLDAP-2.7", "OML", "OPL-1.0",
|
||||
"OSL-1.0", "OSL-1.1", "OSL-2.0", "OSL-2.1", "OSL-3.0", "OLDAP-2.8",
|
||||
"OpenSSL", "PHP-3.0", "PHP-3.01", "Plexus", "PostgreSQL", "psfrag",
|
||||
"psutils", "Python-2.0", "QPL-1.0", "Qhull", "Rdisc", "RPSL-1.0", "RPL-1.1",
|
||||
"RPL-1.5", "RHeCos-1.1", "RSCPL", "Ruby", "SAX-PD", "Saxpath", "SCEA",
|
||||
"SWL", "SGI-B-1.0", "SGI-B-1.1", "SGI-B-2.0", "OFL-1.0", "OFL-1.1",
|
||||
"SimPL-2.0", "Sleepycat", "SNIA", "SMLNJ", "StandardML-NJ",
|
||||
"SugarCRM-1.1.3", "SISSL", "SISSL-1.2", "SPL-1.0", "Watcom-1.0", "TCL",
|
||||
"Unlicense", "TMate", "TORQUE-1.1", "TOSL", "Unicode-TOU", "NCSA", "Vim",
|
||||
"VOSTROM", "VSL-1.0", "W3C", "Wsuipa", "WXwindows", "Xnet", "X11", "Xerox",
|
||||
"XFree86-1.1", "xinetd", "xpp", "XSkat", "YPL-1.0", "YPL-1.1", "Zed",
|
||||
"Zend-2.0", "Zimbra-1.3", "Zlib", "zlib-acknowledgement", "ZPL-1.1",
|
||||
"ZPL-2.0", "ZPL-2.1"
|
||||
]
|
File diff suppressed because it is too large
Load Diff
@ -1,178 +1,229 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
use Composer\Json\JsonFile;
|
||||
|
||||
/**
|
||||
* Supports composer array and SPDX tag notation for disjunctive/conjunctive
|
||||
* licenses.
|
||||
*
|
||||
* @author Tom Klingenberg <tklingenberg@lastflood.net>
|
||||
*/
|
||||
class SpdxLicenseIdentifier
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $identifiers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->initIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $license
|
||||
*
|
||||
* @return bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function validate($license)
|
||||
{
|
||||
if (is_array($license)) {
|
||||
$count = count($license);
|
||||
if ($count !== count(array_filter($license, 'is_string'))) {
|
||||
throw new \InvalidArgumentException('Array of strings expected.');
|
||||
}
|
||||
$license = $count > 1 ? '('.implode(' or ', $license).')' : (string) reset($license);
|
||||
}
|
||||
if (!is_string($license)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Array or String expected, %s given.', gettype($license)
|
||||
));
|
||||
}
|
||||
|
||||
return $this->isValidLicenseString($license);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads SPDX identifiers
|
||||
*/
|
||||
private function initIdentifiers()
|
||||
{
|
||||
$jsonFile = new JsonFile(__DIR__ . '/../../../res/spdx-identifier.json');
|
||||
$this->identifiers = $jsonFile->read();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidLicenseIdentifier($identifier)
|
||||
{
|
||||
return in_array($identifier, $this->identifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $license
|
||||
*
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
private function isValidLicenseString($license)
|
||||
{
|
||||
$tokens = array(
|
||||
'po' => '\(',
|
||||
'pc' => '\)',
|
||||
'op' => '(?:or|and)',
|
||||
'lix' => '(?:NONE|NOASSERTION)',
|
||||
'lir' => 'LicenseRef-\d+',
|
||||
'lic' => '[-+_.a-zA-Z0-9]{3,}',
|
||||
'ws' => '\s+',
|
||||
'_' => '.',
|
||||
);
|
||||
|
||||
$next = function () use ($license, $tokens) {
|
||||
static $offset = 0;
|
||||
|
||||
if ($offset >= strlen($license)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($tokens as $name => $token) {
|
||||
if (false === $r = preg_match('{' . $token . '}', $license, $matches, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
throw new \RuntimeException('Pattern for token %s failed (regex error).', $name);
|
||||
}
|
||||
if ($r === 0) {
|
||||
continue;
|
||||
}
|
||||
if ($matches[0][1] !== $offset) {
|
||||
continue;
|
||||
}
|
||||
$offset += strlen($matches[0][0]);
|
||||
|
||||
return array($name, $matches[0][0]);
|
||||
}
|
||||
|
||||
throw new \RuntimeException('At least the last pattern needs to match, but it did not (dot-match-all is missing?).');
|
||||
};
|
||||
|
||||
$open = 0;
|
||||
$require = 1;
|
||||
$lastop = null;
|
||||
|
||||
while (list($token, $string) = $next()) {
|
||||
switch ($token) {
|
||||
case 'po':
|
||||
if ($open || !$require) {
|
||||
return false;
|
||||
}
|
||||
$open = 1;
|
||||
break;
|
||||
case 'pc':
|
||||
if ($open !== 1 || $require || !$lastop) {
|
||||
return false;
|
||||
}
|
||||
$open = 2;
|
||||
break;
|
||||
case 'op':
|
||||
if ($require || !$open) {
|
||||
return false;
|
||||
}
|
||||
$lastop || $lastop = $string;
|
||||
if ($lastop !== $string) {
|
||||
return false;
|
||||
}
|
||||
$require = 1;
|
||||
break;
|
||||
case 'lix':
|
||||
if ($open) {
|
||||
return false;
|
||||
}
|
||||
goto lir;
|
||||
case 'lic':
|
||||
if (!$this->isValidLicenseIdentifier($string)) {
|
||||
return false;
|
||||
}
|
||||
// Fall-through intended
|
||||
case 'lir':
|
||||
lir:
|
||||
if (!$require) {
|
||||
return false;
|
||||
}
|
||||
$require = 0;
|
||||
break;
|
||||
case 'ws':
|
||||
break;
|
||||
case '_':
|
||||
return false;
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Unparsed token: %s.', print_r($token, true)));
|
||||
}
|
||||
}
|
||||
|
||||
return !($open % 2 || $require);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
use Composer\Json\JsonFile;
|
||||
|
||||
/**
|
||||
* Supports composer array and SPDX tag notation for disjunctive/conjunctive
|
||||
* licenses.
|
||||
*
|
||||
* @author Tom Klingenberg <tklingenberg@lastflood.net>
|
||||
*/
|
||||
class SpdxLicense
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $licenses;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->loadLicenses();
|
||||
}
|
||||
|
||||
private function loadLicenses()
|
||||
{
|
||||
if(is_array($this->licenses)) {
|
||||
return $this->licenses;
|
||||
}
|
||||
|
||||
$jsonFile = new JsonFile(__DIR__ . '/../../../res/spdx-licenses.json');
|
||||
$this->licenses = $jsonFile->read();
|
||||
|
||||
return $this->licenses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns license metadata by license identifier.
|
||||
*
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLicenseByIdentifier($identifier)
|
||||
{
|
||||
$license = $this->licenses[$identifier];
|
||||
|
||||
// add URL for the license text (it's not included in the json)
|
||||
$license[2] = 'http://spdx.org/licenses/' . $identifier . '#licenseText';
|
||||
|
||||
return $license;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short identifier of a license by full name.
|
||||
*
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierByName($name)
|
||||
{
|
||||
foreach ($this->licenses as $identifier => $licenseData) {
|
||||
if($licenseData[0] === $name) { // key 0 = fullname
|
||||
return $identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OSI Approved status for a license by identifier.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOsiApprovedByIdentifier($identifier)
|
||||
{
|
||||
return $this->licenses[$identifier][1]; // key 1 = osi approved
|
||||
}
|
||||
|
||||
/**
|
||||
* Check, if the identifier for a license is valid.
|
||||
*
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidLicenseIdentifier($identifier)
|
||||
{
|
||||
$identifiers = array_keys($this->licenses);
|
||||
|
||||
return in_array($identifier, $identifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $license
|
||||
*
|
||||
* @return bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function validate($license)
|
||||
{
|
||||
if (is_array($license)) {
|
||||
$count = count($license);
|
||||
if ($count !== count(array_filter($license, 'is_string'))) {
|
||||
throw new \InvalidArgumentException('Array of strings expected.');
|
||||
}
|
||||
$license = $count > 1 ? '('.implode(' or ', $license).')' : (string) reset($license);
|
||||
}
|
||||
|
||||
if (!is_string($license)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Array or String expected, %s given.', gettype($license)
|
||||
));
|
||||
}
|
||||
|
||||
return $this->isValidLicenseString($license);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $license
|
||||
*
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
private function isValidLicenseString($license)
|
||||
{
|
||||
$tokens = array(
|
||||
'po' => '\(',
|
||||
'pc' => '\)',
|
||||
'op' => '(?:or|and)',
|
||||
'lix' => '(?:NONE|NOASSERTION)',
|
||||
'lir' => 'LicenseRef-\d+',
|
||||
'lic' => '[-+_.a-zA-Z0-9]{3,}',
|
||||
'ws' => '\s+',
|
||||
'_' => '.',
|
||||
);
|
||||
|
||||
$next = function () use ($license, $tokens) {
|
||||
static $offset = 0;
|
||||
|
||||
if ($offset >= strlen($license)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($tokens as $name => $token) {
|
||||
if (false === $r = preg_match('{' . $token . '}', $license, $matches, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
throw new \RuntimeException('Pattern for token %s failed (regex error).', $name);
|
||||
}
|
||||
if ($r === 0) {
|
||||
continue;
|
||||
}
|
||||
if ($matches[0][1] !== $offset) {
|
||||
continue;
|
||||
}
|
||||
$offset += strlen($matches[0][0]);
|
||||
|
||||
return array($name, $matches[0][0]);
|
||||
}
|
||||
|
||||
throw new \RuntimeException('At least the last pattern needs to match, but it did not (dot-match-all is missing?).');
|
||||
};
|
||||
|
||||
$open = 0;
|
||||
$require = 1;
|
||||
$lastop = null;
|
||||
|
||||
while (list($token, $string) = $next()) {
|
||||
switch ($token) {
|
||||
case 'po':
|
||||
if ($open || !$require) {
|
||||
return false;
|
||||
}
|
||||
$open = 1;
|
||||
break;
|
||||
case 'pc':
|
||||
if ($open !== 1 || $require || !$lastop) {
|
||||
return false;
|
||||
}
|
||||
$open = 2;
|
||||
break;
|
||||
case 'op':
|
||||
if ($require || !$open) {
|
||||
return false;
|
||||
}
|
||||
$lastop || $lastop = $string;
|
||||
if ($lastop !== $string) {
|
||||
return false;
|
||||
}
|
||||
$require = 1;
|
||||
break;
|
||||
case 'lix':
|
||||
if ($open) {
|
||||
return false;
|
||||
}
|
||||
goto lir;
|
||||
case 'lic':
|
||||
if (!$this->isValidLicenseIdentifier($string)) {
|
||||
return false;
|
||||
}
|
||||
// Fall-through intended
|
||||
case 'lir':
|
||||
lir:
|
||||
if (!$require) {
|
||||
return false;
|
||||
}
|
||||
$require = 0;
|
||||
break;
|
||||
case 'ws':
|
||||
break;
|
||||
case '_':
|
||||
return false;
|
||||
default:
|
||||
throw new \RuntimeException(sprintf('Unparsed token: %s.', print_r($token, true)));
|
||||
}
|
||||
}
|
||||
|
||||
return !($open % 2 || $require);
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
use Composer\Json\JsonFormatter;
|
||||
|
||||
/**
|
||||
* The SPDX Licenses Updater scrapes licenses from the spdx website
|
||||
* and updates the "res/spdx-licenses.json" file accordingly.
|
||||
*
|
||||
* The class is used by the update script "bin/update-spdx-licenses".
|
||||
*/
|
||||
class SpdxLicensesUpdater
|
||||
{
|
||||
private $licensesUrl = 'http://www.spdx.org/licenses/';
|
||||
|
||||
public function update()
|
||||
{
|
||||
$json = json_encode($this->getLicenses(), true);
|
||||
$prettyJson = JsonFormatter::format($json, true, true);
|
||||
file_put_contents(__DIR__ . '/../../../res/spdx-licenses.json', $prettyJson);
|
||||
}
|
||||
|
||||
private function getLicenses()
|
||||
{
|
||||
$licenses = array();
|
||||
|
||||
$dom = new \DOMDocument;
|
||||
$dom->loadHTMLFile($this->licensesUrl);
|
||||
|
||||
$xPath = new \DOMXPath($dom);
|
||||
$trs = $xPath->query('//table//tbody//tr');
|
||||
|
||||
// iterate over each row in the table
|
||||
foreach($trs as $tr) {
|
||||
$tds = $tr->getElementsByTagName('td'); // get the columns in this row
|
||||
|
||||
if($tds->length < 4) {
|
||||
throw new \Exception('Obtaining the license table failed. Wrong table format. Found less than 4 cells in a row.');
|
||||
}
|
||||
|
||||
if(trim($tds->item(3)->nodeValue) == 'License Text') {
|
||||
$fullname = trim($tds->item(0)->nodeValue);
|
||||
$identifier = trim($tds->item(1)->nodeValue);
|
||||
$osiApproved = ((isset($tds->item(2)->nodeValue) && $tds->item(2)->nodeValue === 'Y')) ? true : false;
|
||||
|
||||
// The license URL is not scraped intentionally to keep json file size low.
|
||||
// It's build when requested, see SpdxLicense->getLicenseByIdentifier().
|
||||
//$licenseURL = = $tds->item(3)->getAttribute('href');
|
||||
|
||||
$licenses += array($identifier => array($fullname, $osiApproved));
|
||||
}
|
||||
}
|
||||
|
||||
return $licenses;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue