Skip to content
Snippets Groups Projects
Unverified Commit f18ea2fa authored by Trim21's avatar Trim21 Committed by GitHub
Browse files

feat(pypi): search sourceUrl in project_urls (#6418)

parent 046f7245
No related branches found
No related tags found
No related merge requests found
...@@ -92,6 +92,7 @@ Object { ...@@ -92,6 +92,7 @@ Object {
exports[`datasource/pypi getReleases processes real data 1`] = ` exports[`datasource/pypi getReleases processes real data 1`] = `
Object { Object {
"homepage": "https://github.com/Azure/azure-cli",
"releases": Array [ "releases": Array [
Object { Object {
"releaseTimestamp": "2017-04-03T16:55:14", "releaseTimestamp": "2017-04-03T16:55:14",
...@@ -205,6 +206,14 @@ Object { ...@@ -205,6 +206,14 @@ Object {
} }
`; `;
exports[`datasource/pypi getReleases return sourceUrl in project_urls 1`] = `
Object {
"homepage": "https://flexget.com",
"releases": Array [],
"sourceUrl": "https://github.com/Flexget/Flexget",
}
`;
exports[`datasource/pypi getReleases returns non-github home_page 1`] = ` exports[`datasource/pypi getReleases returns non-github home_page 1`] = `
Object { Object {
"homepage": "https://microsoft.com", "homepage": "https://microsoft.com",
......
...@@ -122,6 +122,27 @@ describe('datasource/pypi', () => { ...@@ -122,6 +122,27 @@ describe('datasource/pypi', () => {
}) })
).toMatchSnapshot(); ).toMatchSnapshot();
}); });
it('return sourceUrl in project_urls', async () => {
got.mockReturnValueOnce({
body: {
info: {
name: 'flexget',
home_page: 'https://flexget.com',
project_urls: {
Forum: 'https://discuss.flexget.com',
Homepage: 'https://flexget.com',
'Issue Tracker': 'https://github.com/Flexget/Flexget/issues',
Repository: 'https://github.com/Flexget/Flexget',
},
},
},
});
const result = await pypi.getReleases({
lookupName: 'flexget',
});
expect(result.sourceUrl).toBe('https://github.com/Flexget/Flexget');
expect(result).toMatchSnapshot();
});
it('returns null if mismatched name', async () => { it('returns null if mismatched name', async () => {
got.mockReturnValueOnce({ got.mockReturnValueOnce({
body: { body: {
......
...@@ -8,15 +8,29 @@ import * as pep440 from '../../versioning/pep440'; ...@@ -8,15 +8,29 @@ import * as pep440 from '../../versioning/pep440';
import { GetReleasesConfig, ReleaseResult } from '../common'; import { GetReleasesConfig, ReleaseResult } from '../common';
export const id = 'pypi'; export const id = 'pypi';
const github_repo_pattern = /^https?:\/\/github\.com\/[^\\/]+\/[^\\/]+$/;
const http = new Http(id); const http = new Http(id);
type Releases = Record<
string,
{ requires_python?: boolean; upload_time?: string }[]
>;
type PypiJSON = {
info: {
name: string;
home_page?: string;
project_urls?: Record<string, string>;
};
releases?: Releases;
};
function normalizeName(input: string): string { function normalizeName(input: string): string {
return input.toLowerCase().replace(/(-|\.)/g, '_'); return input.toLowerCase().replace(/(-|\.)/g, '_');
} }
function compatibleVersions( function compatibleVersions(
releases: Record<string, { requires_python?: boolean }[]>, releases: Releases,
compatibility: Record<string, string> compatibility: Record<string, string>
): string[] { ): string[] {
const versions = Object.keys(releases); const versions = Object.keys(releases);
...@@ -42,8 +56,7 @@ async function getDependency( ...@@ -42,8 +56,7 @@ async function getDependency(
const lookupUrl = url.resolve(hostUrl, `${packageName}/json`); const lookupUrl = url.resolve(hostUrl, `${packageName}/json`);
const dependency: ReleaseResult = { releases: null }; const dependency: ReleaseResult = { releases: null };
logger.trace({ lookupUrl }, 'Pypi api got lookup'); logger.trace({ lookupUrl }, 'Pypi api got lookup');
// TODO: fix type const rep = await http.getJson<PypiJSON>(lookupUrl);
const rep = await http.getJson<any>(lookupUrl);
const dep = rep && rep.body; const dep = rep && rep.body;
if (!dep) { if (!dep) {
logger.trace({ dependency: packageName }, 'pip package not found'); logger.trace({ dependency: packageName }, 'pip package not found');
...@@ -59,16 +72,31 @@ async function getDependency( ...@@ -59,16 +72,31 @@ async function getDependency(
); );
return null; return null;
} }
if (dep.info && dep.info.home_page) {
if (dep.info.home_page.match(/^https?:\/\/github.com/)) { if (dep.info?.home_page) {
dependency.homepage = dep.info.home_page;
if (github_repo_pattern.exec(dep.info.home_page)) {
dependency.sourceUrl = dep.info.home_page.replace( dependency.sourceUrl = dep.info.home_page.replace(
'http://', 'http://',
'https://' 'https://'
); );
} else {
dependency.homepage = dep.info.home_page;
} }
} }
if (dep.info?.project_urls && !dependency.sourceUrl) {
for (const [name, projectUrl] of Object.entries(dep.info.project_urls)) {
const lower = name.toLowerCase();
if (
lower.startsWith('repo') ||
lower === 'code' ||
github_repo_pattern.exec(projectUrl)
) {
dependency.sourceUrl = projectUrl;
break;
}
}
}
dependency.releases = []; dependency.releases = [];
if (dep.releases) { if (dep.releases) {
const versions = compatibleVersions(dep.releases, compatibility); const versions = compatibleVersions(dep.releases, compatibility);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment