UNPKG

@pnpm/git-resolver

Version:
124 lines 4.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createGitHostedPkgId = void 0; exports.createGitResolver = createGitResolver; const graceful_git_1 = __importDefault(require("graceful-git")); const semver_1 = __importDefault(require("semver")); const parseBareSpecifier_js_1 = require("./parseBareSpecifier.js"); const createGitHostedPkgId_js_1 = require("./createGitHostedPkgId.js"); Object.defineProperty(exports, "createGitHostedPkgId", { enumerable: true, get: function () { return createGitHostedPkgId_js_1.createGitHostedPkgId; } }); function createGitResolver(opts) { return async function resolveGit(wantedDependency) { const parsedSpec = await (0, parseBareSpecifier_js_1.parseBareSpecifier)(wantedDependency.bareSpecifier, opts); if (parsedSpec == null) return null; const bareSpecifier = parsedSpec.gitCommittish == null || parsedSpec.gitCommittish === '' ? 'HEAD' : parsedSpec.gitCommittish; const commit = await resolveRef(parsedSpec.fetchSpec, bareSpecifier, parsedSpec.gitRange); let resolution; if ((parsedSpec.hosted != null) && !isSsh(parsedSpec.fetchSpec)) { // don't use tarball for ssh url, they are likely private repo const hosted = parsedSpec.hosted; // use resolved committish hosted.committish = commit; const tarball = hosted.tarball?.(); if (tarball) { resolution = { tarball }; } } if (resolution == null) { resolution = { commit, repo: parsedSpec.fetchSpec, type: 'git', }; } if (parsedSpec.path) { resolution.path = parsedSpec.path; } let id; if ('tarball' in resolution) { id = resolution.tarball; if (resolution.path) { id = `${id}#path:${resolution.path}`; } } else { id = (0, createGitHostedPkgId_js_1.createGitHostedPkgId)(resolution); } return { id, normalizedBareSpecifier: parsedSpec.normalizedBareSpecifier, resolution, resolvedVia: 'git-repository', }; }; } function resolveVTags(vTags, range) { return semver_1.default.maxSatisfying(vTags, range, true); } async function getRepoRefs(repo, ref) { const gitArgs = [repo]; if (ref !== 'HEAD') { gitArgs.unshift('--refs'); } if (ref) { gitArgs.push(ref); } // graceful-git by default retries 10 times, reduce to single retry const result = await (0, graceful_git_1.default)(['ls-remote', ...gitArgs], { retries: 1 }); const refs = {}; for (const line of result.stdout.split('\n')) { const [commit, refName] = line.split('\t'); refs[refName] = commit; } return refs; } async function resolveRef(repo, ref, range) { if (ref.match(/^[0-9a-f]{7,40}$/) != null) { return ref; } const refs = await getRepoRefs(repo, range ? null : ref); return resolveRefFromRefs(refs, repo, ref, range); } function resolveRefFromRefs(refs, repo, ref, range) { if (!range) { const commitId = refs[ref] || refs[`refs/${ref}`] || refs[`refs/tags/${ref}^{}`] || // prefer annotated tags refs[`refs/tags/${ref}`] || refs[`refs/heads/${ref}`]; if (!commitId) { throw new Error(`Could not resolve ${ref} to a commit of ${repo}.`); } return commitId; } else { const vTags = Object.keys(refs) // using the same semantics of version tags as https://github.com/zkat/pacote .filter((key) => /^refs\/tags\/v?\d+\.\d+\.\d+(?:[-+].+)?(?:\^\{\})?$/.test(key)) .map((key) => { return key .replace(/^refs\/tags\//, '') .replace(/\^\{\}$/, ''); // accept annotated tags }) .filter((key) => semver_1.default.valid(key, true)); const refVTag = resolveVTags(vTags, range); const commitId = refVTag && (refs[`refs/tags/${refVTag}^{}`] || // prefer annotated tags refs[`refs/tags/${refVTag}`]); if (!commitId) { throw new Error(`Could not resolve ${range} to a commit of ${repo}. Available versions are: ${vTags.join(', ')}`); } return commitId; } } function isSsh(gitSpec) { return gitSpec.slice(0, 10) === 'git+ssh://' || gitSpec.slice(0, 4) === 'git@'; } //# sourceMappingURL=index.js.map