mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-15 10:12:44 -04:00
The git-resolver unit tests hit live github.com by default: the mocks for fetchWithDispatcher and graceful-git existed, but beforeEach restored the real implementations. When GitHub throttles the shared CI runner IPs, the HEAD probe in isRepoPublic() fails (it has zero retries and treats any error as "private"), and resolution silently degrades from the hosted tarball to a git clone, changing the resolved id and failing the assertions. This broke the main branch build at https://github.com/pnpm/pnpm/actions/runs/29026897310/job/86153736091 The mocks are now the default: fetch reports every repository as public and graceful-git serves ls-remote output from a fixture table captured from the real repositories, with the same commit hashes the assertions already expected. The private-repo-over-HTTPS test now calls mockFetchAsPrivate() explicitly instead of relying on a real 404 for the nonexistent github.com/foo/bar. The one live-network case in parsePref.test.ts got the same treatment. The suite drops from ~40s to under half a second and runs offline. The dlx e2e test stays a genuine end-to-end test against GitHub, but its allowBuild list now approves both resolution shapes of the same commit (codeload tarball and git+https clone), so the resolver's rate-limit-induced fallback no longer trips the GIT_DEP_PREPARE_NOT_ALLOWED gate, as seen in https://github.com/pnpm/pnpm/actions/runs/29029971938/job/86170695840 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
84 lines
5.0 KiB
TypeScript
84 lines
5.0 KiB
TypeScript
import { expect, jest, test } from '@jest/globals'
|
|
|
|
jest.unstable_mockModule('@pnpm/network.fetch', () => ({
|
|
fetchWithDispatcher: jest.fn(async () => ({ ok: true })),
|
|
}))
|
|
jest.unstable_mockModule('graceful-git', () => ({
|
|
gracefulGit: jest.fn(async () => ({ stdout: '' })),
|
|
}))
|
|
const { parseBareSpecifier } = await import('../lib/parseBareSpecifier.js')
|
|
|
|
test.each([
|
|
['ssh://username:password@example.com:repo.git', 'ssh://username:password@example.com/repo.git'],
|
|
['ssh://username:password@example.com:repo/@foo.git', 'ssh://username:password@example.com/repo/@foo.git'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
['ssh://username:password@example.com:22repo/@foo.git', 'ssh://username:password@example.com/22repo/@foo.git'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b&dev', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
['git+ssh://username:password@example.com:repo.git', 'ssh://username:password@example.com/repo.git'],
|
|
['git+ssh://username:password@example.com:repo/@foo.git', 'ssh://username:password@example.com/repo/@foo.git'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b&dev', 'ssh://username:password@example.com:22/repo/@foo.git'],
|
|
])('the right colon is escaped in %s', async (input, output) => {
|
|
const parsed = await parseBareSpecifier(input, {})?.()
|
|
expect(parsed?.fetchSpec).toBe(output)
|
|
})
|
|
|
|
test.each([
|
|
['ssh://username:password@example.com:repo.git#path:/a/@b', '/a/@b'],
|
|
['ssh://username:password@example.com:repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['ssh://username:password@example.com:22repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b&dev', '/a/@b'],
|
|
['git+ssh://username:password@example.com:repo.git#path:/a/@b', '/a/@b'],
|
|
['git+ssh://username:password@example.com:repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', '/a/@b'],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b&dev', '/a/@b'],
|
|
['ssh://username:password@example.com:repo.git', undefined],
|
|
['ssh://username:password@example.com:repo/@foo.git', undefined],
|
|
['ssh://username:password@example.com:22/repo/@foo.git', undefined],
|
|
['ssh://username:password@example.com:22repo/@foo.git', undefined],
|
|
['ssh://username:password@example.com:22/repo/@foo.git', undefined],
|
|
['ssh://username:password@example.com:22/repo/@foo.git#dev', undefined],
|
|
['git+ssh://username:password@example.com:repo.git', undefined],
|
|
['git+ssh://username:password@example.com:repo/@foo.git', undefined],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git', undefined],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git', undefined],
|
|
['git+ssh://username:password@example.com:22/repo/@foo.git#dev', undefined],
|
|
])('the path of %s should be %s', async (input, output) => {
|
|
const parsed = await parseBareSpecifier(input, {})?.()
|
|
expect(parsed?.path).toBe(output)
|
|
})
|
|
|
|
test.each([
|
|
['git+https://github.com/pnpm/pnpm.git', 'https://github.com/pnpm/pnpm.git'],
|
|
['git+ssh://git@sub.domain.tld:internal-app/sub-path/service-name.git', 'ssh://git@sub.domain.tld/internal-app/sub-path/service-name.git'],
|
|
])('the fetchSpec of %s should be %s', async (input, output) => {
|
|
const parsed = await parseBareSpecifier(input, {})?.()
|
|
expect(parsed?.fetchSpec).toBe(output)
|
|
})
|
|
|
|
// Test for https:// URLs ending in .git (issue #10468)
|
|
test.each([
|
|
['https://gitea.osmocom.org/ttcn3/highlightjs-ttcn3.git', 'https://gitea.osmocom.org/ttcn3/highlightjs-ttcn3.git'],
|
|
['https://gitea.osmocom.org/ttcn3/highlightjs-ttcn3.git#6daccff309fca1e7561a43984d42fa4f829ce06d', 'https://gitea.osmocom.org/ttcn3/highlightjs-ttcn3.git'],
|
|
['http://example.com/repo.git', 'http://example.com/repo.git'],
|
|
['http://example.com/repo.git#main', 'http://example.com/repo.git'],
|
|
])('plain http/https URLs ending in .git should be recognized: %s', async (input, output) => {
|
|
const parsed = await parseBareSpecifier(input, {})?.()
|
|
expect(parsed?.fetchSpec).toBe(output)
|
|
})
|
|
|
|
// Ensure non-.git https URLs are not recognized as git repos
|
|
test.each([
|
|
['https://example.com/package.tar.gz'],
|
|
['https://example.com/package.tgz'],
|
|
['https://example.com/file'],
|
|
])('plain http/https URLs not ending in .git should not be recognized: %s', async (input) => {
|
|
const parsed = parseBareSpecifier(input, {})
|
|
expect(parsed).toBeNull()
|
|
})
|