UNPKG

@pnpm/git-resolver

Version:
111 lines 4.21 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const graceful_git_1 = __importDefault(require("graceful-git")); const semver_1 = __importDefault(require("semver")); const parsePref_1 = __importDefault(require("./parsePref")); function default_1(opts) { return async function resolveGit(wantedDependency) { const parsedSpec = await (0, parsePref_1.default)(wantedDependency.pref); if (parsedSpec == null) return null; const pref = parsedSpec.gitCommittish == null || parsedSpec.gitCommittish === '' ? 'HEAD' : parsedSpec.gitCommittish; const commit = await resolveRef(parsedSpec.fetchSpec, pref, 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', }; } return { id: parsedSpec.fetchSpec .replace(/^.*:\/\/(git@)?/, '') .replace(/:/g, '+') .replace(/\.git$/, '') + '/' + commit, normalizedPref: parsedSpec.normalizedPref, resolution, resolvedVia: 'git-repository', }; }; } exports.default = default_1; 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 = result.stdout.split('\n').reduce((obj, line) => { const [commit, refName] = line.split('\t'); obj[refName] = commit; return obj; }, {}); 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