diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 7cc0dfb8fa..4ae21b6b26 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -7,6 +7,7 @@ const packageSchema = Joi.object() .pattern( /^/, Joi.object({ + 'default-branch': Joi.bool(), version: Joi.string(), require: Joi.object({ php: Joi.string(), @@ -74,6 +75,13 @@ class BasePackagistService extends BaseJsonService { }) } + getDefaultBranch(json, user, repo) { + const packageName = this.getPackageName(user, repo) + return Object.values(json.packages[packageName]).find( + b => b['default-branch'] === true + ) + } + getPackageName(user, repo) { return `${user.toLowerCase()}/${repo.toLowerCase()}` } diff --git a/services/packagist/packagist-license.service.js b/services/packagist/packagist-license.service.js index 4511cd3496..1184844736 100644 --- a/services/packagist/packagist-license.service.js +++ b/services/packagist/packagist-license.service.js @@ -14,6 +14,7 @@ const packageSchema = Joi.object() .pattern( /^/, Joi.object({ + 'default-branch': Joi.bool(), license: Joi.array().required(), }).required() ) @@ -66,8 +67,7 @@ module.exports = class PackagistLicense extends BasePackagistService { } transform({ json, user, repo }) { - const packageName = this.getPackageName(user, repo) - const branch = json.packages[packageName]['dev-master'] + const branch = this.getDefaultBranch(json, user, repo) if (!branch) { throw new NotFound({ prettyMessage: 'default branch not found' }) } diff --git a/services/packagist/packagist-license.spec.js b/services/packagist/packagist-license.spec.js index 04f0238432..a9241e10ae 100644 --- a/services/packagist/packagist-license.spec.js +++ b/services/packagist/packagist-license.spec.js @@ -8,20 +8,47 @@ describe('PackagistLicense', function () { it('should throw NotFound when default branch is missing', function () { const json = { packages: { - 'doctrine/orm': {}, - 'elhadraoui/doctrine-orm': { - 'dev-master': { license: 'MIT' }, + 'frodo/the-one-package': { + '1.0.x-dev': { license: 'MIT' }, + '1.1.x-dev': { license: 'MIT' }, + '2.0.x-dev': { license: 'MIT' }, + '2.1.x-dev': { license: 'MIT' }, }, }, } expect(() => PackagistLicense.prototype.transform({ json, - user: 'doctrine', - repo: 'orm', + user: 'frodo', + repo: 'the-one-package', }) ) .to.throw(NotFound) .with.property('prettyMessage', 'default branch not found') }) + + it('should return default branch when default branch is found', function () { + const json = { + packages: { + 'frodo/the-one-package': { + '1.0.x-dev': { license: 'MIT' }, + '1.1.x-dev': { license: 'MIT' }, + '2.0.x-dev': { + license: 'MIT-default-branch', + 'default-branch': true, + }, + '2.1.x-dev': { license: 'MIT' }, + }, + }, + } + expect( + PackagistLicense.prototype.transform({ + json, + user: 'frodo', + repo: 'the-one-package', + }) + ) + .to.have.property('license') + .that.equals('MIT-default-branch') + }) }) diff --git a/services/packagist/packagist-php-version.service.js b/services/packagist/packagist-php-version.service.js index 6388f51902..96ff0d1c1d 100644 --- a/services/packagist/packagist-php-version.service.js +++ b/services/packagist/packagist-php-version.service.js @@ -76,26 +76,36 @@ module.exports = class PackagistPhpVersion extends BasePackagistService { } } - async handle({ user, repo, version = 'dev-master' }, { server }) { + transform({ json, user, repo, version = '' }) { + const packageVersion = + version === '' + ? this.getDefaultBranch(json, user, repo) + : json.packages[this.getPackageName(user, repo)][version] + + if (!packageVersion) { + throw new NotFound({ prettyMessage: 'invalid version' }) + } + + if (!packageVersion.require || !packageVersion.require.php) { + throw new NotFound({ prettyMessage: 'version requirement not found' }) + } + + return { phpVersion: packageVersion.require.php } + } + + async handle({ user, repo, version = '' }, { server }) { const allData = await this.fetch({ user, repo, schema: allVersionsSchema, server, }) - - if (!(version in allData.packages[this.getPackageName(user, repo)])) { - throw new NotFound({ prettyMessage: 'invalid version' }) - } - - const packageVersion = - allData.packages[this.getPackageName(user, repo)][version] - if (!packageVersion.require || !packageVersion.require.php) { - throw new NotFound({ prettyMessage: 'version requirement not found' }) - } - - return this.constructor.render({ - php: packageVersion.require.php, + const { phpVersion } = this.transform({ + json: allData, + user, + repo, + version, }) + return this.constructor.render({ php: phpVersion }) } } diff --git a/services/packagist/packagist-php-version.spec.js b/services/packagist/packagist-php-version.spec.js new file mode 100644 index 0000000000..7af1b66996 --- /dev/null +++ b/services/packagist/packagist-php-version.spec.js @@ -0,0 +1,101 @@ +'use strict' + +const { expect } = require('chai') +const { NotFound } = require('..') +const PackagistPhpVersion = require('./packagist-php-version.service') + +describe('PackagistPhpVersion', function () { + const json = { + packages: { + 'frodo/the-one-package': { + '1.0.0': { require: { php: '^5.6 || ^7' } }, + '2.0.0': { require: { php: '^7.2' } }, + '3.0.0': { require: { php: '^7.4 || 8' } }, + 'dev-main': { require: { php: '^8' }, 'default-branch': true }, + }, + 'samwise/gardening': { + '1.0.x-dev': {}, + '2.0.x-dev': {}, + }, + 'pippin/mischief': { + '1.0.0': {}, + 'dev-main': { require: {}, 'default-branch': true }, + }, + }, + } + + it('should throw NotFound when package version is missing', function () { + expect(() => + PackagistPhpVersion.prototype.transform({ + json, + user: 'frodo', + repo: 'the-one-package', + version: '4.0.0', + }) + ) + .to.throw(NotFound) + .with.property('prettyMessage', 'invalid version') + }) + + it('should throw NotFound when version not specified and no default branch found', function () { + expect(() => + PackagistPhpVersion.prototype.transform({ + json, + user: 'samwise', + repo: 'gardening', + }) + ) + .to.throw(NotFound) + .with.property('prettyMessage', 'invalid version') + }) + + it('should throw NotFound when PHP version not found on package when using default branch', function () { + expect(() => + PackagistPhpVersion.prototype.transform({ + json, + user: 'pippin', + repo: 'mischief', + }) + ) + .to.throw(NotFound) + .with.property('prettyMessage', 'version requirement not found') + }) + + it('should throw NotFound when PHP version not found on package when using specified version', function () { + expect(() => + PackagistPhpVersion.prototype.transform({ + json, + user: 'pippin', + repo: 'mischief', + version: '1.0.0', + }) + ) + .to.throw(NotFound) + .with.property('prettyMessage', 'version requirement not found') + }) + + it('should return PHP version for the default branch', function () { + expect( + PackagistPhpVersion.prototype.transform({ + json, + user: 'frodo', + repo: 'the-one-package', + }) + ) + .to.have.property('phpVersion') + .that.equals('^8') + }) + + it('should return PHP version for the specified branch', function () { + expect( + PackagistPhpVersion.prototype.transform({ + json, + user: 'frodo', + repo: 'the-one-package', + version: '3.0.0', + }) + ) + .to.have.property('phpVersion') + .that.equals('^7.4 || 8') + }) +})