diff --git a/services/vcpkg/vcpkg-version-helpers.js b/services/vcpkg/vcpkg-version-helpers.js new file mode 100644 index 0000000000000000000000000000000000000000..23cc2d7f4bb3ccc37c2fbc7e137644b035a8e0dd --- /dev/null +++ b/services/vcpkg/vcpkg-version-helpers.js @@ -0,0 +1,17 @@ +import { InvalidResponse } from '../index.js' + +export function parseVersionFromVcpkgManifest(manifest) { + if (manifest['version-date']) { + return manifest['version-date'] + } + if (manifest['version-semver']) { + return manifest['version-semver'] + } + if (manifest['version-string']) { + return manifest['version-string'] + } + if (manifest.version) { + return manifest.version + } + throw new InvalidResponse({ prettyMessage: 'missing version' }) +} diff --git a/services/vcpkg/vcpkg-version-helpers.spec.js b/services/vcpkg/vcpkg-version-helpers.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..5c16de5f5439a9319e6ea00a3a4e2d80864fd496 --- /dev/null +++ b/services/vcpkg/vcpkg-version-helpers.spec.js @@ -0,0 +1,41 @@ +import { expect } from 'chai' +import { InvalidResponse } from '../index.js' +import { parseVersionFromVcpkgManifest } from './vcpkg-version-helpers.js' + +describe('parseVersionFromVcpkgManifest', function () { + it('returns a version when `version` field is detected', function () { + expect( + parseVersionFromVcpkgManifest({ + version: '2.12.1', + }) + ).to.equal('2.12.1') + }) + + it('returns a version when `version-date` field is detected', function () { + expect( + parseVersionFromVcpkgManifest({ + 'version-date': '2022-12-04', + }) + ).to.equal('2022-12-04') + }) + + it('returns a version when `version-semver` field is detected', function () { + expect( + parseVersionFromVcpkgManifest({ + 'version-semver': '3.11.2', + }) + ).to.equal('3.11.2') + }) + + it('returns a version when `version-date` field is detected', function () { + expect( + parseVersionFromVcpkgManifest({ + 'version-string': '22.01', + }) + ).to.equal('22.01') + }) + + it('rejects when no version field variant is detected', function () { + expect(() => parseVersionFromVcpkgManifest('{}')).to.throw(InvalidResponse) + }) +}) diff --git a/services/vcpkg/vcpkg-version.service.js b/services/vcpkg/vcpkg-version.service.js index 8cf7613ea50525069f5dd00d46bd50ed17461fdc..0b2e0403083d827f4a25d87c8eae34bbd2dfc72e 100644 --- a/services/vcpkg/vcpkg-version.service.js +++ b/services/vcpkg/vcpkg-version.service.js @@ -3,10 +3,26 @@ import { ConditionalGithubAuthV3Service } from '../github/github-auth-service.js import { fetchJsonFromRepo } from '../github/github-common-fetch.js' import { renderVersionBadge } from '../version.js' import { NotFound } from '../index.js' +import { parseVersionFromVcpkgManifest } from './vcpkg-version-helpers.js' -const vcpkgManifestSchema = Joi.object({ - version: Joi.string().required(), -}).required() +// Handle the different version fields available in Vcpkg manifests +// https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json?source=recommendations#version +const vcpkgManifestSchema = Joi.alternatives() + .match('one') + .try( + Joi.object({ + version: Joi.string().required(), + }).required(), + Joi.object({ + 'version-date': Joi.string().required(), + }).required(), + Joi.object({ + 'version-semver': Joi.string().required(), + }).required(), + Joi.object({ + 'version-string': Joi.string().required(), + }).required() + ) export default class VcpkgVersion extends ConditionalGithubAuthV3Service { static category = 'version' @@ -29,13 +45,14 @@ export default class VcpkgVersion extends ConditionalGithubAuthV3Service { async handle({ portName }) { try { - const { version } = await fetchJsonFromRepo(this, { + const manifest = await fetchJsonFromRepo(this, { schema: vcpkgManifestSchema, user: 'microsoft', repo: 'vcpkg', branch: 'master', filename: `ports/${portName}/vcpkg.json`, }) + const version = parseVersionFromVcpkgManifest(manifest) return this.constructor.render({ version }) } catch (error) { if (error instanceof NotFound) { diff --git a/services/vcpkg/vcpkg-version.tester.js b/services/vcpkg/vcpkg-version.tester.js index 0ffe35d55ee5d4ac18454dc47f801412198fec57..b7ad6afc3e0a75247a90ff5ed2630a9b5436e713 100644 --- a/services/vcpkg/vcpkg-version.tester.js +++ b/services/vcpkg/vcpkg-version.tester.js @@ -3,11 +3,11 @@ import { createServiceTester } from '../tester.js' export const t = await createServiceTester() -t.create('gets the port version of entt') - .get('/entt.json') - .expectBadge({ label: 'vcpkg', message: isSemver }) +t.create('gets nlohmann-json port version') + .get('/nlohmann-json.json') + .expectBadge({ label: 'vcpkg', color: 'blue', message: isSemver }) -t.create('returns not found for invalid port') +t.create('gets not found error for invalid port') .get('/this-port-does-not-exist.json') .expectBadge({ label: 'vcpkg',