Skip to content

Commit 3d26c6c

Browse files
committed
fix: additional comments
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
1 parent 8a4985e commit 3d26c6c

3 files changed

Lines changed: 69 additions & 8 deletions

File tree

services/apps/packages_worker/src/maven/__tests__/normalize.test.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ describe('parseRepoUrl', () => {
119119
const result = parseRepoUrl('https://github.com/')
120120
expect(result).toEqual({ host: 'github', owner: null, name: null })
121121
})
122+
123+
// The canonical OpenDaylight link keeps repo identity in ?p=, not the (fixed)
124+
// pathname — a generic parts[0]/parts[1] split would collapse every OpenDaylight
125+
// repo to the same owner='gerrit', name='gitweb'.
126+
it('derives owner=null and name from the ?p= query for OpenDaylight Gerrit links', () => {
127+
expect(parseRepoUrl('https://git.opendaylight.org/gerrit/gitweb?p=netconf.git')).toEqual({
128+
host: 'gerrit',
129+
owner: null,
130+
name: 'netconf',
131+
})
132+
expect(parseRepoUrl('https://git.opendaylight.org/gerrit/gitweb?p=aaa.git')).toEqual({
133+
host: 'gerrit',
134+
owner: null,
135+
name: 'aaa',
136+
})
137+
})
122138
})
123139

