diff --git a/build/build-composer-json.php b/build/build-composer-json.php index b415877..d553fa5 100644 --- a/build/build-composer-json.php +++ b/build/build-composer-json.php @@ -1,11 +1,14 @@ push( new CacheMiddleware( - new PrivateCacheStrategy( + new GreedyCacheStrategy( new DoctrineCacheStorage( new FilesystemCache(__DIR__ . '/cache') - ) + ), + 3600 ) ), 'cache' ); $client = new Client(['handler' => $stack]); - -$data = json_decode($client->get('https://www.drupal.org/api-d7/node.json?type=project_release&taxonomy_vocabulary_7=100&field_release_build_type=static')->getBody()); - -$projects = []; +$projects = new Projects($client); $conflict = []; -class UrlHelper { - - public static function prepareUrl($url) { - return str_replace('https://www.drupal.org/api-d7/node', 'https://www.drupal.org/api-d7/node.json', $url); +/** + * @param $url + * @param \GuzzleHttp\Client $client + * + * @return array + */ +function fetchAllData($url, Client $client) { + $results = []; + $data = json_decode($client->get($url)->getBody()); + while (isset($data) && isset($data->list)) { + $results = array_merge($results, $data->list); + + if (isset($data->next)) { + $data = json_decode($client->get(UrlHelper::prepareUrl($data->next))->getBody()); + } + else { + $data = NULL; + } } - + return $results; } -class VersionParser { - - public static function getSemVer($version, $isCore) { - $version = $isCore ? static::handleCore($version) : static::handleContrib($version); - return static::isValid($version) ? $version : FALSE; - } +// Security releases +$results = fetchAllData('https://www.drupal.org/api-d7/node.json?type=project_release&taxonomy_vocabulary_7=100&field_release_build_type=static', $client); +foreach ($results as $result) { + $nid = $result->field_release_project->id; + $core = (int) substr($result->field_release_version, 0, 1); - public static function handleCore($version) { - return $version; + // Skip D6 and older. + if ($core < 7) { + continue; } - public static function handleContrib($version) { - list($core, $version) = explode('-', $version, 2); - return $version; - } + $project = $projects->getFromNid($nid); - public static function isValid($version) { - return (strpos($version, 'unstable') === FALSE); + if (!$project) { + // @todo: log error + continue; } -} - -while (isset($data) && isset($data->list)) { - $results = array_merge($results, $data->list); - - if (isset($data->next)) { - $data = json_decode($client->get(UrlHelper::prepareUrl($data->next))->getBody()); - } - else { - $data = NULL; + try { + $is_core = ($project->field_project_machine_name == 'drupal') ? TRUE : FALSE; + $constraint = VersionParser::generateRangeConstraint($result->field_release_version, $is_core); + if (!$constraint) { + throw new InvalidArgumentException('Invalid version number.'); + } + $conflict[$core]['drupal/' . $project->field_project_machine_name][] = $constraint; + } catch (\Exception $e) { + // @todo: log exception + continue; } } +// Insecure releases +$results = fetchAllData('https://www.drupal.org/api-d7/node.json?type=project_release&taxonomy_vocabulary_7=188131&field_release_build_type=static', $client); foreach ($results as $result) { $nid = $result->field_release_project->id; $core = (int) substr($result->field_release_version, 0, 1); @@ -81,24 +96,20 @@ public static function isValid($version) { continue; } - try { - if (!isset($projects[$nid])) { - $project = json_decode($client->get('https://www.drupal.org/api-d7/node.json?nid=' . $nid)->getBody()); - $projects[$nid] = $project->list[0]; - } - } catch (\GuzzleHttp\Exception\ServerException $e) { - // @todo: log exception + $project = $projects->getFromNid($nid); + + if (!$project) { + // @todo: log error continue; } try { - $project = $projects[$nid]; $is_core = ($project->field_project_machine_name == 'drupal') ? TRUE : FALSE; - $version = VersionParser::getSemVer($result->field_release_version, $is_core); - if (!$version) { + $constraint = VersionParser::generateExplicitConstraint($result->field_release_version, $is_core); + if (!$constraint) { throw new InvalidArgumentException('Invalid version number.'); } - $conflict[$core]['drupal/' . $project->field_project_machine_name][] = '<' . $version; + $conflict[$core]['drupal/' . $project->field_project_machine_name][] = $constraint; } catch (\Exception $e) { // @todo: log exception continue; @@ -121,7 +132,7 @@ public static function isValid($version) { foreach ($packages as $package => $constraints) { natsort($constraints); - $composer['conflict'][$package] = implode(',', $constraints); + $composer['conflict'][$package] = implode('|', $constraints); } // drupal/core is a subtree split for drupal/drupal and has no own SAs. diff --git a/build/composer.json b/build/composer.json index a7c367c..1ddabe5 100644 --- a/build/composer.json +++ b/build/composer.json @@ -10,6 +10,12 @@ "composer/composer": "^1.0", "kevinrob/guzzle-cache-middleware": "^3.2", "guzzlehttp/guzzle": "^6.3", - "doctrine/cache": "^1.7" + "doctrine/cache": "^1.7", + "ext-json": "*" + }, + "autoload": { + "psr-4": { + "DrupalComposer\\DrupalSecurityAdvisories\\": "src" + } } } diff --git a/build/src/Projects.php b/build/src/Projects.php new file mode 100644 index 0000000..fd78b25 --- /dev/null +++ b/build/src/Projects.php @@ -0,0 +1,27 @@ +client = $client; + } + + public function getFromNid($nid) { + try { + if (!isset($this->storage[$nid])) { + $project = json_decode($this->client->get('https://www.drupal.org/api-d7/node.json?nid=' . $nid)->getBody()); + $this->storage[$nid] = $project->list[0]; + } + } catch (\GuzzleHttp\Exception\ServerException $e) { + $this->storage[$nid] = []; + } + return $this->storage[$nid]; + } + +} diff --git a/build/src/UrlHelper.php b/build/src/UrlHelper.php new file mode 100644 index 0000000..6fd9382 --- /dev/null +++ b/build/src/UrlHelper.php @@ -0,0 +1,11 @@ +=$major.$minor,<$version"; + } + + public static function handleContrib($version) { + list($core, $version) = explode('-', $version, 2); + list($major) = explode('.', $version); + return ">=$major,<$version"; + } + + public static function isValid($version) { + return (strpos($version, 'unstable') === FALSE); + } + +}