diff --git a/docs/usage/getting-started/private-packages.md b/docs/usage/getting-started/private-packages.md index 7955afb019aa13f41d3153fa17d0c9f8093102e6..0dfa4e59d7afd85f2deb7f05250266fe52d730cf 100644 --- a/docs/usage/getting-started/private-packages.md +++ b/docs/usage/getting-started/private-packages.md @@ -140,7 +140,7 @@ module.exports = { hostRules: [ { matchHost: 'your.host.io', - hostType: 'helm' + hostType: 'helm', username: '<your-username>', password: process.env.SELF_HOSTED_HELM_CHARTS_PASSWORD, }, diff --git a/lib/modules/datasource/dart/__fixtures__/shared_preferences.json b/lib/modules/datasource/dart/__fixtures__/shared_preferences.json index 778084c4467ab4cfaca33048d193a358e69b7a43..9f276952a402ee2a27155aa6c65ab2324eda23c4 100644 --- a/lib/modules/datasource/dart/__fixtures__/shared_preferences.json +++ b/lib/modules/datasource/dart/__fixtures__/shared_preferences.json @@ -6,7 +6,7 @@ "name": "shared_preferences", "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences", - "repository": "http://example.com", + "repository": "https://github.com/flutter/plugins", "version": "0.5.8", "flutter": { "plugin": { diff --git a/lib/modules/datasource/dart/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/dart/__snapshots__/index.spec.ts.snap index 636f7140a801465e13ec8986ff0331b720bb9631..63f14b0018e2bb75c2e9765150197c53855f99b3 100644 --- a/lib/modules/datasource/dart/__snapshots__/index.spec.ts.snap +++ b/lib/modules/datasource/dart/__snapshots__/index.spec.ts.snap @@ -2,6 +2,7 @@ exports[`modules/datasource/dart/index getReleases processes real data 1`] = ` { + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences", "registryUrl": "https://pub.dartlang.org/", "releases": [ { @@ -181,6 +182,6 @@ exports[`modules/datasource/dart/index getReleases processes real data 1`] = ` "version": "0.5.8", }, ], - "sourceUrl": "http://example.com", + "sourceUrl": "https://github.com/flutter/plugins", } `; diff --git a/lib/modules/datasource/metadata.spec.ts b/lib/modules/datasource/metadata.spec.ts index c07d5df1fc07173e5405e635744aa5eca4ca7346..5b1b1485737022a9fb0e366779590708b23f12d4 100644 --- a/lib/modules/datasource/metadata.spec.ts +++ b/lib/modules/datasource/metadata.spec.ts @@ -1,5 +1,9 @@ import { MavenDatasource } from './maven'; -import { addMetaData, massageGithubUrl } from './metadata'; +import { + addMetaData, + massageGithubUrl, + shouldDeleteHomepage, +} from './metadata'; import { NpmDatasource } from './npm'; import { PypiDatasource } from './pypi'; import type { ReleaseResult } from './types'; @@ -256,4 +260,141 @@ describe('modules/datasource/metadata', () => { 'https://example.com/foo/bar' ); }); + + it('Should remove homepage when homepage and sourceUrl are same', () => { + const dep = { + homepage: 'https://github.com/foo/bar', + sourceUrl: 'https://github.com/foo/bar', + releases: [ + { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, + { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, + { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + ], + }; + addMetaData(dep, MavenDatasource.id, 'foobar'); + expect(dep).toMatchObject({ + releases: [ + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56.000Z', + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z', + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T12:34:56.000Z', + }, + ], + sourceUrl: 'https://github.com/foo/bar', + }); + }); + + it('Should delete gitlab homepage if its same as sourceUrl', () => { + const dep = { + sourceUrl: 'https://gitlab.com/meno/repo', + homepage: 'https://gitlab.com/meno/repo', + releases: [ + { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, + { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, + { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + ], + }; + addMetaData(dep, MavenDatasource.id, 'foobar'); + expect(dep).toMatchObject({ + sourceUrl: 'https://gitlab.com/meno/repo', + releases: [ + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56.000Z', + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z', + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T12:34:56.000Z', + }, + ], + }); + }); + + it('does not set homepage to sourceURl when undefined', () => { + const dep = { + sourceUrl: 'https://gitlab.com/meno/repo', + releases: [ + { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, + { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, + { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + ], + }; + addMetaData(dep, MavenDatasource.id, 'foobar'); + expect(dep).toMatchObject({ + sourceUrl: 'https://gitlab.com/meno/repo', + releases: [ + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56.000Z', + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z', + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T12:34:56.000Z', + }, + ], + }); + }); + + it('does not set homepage to sourceURl when not github or gitlab', () => { + const dep = { + homepage: 'https://somesource.com/', + releases: [ + { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, + { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, + { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + ], + }; + addMetaData(dep, MavenDatasource.id, 'foobar'); + expect(dep).toMatchObject({ + homepage: 'https://somesource.com/', + releases: [ + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56.000Z', + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z', + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T12:34:56.000Z', + }, + ], + }); + }); + + test.each` + sourceUrl | homepage | expected + ${'not a url'} | ${'https://gitlab.com/org/repo'} | ${false} + ${'https://gitlab.com/org/repo'} | ${'not a url'} | ${false} + ${'https://gitlab.com/org'} | ${'https://gitlab.com/org/'} | ${true} + ${'https://gitlab.com/org/repo/'} | ${'https://gitlab.com/org/repo'} | ${true} + ${'https://github.com/org/repo/path/'} | ${'https://github.com/org/repo/path/'} | ${false} + ${'https://gitlab.com/org/repo/'} | ${'https://gitlab.com/org/repo/path/to/something/'} | ${false} + ${'https://gitlab.com/org/repo/'} | ${null} | ${false} + ${'https://gitlab.com/org/repo/'} | ${undefined} | ${false} + ${'https://gitlab.com/org/repo/'} | ${'github.com'} | ${false} + ${'https://github.com/bitnami/charts'} | ${'https://github.com/bitnami/charts/tree/master/bitnami/kube-prometheus'} | ${false} + `( + 'shouldDeleteHomepage($sourceUrl, $homepage) -> $expected', + ({ sourceUrl, homepage, expected }) => { + expect(shouldDeleteHomepage(sourceUrl, homepage)).toBe(expected); + } + ); }); diff --git a/lib/modules/datasource/metadata.ts b/lib/modules/datasource/metadata.ts index 1503f4ba6e110c644ae22f801a26fd464d9c8b92..80694b77dfcd95a887173e00032e13fb440d3bdf 100644 --- a/lib/modules/datasource/metadata.ts +++ b/lib/modules/datasource/metadata.ts @@ -2,9 +2,10 @@ import URL from 'url'; import is from '@sindresorhus/is'; import parse from 'github-url-from-git'; import { DateTime } from 'luxon'; +import { detectPlatform } from '../../util/common'; import * as hostRules from '../../util/host-rules'; import { regEx } from '../../util/regex'; -import { parseUrl, validateUrl } from '../../util/url'; +import { parseUrl, trimTrailingSlash, validateUrl } from '../../util/url'; import { manualChangelogUrls, manualSourceUrls } from './metadata-manual'; import type { ReleaseResult } from './types'; @@ -120,19 +121,17 @@ export function addMetaData( } if ( - dep.changelogUrl?.includes('github.com') && // lgtm [js/incomplete-url-substring-sanitization] - !dep.sourceUrl + !dep.sourceUrl && + dep.changelogUrl && + detectPlatform(dep.changelogUrl) === 'github' ) { dep.sourceUrl = dep.changelogUrl; } - if (dep.homepage) { - const parsedHomePage = parseUrl(dep.homepage); - if (parsedHomePage?.hostname.includes('github')) { - if (!dep.sourceUrl) { - dep.sourceUrl = dep.homepage; - } - delete dep.homepage; + if (!dep.sourceUrl && dep.homepage) { + const platform = detectPlatform(dep.homepage); + if (platform === 'github' || platform === 'gitlab') { + dep.sourceUrl = dep.homepage; } } const extraBaseUrls = []; @@ -153,7 +152,9 @@ export function addMetaData( }) || dep.sourceUrl; } } - + if (shouldDeleteHomepage(dep.sourceUrl, dep.homepage)) { + delete dep.homepage; + } // Clean up any empty urls const urlKeys: (keyof ReleaseResult)[] = [ 'homepage', @@ -170,3 +171,34 @@ export function addMetaData( } } } + +/** + * Returns true if + * 1. it's a github or gitlab url and not a path within the repo. + * 2. it's equal to sourceURl + * @param sourceUrl + * @param homepage + */ +export function shouldDeleteHomepage( + sourceUrl: string | null | undefined, + homepage: string | undefined +): boolean { + if (is.nullOrUndefined(sourceUrl) || is.undefined(homepage)) { + return false; + } + const massagedSourceUrl = massageUrl(sourceUrl); + const platform = detectPlatform(homepage); + if (platform === 'github' || platform === 'gitlab') { + const sourceUrlParsed = parseUrl(massagedSourceUrl); + if (is.nullOrUndefined(sourceUrlParsed)) { + return false; + } + const homepageParsed = parseUrl(homepage); + return ( + homepageParsed !== null && + trimTrailingSlash(homepageParsed.pathname) === + trimTrailingSlash(sourceUrlParsed.pathname) + ); + } + return massagedSourceUrl === homepage; +} diff --git a/lib/modules/datasource/nuget/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/nuget/__snapshots__/index.spec.ts.snap index 04e7ce01a9d08fe6231957344a0a6b0ede0773fe..bdbf086ec83c9ad03075a2b41206bed99a671279 100644 --- a/lib/modules/datasource/nuget/__snapshots__/index.spec.ts.snap +++ b/lib/modules/datasource/nuget/__snapshots__/index.spec.ts.snap @@ -396,7 +396,6 @@ exports[`modules/datasource/nuget/index getReleases processes real data (v3) fee exports[`modules/datasource/nuget/index getReleases processes real data (v3) feed is not a nuget.org 1`] = ` { - "homepage": "https://nunit.org/", "registryUrl": "https://myprivatefeed/index.json", "releases": [ {