124140
describe('normalizeScmUrl', () => {
@@ -206,6 +222,17 @@ describe('normalizeScmUrl', () => {
206222
expect(normalizeScmUrl('https://svn.apache.org/repos/asf')).toBeNull()
207223
})
208224

225+
// java.net requires an explicit SVN marker because the bare host is shared with
226+
// non-SVN content (forums, wikis, JIRA) — this must not accidentally widen to
227+
// treat every java.net URL as SVN.
228+
it('treats java.net as SVN only with an explicit scm:svn:/svn:// marker', () => {
229+
expect(normalizeScmUrl('https://java.net/projects/foo/sources/svn')).toBeNull()
230+
expect(normalizeScmUrl('scm:svn:https://java.net/svn/foo/trunk')).toBe(
231+
'https://java.net/svn/foo',
232+
)
233+
expect(normalizeScmUrl('svn://java.net/svn/foo/trunk')).toBe('https://java.net/svn/foo')
234+
})
235+
209236
it('does not map dead services that incidentally match an "svn" text filter', () => {
210237
expect(normalizeScmUrl('http://specs.googlecode.com/svn/trunk')).toBeNull()
211238
})
@@ -408,6 +435,21 @@ describe('normalizeScmUrl', () => {
408435
expect(normalizeScmUrl('https://android.googlesource.com/')).toBeNull()
409436
})
410437

438+
// cs.android.com is the Android Code Search UI, backed by the same Gitiles
439+
// repos as android.googlesource.com — same identity passthrough applies.
440+
it('passes through cs.android.com urls unchanged, mirroring the googlesource identity form', () => {
441+
expect(normalizeScmUrl('https://cs.android.com/androidx/platform/frameworks/support')).toBe(
442+
'https://cs.android.com/androidx/platform/frameworks/support',
443+
)
444+
})
445+
446+
it('returns null for a bare OpenDaylight Gerrit root with no repo path', () => {
447+
// /gerrit/ alone (as opposed to /gerrit/gitweb?p=...) has nothing to extract —
448+
// same "no derivable identity" case as the bare gerrit.onosproject.org root
449+
// tested above, confirmed against real declared_repository_url values.
450+
expect(normalizeScmUrl('https://git.opendaylight.org/gerrit/')).toBeNull()
451+
})
452+
411453
it('recovers GitHub Pages project-page urls (owner.github.io/repo)', () => {
412454
expect(normalizeScmUrl('https://silentbalanceyh.github.io/vertx-zero/')).toBe(
413455
'https://github.com/silentbalanceyh/vertx-zero',
@@ -594,9 +636,7 @@ describe('normalizeScmUrl', () => {
594636

595637
it('returns null for non-SCM OpenDaylight URLs instead of mistaking them for a repo', () => {
596638
// A `p` query on some unrelated path is not a gitweb browse link.
597-
expect(
598-
normalizeScmUrl('https://git.opendaylight.org/somewhere?p=netconf.git'),
599-
).toBeNull()
639+
expect(normalizeScmUrl('https://git.opendaylight.org/somewhere?p=netconf.git')).toBeNull()
600640
// Single path segment with no .git suffix — e.g. a static asset, not a clone URL.
601641
expect(normalizeScmUrl('https://git.opendaylight.org/favicon.ico')).toBeNull()
602642
})

services/apps/packages_worker/src/maven/extract.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,13 +487,18 @@ export async function extractArtifact(groupId: string, artifactId: string, versi
487487
* declared_repository_url that need more than a flat owner/repo allowlist are handled
488488
* by their own dedicated normalizers below rather than here:
489489
* - git.eclipse.org: cgit `/c/<owner>/<repo>` paths → normalizeEclipseCgitUrl.
490-
* - android.googlesource.com: Gitiles identity paths → normalizeGooglesourceUrl.
490+
* - android.googlesource.com / cs.android.com: Gitiles identity paths (the Android
491+
* Code Search UI mirrors the same repo naming as the Gitiles source itself) →
492+
* normalizeGooglesourceUrl.
491493
* - ec.europa.eu: Bitbucket-Server `/projects/x/repos/y` → normalizeBitbucketServerUrl.
492494
* - gitbox.apache.org / git.apache.org / git-wip-us.apache.org: gitweb
493495
* `/repos/asf/<repo>` or `?p=<repo>` → normalizeApacheGitwebUrl.
494496
*
495497
* Still NOT handled (need more than a host allowlist, or are unreachable):
496498
* - eclipse.gerrithub.io: Gerrit admin-UI paths (`/admin/repos/...`), not a clone shape.
499+
* - gerrit.onosproject.org: every occurrence observed is the bare Gerrit root
500+
* (`http://gerrit.onosproject.org/`) with no path at all — nothing to extract,
501+
* unlike git.opendaylight.org which has resolvable gitweb/SSH forms.
497502
*
498503
* Internal-only hosts (git.corp.adobe.com, fit.corp.adobe.com, gitlab.alibaba-inc.com)
499504
* are included below even though they're unreachable for external consumers — per
@@ -764,8 +769,12 @@ function normalizeAliyunCodeupUrl(host: string, pathname: string): string | null
764769
* Android's Gerrit/Gitiles mirror already uses its full path as the canonical,
765770
* resolvable repo name (e.g. /platform/tools/base) — nested repo naming is normal
766771
* here, so this is an identity passthrough rather than an owner/repo split.
772+
*
773+
* cs.android.com (Android Code Search) is included too: it's a browsing UI over
774+
* the same Gitiles-backed repos and mirrors the identical path naming (e.g.
775+
* /androidx/platform/frameworks/support) — same passthrough applies.
767776
*/
768-
const GOOGLESOURCE_IDENTITY_HOSTS = new Set(['android.googlesource.com'])
777+
const GOOGLESOURCE_IDENTITY_HOSTS = new Set(['android.googlesource.com', 'cs.android.com'])
769778

770779
function normalizeGooglesourceUrl(host: string, pathname: string): string | null {
771780
const path = pathname.replace(/\/+$/, '').replace(/\.git$/, '')
@@ -782,12 +791,14 @@ function normalizeGooglesourceUrl(host: string, pathname: string): string | null
782791
* Both are unified to the gitweb browse form so the stored link is always
783792
* resolvable in a browser, not just via `git clone`.
784793
*/
785-
const OPENDALIGHT_GERRIT_HOST = 'git.opendaylight.org'
794+
export const OPENDALIGHT_GERRIT_HOST = 'git.opendaylight.org'
795+
export const OPENDALIGHT_GERRIT_GITWEB_PATH = '/gerrit/gitweb'
786796

787797
function normalizeOpendaylightGerritUrl(pathname: string, search: string): string | null {
788798
// Query extraction only applies to the actual gitweb browse script — a `p` query
789799
// on some unrelated path isn't a repo reference.
790-
const queryRepo = pathname === '/gerrit/gitweb' ? new URLSearchParams(search).get('p') : null
800+
const queryRepo =
801+
pathname === OPENDALIGHT_GERRIT_GITWEB_PATH ? new URLSearchParams(search).get('p') : null
791802
const segments = pathname.split('/').filter(Boolean)
792803
// The one-segment SSH-clone form must end in .git, otherwise any arbitrary
793804
// single-segment path (e.g. /favicon.ico) would be mistaken for a repo.

services/apps/packages_worker/src/maven/normalize.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isSvnHost } from './extract'
1+
import { OPENDALIGHT_GERRIT_GITWEB_PATH, OPENDALIGHT_GERRIT_HOST, isSvnHost } from './extract'
22

33
export function isPrerelease(version: string): boolean {
44
return /-(SNAPSHOT|alpha|beta|rc|cr|m\d+|dev)/i.test(version)
@@ -18,6 +18,16 @@ export function parseRepoUrl(
1818
// name='asf'). Keep the whole path as `name` instead.
1919
if (isSvnHost(h)) return { host: 'svn', owner: null, name: parts.join('/') || null }
2020

21+
// OpenDaylight's canonical link keeps the actual repo identity only in the
22+
// ?p= query — the pathname is always the fixed /gerrit/gitweb script, so a
23+
// generic parts[0]/parts[1] split would store owner='gerrit', name='gitweb'
24+
// for every single OpenDaylight repo, indistinguishable from one another.
25+
if (h === OPENDALIGHT_GERRIT_HOST && parsed.pathname === OPENDALIGHT_GERRIT_GITWEB_PATH) {
26+
const p = parsed.searchParams.get('p')
27+
const name = p ? p.replace(/\.git$/, '') : null
28+
return { host: 'gerrit', owner: null, name }
29+
}
30+
2131
let host: string
2232
if (h === 'github.com' || h.endsWith('.github.com')) host = 'github'
2333
else if (h === 'gitlab.com' || h.includes('gitlab')) host = 'gitlab'

0 commit comments

Comments
 (0)