From 814aa30da413f10959d007202cca1cc5a823e688 Mon Sep 17 00:00:00 2001 From: Jacob Bandes-Storch Date: Mon, 28 Feb 2022 22:08:45 -0800 Subject: [PATCH] Add [Conan] version service (#7460) * Add [Conan] version service * Rework to use conan-center-index GitHub repo * Conditional mock based on presence of github token * Refactor yaml parsing into a helper function, move tests to .spec.js * remove custom version parsing * improve test data * updates from review Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com> --- services/conan/conan-version-helpers.js | 21 ++++++++++++ services/conan/conan-version-helpers.spec.js | 33 +++++++++++++++++++ services/conan/conan-version.service.js | 34 ++++++++++++++++++++ services/conan/conan-version.tester.js | 17 ++++++++++ 4 files changed, 105 insertions(+) create mode 100644 services/conan/conan-version-helpers.js create mode 100644 services/conan/conan-version-helpers.spec.js create mode 100644 services/conan/conan-version.service.js create mode 100644 services/conan/conan-version.tester.js diff --git a/services/conan/conan-version-helpers.js b/services/conan/conan-version-helpers.js new file mode 100644 index 0000000000..05519e453d --- /dev/null +++ b/services/conan/conan-version-helpers.js @@ -0,0 +1,21 @@ +import yaml from 'js-yaml' +import { NotFound, InvalidResponse } from '../index.js' +import { latest } from '../version.js' + +export function parseLatestVersionFromConfig(configYaml) { + let versions + try { + const config = yaml.load(configYaml) + versions = Object.keys(config.versions) + } catch (err) { + throw new InvalidResponse({ + prettyMessage: 'invalid config.yml', + underlyingError: err, + }) + } + const version = latest(versions) + if (version == null) { + throw new NotFound({ prettyMessage: 'no versions found' }) + } + return version +} diff --git a/services/conan/conan-version-helpers.spec.js b/services/conan/conan-version-helpers.spec.js new file mode 100644 index 0000000000..3c622b0ab2 --- /dev/null +++ b/services/conan/conan-version-helpers.spec.js @@ -0,0 +1,33 @@ +import { expect } from 'chai' +import { NotFound, InvalidResponse } from '../index.js' +import { parseLatestVersionFromConfig } from './conan-version-helpers.js' + +describe('parseLatestVersionFromConfig', function () { + it('returns latest available version', function () { + expect( + parseLatestVersionFromConfig(` + versions: + 1.68.0: + folder: all + 1.70.0: + folder: all + 1.69.0: + folder: all + `) + ).to.equal('1.70.0') + }) + + it('rejects invalid yaml', function () { + expect(() => parseLatestVersionFromConfig('[')).to.throw(InvalidResponse) + }) + it('treats no results array as invalid', function () { + expect(() => + parseLatestVersionFromConfig('somethingElse: whatever') + ).to.throw(InvalidResponse) + }) + it('treats empty results array as not found', function () { + expect(() => parseLatestVersionFromConfig('versions: []')).to.throw( + NotFound + ) + }) +}) diff --git a/services/conan/conan-version.service.js b/services/conan/conan-version.service.js new file mode 100644 index 0000000000..92d8361664 --- /dev/null +++ b/services/conan/conan-version.service.js @@ -0,0 +1,34 @@ +import { renderVersionBadge } from '../version.js' +import { ConditionalGithubAuthV3Service } from '../github/github-auth-service.js' +import { fetchRepoContent } from '../github/github-common-fetch.js' +import { parseLatestVersionFromConfig } from './conan-version-helpers.js' + +export default class ConanVersion extends ConditionalGithubAuthV3Service { + static category = 'version' + + static route = { base: 'conan/v', pattern: ':packageName' } + + static examples = [ + { + title: 'Conan Center', + namedParams: { packageName: 'boost' }, + staticPreview: renderVersionBadge({ version: '1.78.0' }), + keywords: ['c++'], + }, + ] + + static defaultBadgeData = { label: 'conan' } + + async handle({ packageName }) { + const configContent = await fetchRepoContent(this, { + user: 'conan-io', + repo: 'conan-center-index', + branch: 'master', + filename: `recipes/${packageName}/config.yml`, + }) + + const version = parseLatestVersionFromConfig(configContent) + + return renderVersionBadge({ version }) + } +} diff --git a/services/conan/conan-version.tester.js b/services/conan/conan-version.tester.js new file mode 100644 index 0000000000..75087c2d67 --- /dev/null +++ b/services/conan/conan-version.tester.js @@ -0,0 +1,17 @@ +import { isSemver } from '../test-validators.js' +import { createServiceTester } from '../tester.js' + +export const t = await createServiceTester() + +t.create('gets the package version of zeromq') + .get('/zeromq.json') + .expectBadge({ label: 'conan', message: isSemver }) + +t.create('returns not found for invalid package') + .get('/this package does not exist - shields test.json') + .expectBadge({ + label: 'conan', + color: 'red', + message: + 'repo not found, branch not found, or recipes/this package does not exist - shields test/config.yml missing', + })