Skip to content
Snippets Groups Projects
Commit 9a806cf5 authored by Konstantin_Kurganov's avatar Konstantin_Kurganov Committed by Rhys Arkins
Browse files

feat: add "hex" datasource (Elixir/Erlang) (#3167)

Closes #3043
parent e717dbbd
Branches
No related tags found
No related merge requests found
const URL = require('url');
const got = require('../../util/got');
const hostRules = require('../../util/host-rules');
module.exports = {
getPkgReleases,
};
function getHostOpts(url) {
const { host } = URL.parse(url);
const opts = hostRules.find({ platform: 'hex', host }, { json: true });
if (opts && opts.token) {
opts.hearders = { Authorization: opts.token };
delete opts.token;
}
return opts;
}
async function getPkgReleases({ lookupName }) {
const hexUrl = `https://hex.pm/api/packages/${lookupName}`;
try {
const opts = getHostOpts(hexUrl);
const res = (await got(hexUrl, {
json: true,
...opts,
})).body;
if (!(res && res.releases && res.name)) {
logger.warn({ lookupName }, `Received invalid hex package data`);
return null;
}
const result = {
releases: [],
};
if (res.releases) {
result.releases = res.releases.map(version => ({
version: version.version,
}));
}
if (res.meta && res.meta.links) {
result.sourceUrl = res.meta.links.Github;
}
result.homepage = res.html_url;
return result;
} catch (err) {
if (err.statusCode === 401) {
logger.info({ lookupName }, `Authorization failure: not authorized`);
logger.debug(
{
err,
},
'Authorization error'
);
return null;
}
if (err.statusCode === 404) {
logger.info({ lookupName }, `Dependency lookup failure: not found`);
logger.debug(
{
err,
},
'Package lookup error'
);
return null;
}
logger.warn({ err, lookupName }, 'hex lookup failure: Unknown error');
return null;
}
}
......@@ -3,6 +3,7 @@ const versioning = require('../versioning');
const cargo = require('./cargo');
const docker = require('./docker');
const hex = require('./hex');
const github = require('./github');
const gitlab = require('./gitlab');
const go = require('./go');
......@@ -20,6 +21,7 @@ const terraform = require('./terraform');
const datasources = {
cargo,
docker,
hex,
github,
gitlab,
go,
......
{
"docs_html_url": null,
"downloads": {
"all": 7801231,
"day": 4550,
"recent": 1186862,
"week": 107546
},
"html_url": "https://hex.pm/packages/certifi",
"inserted_at": "2015-09-10T13:58:43.376194Z",
"meta": {
"description": "CA bundle adapted from Mozilla by https://certifi.io",
"licenses": [
"BSD"
],
"links": {
"Github": "https://github.com/certifi/erlang-certifi"
},
"maintainers": [
"Benoit Chesneau"
]
},
"name": "certifi",
"owners": [
{
"email": "bchesneau@gmail.com",
"url": "https://hex.pm/api/users/benoitc",
"username": "benoitc"
}
],
"releases": [
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.5.1",
"version": "2.5.1"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.4.2",
"version": "2.4.2"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.4.1",
"version": "2.4.1"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.3.1",
"version": "2.3.1"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.3.0",
"version": "2.3.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.2.0",
"version": "2.2.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.1.0",
"version": "2.1.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/2.0.0",
"version": "2.0.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/1.2.1",
"version": "1.2.1"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/1.2.0",
"version": "1.2.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/1.1.0",
"version": "1.1.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/1.0.0",
"version": "1.0.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.7.0",
"version": "0.7.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.6.0",
"version": "0.6.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.5.0",
"version": "0.5.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.4.0",
"version": "0.4.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.3.0",
"version": "0.3.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.2.0",
"version": "0.2.0"
},
{
"has_docs": false,
"url": "https://hex.pm/api/packages/certifi/releases/0.1.1",
"version": "0.1.1"
}
],
"repository": "hexpm",
"retirements": {
},
"updated_at": "2019-01-28T20:35:23.869888Z",
"url": "https://hex.pm/api/packages/certifi"
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`datasource/hex getPkgReleases process public repo without auth 1`] = `
Object {
"homepage": "https://hex.pm/packages/certifi",
"releases": Array [
Object {
"version": "2.5.1",
},
Object {
"version": "2.4.2",
},
Object {
"version": "2.4.1",
},
Object {
"version": "2.3.1",
},
Object {
"version": "2.3.0",
},
Object {
"version": "2.2.0",
},
Object {
"version": "2.1.0",
},
Object {
"version": "2.0.0",
},
Object {
"version": "1.2.1",
},
Object {
"version": "1.2.0",
},
Object {
"version": "1.1.0",
},
Object {
"version": "1.0.0",
},
Object {
"version": "0.7.0",
},
Object {
"version": "0.6.0",
},
Object {
"version": "0.5.0",
},
Object {
"version": "0.4.0",
},
Object {
"version": "0.3.0",
},
Object {
"version": "0.2.0",
},
Object {
"version": "0.1.1",
},
],
"sourceUrl": "https://github.com/certifi/erlang-certifi",
}
`;
exports[`datasource/hex getPkgReleases processes real data 1`] = `
Object {
"homepage": "https://hex.pm/packages/certifi",
"releases": Array [
Object {
"version": "2.5.1",
},
Object {
"version": "2.4.2",
},
Object {
"version": "2.4.1",
},
Object {
"version": "2.3.1",
},
Object {
"version": "2.3.0",
},
Object {
"version": "2.2.0",
},
Object {
"version": "2.1.0",
},
Object {
"version": "2.0.0",
},
Object {
"version": "1.2.1",
},
Object {
"version": "1.2.0",
},
Object {
"version": "1.1.0",
},
Object {
"version": "1.0.0",
},
Object {
"version": "0.7.0",
},
Object {
"version": "0.6.0",
},
Object {
"version": "0.5.0",
},
Object {
"version": "0.4.0",
},
Object {
"version": "0.3.0",
},
Object {
"version": "0.2.0",
},
Object {
"version": "0.1.1",
},
],
"sourceUrl": "https://github.com/certifi/erlang-certifi",
}
`;
const fs = require('fs');
const got = require('../../lib/util/got');
const hostRules = require('../../lib/util/host-rules');
const { getPkgReleases } = require('../../lib/datasource/hex');
let res1 = fs.readFileSync('test/_fixtures/hex/certifi.json', 'utf8');
res1 = JSON.parse(res1);
jest.mock('../../lib/util/got');
jest.mock('../../lib/util/host-rules');
describe('datasource/hex', () => {
describe('getPkgReleases', () => {
beforeEach(() => {
global.repoCache = {};
});
it('returns null for empty result', async () => {
got.mockReturnValueOnce(null);
expect(
await getPkgReleases({ lookupName: 'non_existent_package' })
).toBeNull();
});
it('returns null for missing fields', async () => {
got.mockReturnValueOnce({ res: {} });
expect(
await getPkgReleases({ lookupName: 'non_existent_package' })
).toBeNull();
});
it('returns null for 404', async () => {
got.mockImplementationOnce(() =>
Promise.reject({
statusCode: 404,
})
);
expect(await getPkgReleases({ lookupName: 'some_package' })).toBeNull();
});
it('returns null for 401', async () => {
got.mockImplementationOnce(() =>
Promise.reject({
statusCode: 401,
})
);
expect(await getPkgReleases({ lookupName: 'some_package' })).toBeNull();
});
it('returns null for unknown error', async () => {
got.mockImplementationOnce(() => {
throw new Error();
});
expect(await getPkgReleases('some_package')).toBeNull();
});
it('returns null with wrong auth token', async () => {
hostRules.find.mockReturnValueOnce({ token: 'this_simple_token' });
got.mockReturnValueOnce(
Promise.reject({
statusCode: 401,
})
);
const res = await getPkgReleases({ lookupName: 'certifi' });
expect(res).toBeNull();
});
it('processes real data', async () => {
got.mockReturnValueOnce({
body: res1,
});
const res = await getPkgReleases({ lookupName: 'certifi' });
expect(res).toMatchSnapshot();
expect(res).not.toBeNull();
expect(res).toBeDefined();
});
it('process public repo without auth', async () => {
hostRules.find.mockReturnValueOnce(null);
got.mockReturnValueOnce({
body: res1,
});
const res = await getPkgReleases({ lookupName: 'certifi' });
expect(res).toMatchSnapshot();
expect(res).not.toBeNull();
expect(res).toBeDefined();
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment