From 0d3d33bf1bfb7570eb6070c9d2cd2b1bc07451d2 Mon Sep 17 00:00:00 2001 From: Peter Gribanov Date: Fri, 10 Nov 2017 20:46:52 +0300 Subject: [PATCH] Get PHP version from [Packagist] (#1256) --- lib/all-badge-examples.js | 9 +++++++- server.js | 33 +++++++++++++++++++++++++++++ service-tests/helpers/validators.js | 15 +++++++++++++ service-tests/packagist.js | 20 +++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 service-tests/packagist.js diff --git a/lib/all-badge-examples.js b/lib/all-badge-examples.js index bbaf93ac01..f8ac1c8958 100644 --- a/lib/all-badge-examples.js +++ b/lib/all-badge-examples.js @@ -966,7 +966,14 @@ const allBadgeExamples = [ { title: 'JetBrains Plugins', previewUri: '/jetbrains/plugin/v/9630-a8translate.svg' - } + }, + { + title: 'PHP from Packagist', + previewUri: '/packagist/php-v/symfony/symfony.svg', + keywords: [ + 'PHP' + ] + }, ] }, { diff --git a/server.js b/server.js index 218b249ec3..b80e74b4a8 100644 --- a/server.js +++ b/server.js @@ -7395,6 +7395,39 @@ cache(function(data, match, sendBadge, request) { }); })); +// PHP version from Packagist +camp.route(/^\/packagist\/php-v\/([^/]+\/[^/]+)(?:\/([^/]+))?\.(svg|png|gif|jpg|json)$/, +cache(function(data, match, sendBadge, request) { + const userRepo = match[1]; // eg, espadrine/sc + const version = match[2] ? match[2] : 'dev-master'; + const format = match[3]; + const options = { + method: 'GET', + uri: 'https://packagist.org/p/' + userRepo + '.json', + }; + const badgeData = getBadgeData('PHP', data); + request(options, function(err, res, buffer) { + if (err !== null) { + log.error('Packagist error: ' + err.stack); + if (res) { + log.error('' + res); + } + badgeData.text[1] = 'invalid'; + sendBadge(format, badgeData); + return; + } + + try { + const data = JSON.parse(buffer); + badgeData.text[1] = data.packages[userRepo][version].require.php; + badgeData.colorscheme = 'blue'; + } catch(e) { + badgeData.text[1] = 'invalid'; + } + sendBadge(format, badgeData); + }); +})); + // Any badge. camp.route(/^\/(:|badge\/)(([^-]|--)*?)-(([^-]|--)*)-(([^-]|--)+)\.(svg|png|gif|jpg)$/, function(data, match, end, ask) { diff --git a/service-tests/helpers/validators.js b/service-tests/helpers/validators.js index ef925be296..1df150de16 100644 --- a/service-tests/helpers/validators.js +++ b/service-tests/helpers/validators.js @@ -11,6 +11,20 @@ const isVPlusTripleDottedVersion = withRegex(/^v[0-9]+.[0-9]+.[0-9]+$/); const isVPlusDottedVersionAtLeastOne = withRegex(/^v\d+(\.\d+)?(\.\d+)?$/); +// Simple regex for test Composer versions rule +// https://getcomposer.org/doc/articles/versions.md +// Examples: +// 7.1 +// >=5.6 +// >1.0 <2.0 +// !=1.0 <1.1 || >=1.2 +// 7.1.* +// 7.* || 5.6.* +// This regex not support branches, minimum-stability, ref and any (*) +// https://getcomposer.org/doc/04-schema.md#package-links +// https://getcomposer.org/doc/04-schema.md#minimum-stability +const isComposerVersion = withRegex(/^\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?((\s*\|\|)?\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?)*\s*$/); + const isStarRating = withRegex(/^(?=.{5}$)(\u2605{0,5}[\u00BC\u00BD\u00BE]?\u2606{0,5})$/); // Required to be > 0, beacuse accepting zero masks many problems. @@ -31,6 +45,7 @@ module.exports = { isSemver, isVPlusTripleDottedVersion, isVPlusDottedVersionAtLeastOne, + isComposerVersion, isStarRating, isMetric, isMetricOverTimePeriod, diff --git a/service-tests/packagist.js b/service-tests/packagist.js new file mode 100644 index 0000000000..dc30d321a6 --- /dev/null +++ b/service-tests/packagist.js @@ -0,0 +1,20 @@ +'use strict'; + +const Joi = require('joi'); +const ServiceTester = require('./runner/service-tester'); +const { isComposerVersion } = require('./helpers/validators'); + +const t = new ServiceTester({ id: 'packagist', title: 'PHP version from Packagist' }); +module.exports = t; + +t.create('gets the package version of symfony') + .get('/php-v/symfony/symfony.json') + .expectJSONTypes(Joi.object().keys({ name: 'PHP', value: isComposerVersion })); + +t.create('gets the package version of symfony 2.8') + .get('/php-v/symfony/symfony/v2.8.0.json') + .expectJSONTypes(Joi.object().keys({ name: 'PHP', value: isComposerVersion })); + +t.create('invalid package name') + .get('/php-v/frodo/is-not-a-package.json') + .expectJSON({ name: 'PHP', value: 'invalid' });