Skip to content

Commit 7ee23c3

Browse files
committedNov 11, 2019
git: make 'from' and 'resolved' consistent and useful
- Always track a 'from' value for hosted git urls as the shortcut. - Always track a 'resolved' for hosted git urls as the sshurl (even when we can actually fetch a rendered tarball, because we have the full sha.) This makes 'from' and 'resolved' suitable to track and compare in lockfiles and dependency lists. Part 1 of fix for #15
1 parent 10ff45f commit 7ee23c3

File tree

2 files changed

+74
-56
lines changed

2 files changed

+74
-56
lines changed
 

‎lib/git.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,23 @@ const _prepareDir = Symbol('_prepareDir')
2323

2424
// get the repository url. prefer ssh, fall back to git://
2525
const repoUrl = (hosted, opts) =>
26-
hosted.ssh && hosted.ssh(opts) ||
26+
hosted.sshurl && hosted.sshurl(opts) ||
2727
hosted.git && hosted.git(opts)
2828

2929
class GitFetcher extends Fetcher {
3030
constructor (spec, opts) {
3131
super(spec, opts)
3232
this.resolvedRef = null
33+
if (this.spec.hosted)
34+
this.from = this.spec.hosted.shortcut({ noCommittish: false })
35+
3336
// shortcut: avoid full clone when we can go straight to the tgz
3437
// if we have the full sha and it's a hosted git platform
3538
if (this.spec.gitCommittish && hashre.test(this.spec.gitCommittish)) {
3639
this.resolvedSha = this.spec.gitCommittish
37-
// use hosted.tarball() and then later shell to RemoteFetcher
40+
// use hosted.tarball() when we shell to RemoteFetcher later
3841
this.resolved = this.spec.hosted
39-
? this.spec.hosted.tarball({ noCommittish: false })
42+
? repoUrl(this.spec.hosted, { noCommittish: false })
4043
: this.spec.fetchSpec + '#' + this.spec.gitCommittish
4144
} else
4245
this.resolvedSha = ''
@@ -92,7 +95,7 @@ class GitFetcher extends Fetcher {
9295
// we haven't cloned, so a tgz download is still faster
9396
// of course, if it's not a known host, we can't do that.
9497
this.resolved = !this.spec.hosted ? withSha
95-
: npa(withSha).hosted.tarball({ noCommittish: false })
98+
: repoUrl(npa(withSha).hosted, { noCommittish: false })
9699
}
97100

98101
// when we get the git sha, we affix it to our spec to build up
@@ -178,10 +181,10 @@ class GitFetcher extends Fetcher {
178181
const resolved = this.resolved
179182

180183
return cacache.tmp.withTmp(this.cache, o, tmp => {
181-
// if we're resolved, and it's a tarball url, shell out to RemoteFetcher
182-
if (h && resolved === h.tarball({ noCommittish: false })) {
184+
// if we're resolved, and have a tarball url, shell out to RemoteFetcher
185+
if (h && resolved === repoUrl(h, { noCommittish: false }) && h.tarball) {
183186
const nameat = this.spec.name ? `${this.spec.name}@` : ''
184-
return new RemoteFetcher(this.resolved, {
187+
return new RemoteFetcher(h.tarball({ noCommittish: false }), {
185188
...this.opts,
186189
pkgid: `git:${nameat}${this.resolved}`,
187190
resolved: this.resolved,
@@ -213,8 +216,9 @@ class GitFetcher extends Fetcher {
213216
readPackageJson(dir + '/package.json')
214217
.then(mani => this.package = {
215218
...mani,
216-
_integrity: String(this.integrity),
219+
_integrity: this.integrity && String(this.integrity),
217220
_resolved: this.resolved,
221+
_from: this.from,
218222
}))
219223
}
220224

‎test/git.js

+62-48
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ t.test('weird hosted that doesnt provide .git()', t => {
292292
spec.hosted = {
293293
git () { return null },
294294
tarball () { return null },
295+
shortcut () { return `weird:${remote}` },
295296
}
296297
const r = new GitFetcher(spec, {cache})
297298
return t.rejects(r.resolve(), {
@@ -300,66 +301,79 @@ t.test('weird hosted that doesnt provide .git()', t => {
300301
})
301302

302303
t.test('extract from tarball from hosted git service', t => {
303-
const spec = npa(`repo@localhost:repo/x#${REPO_HEAD}`)
304-
const g = new GitFetcher(spec, {cache})
305-
return g.manifest().then(m => t.match(m, {
306-
name: 'repo',
307-
version: '1.0.0',
308-
description: 'just some random thing',
309-
devDependencies: {
310-
abbrev: abbrevSpec
311-
},
312-
scripts: { prepare: 'node prepare.js', test: 'node index.js' },
313-
files: [ 'index.js' ],
314-
readme: 'some docs and some more docs',
315-
readmeFilename: 'README.md',
316-
_id: 'repo@1.0.0',
317-
_integrity: /^sha512-/,
318-
_resolved: `${hostedUrl}/repo-HEAD.tgz`,
319-
}))
320-
.then(() => g.packument())
321-
.then(p => t.match(p, {
322-
name: 'repo',
323-
'dist-tags': { latest: '1.0.0' },
324-
versions: {
325-
'1.0.0': {
326-
name: 'repo',
327-
version: '1.0.0',
328-
description: 'just some random thing',
329-
devDependencies: {
330-
abbrev: abbrevSpec,
331-
},
332-
scripts: { prepare: 'node prepare.js', test: 'node index.js' },
333-
files: [ 'index.js' ],
334-
readme: 'some docs and some more docs',
335-
readmeFilename: 'README.md',
336-
_id: 'repo@1.0.0',
337-
_integrity: /^sha512-/,
338-
_resolved: `${hostedUrl}/repo-HEAD.tgz`,
339-
dist: {},
304+
const runTest = nameat => t => {
305+
const spec = npa(`${nameat}localhost:repo/x#${REPO_HEAD}`)
306+
const g = new GitFetcher(spec, {cache})
307+
return g.manifest().then(m => t.match(m, {
308+
name: 'repo',
309+
version: '1.0.0',
310+
description: 'just some random thing',
311+
devDependencies: {
312+
abbrev: abbrevSpec
313+
},
314+
scripts: { prepare: 'node prepare.js', test: 'node index.js' },
315+
files: [ 'index.js' ],
316+
readme: 'some docs and some more docs',
317+
readmeFilename: 'README.md',
318+
_id: 'repo@1.0.0',
319+
_integrity: /^sha512-/,
320+
_resolved: `${remoteHosted}#${REPO_HEAD}`,
321+
}))
322+
.then(() => g.packument())
323+
.then(p => t.match(p, {
324+
name: 'repo',
325+
'dist-tags': { latest: '1.0.0' },
326+
versions: {
327+
'1.0.0': {
328+
name: 'repo',
329+
version: '1.0.0',
330+
description: 'just some random thing',
331+
devDependencies: {
332+
abbrev: abbrevSpec,
333+
},
334+
scripts: { prepare: 'node prepare.js', test: 'node index.js' },
335+
files: [ 'index.js' ],
336+
readme: 'some docs and some more docs',
337+
readmeFilename: 'README.md',
338+
_id: 'repo@1.0.0',
339+
_integrity: /^sha512-/,
340+
_resolved: `${remoteHosted}#${REPO_HEAD}`,
341+
dist: {},
342+
}
340343
}
341-
}
342-
}))
343-
.then(() => g.extract(me + '/hosted'))
344-
.then(() => {
345-
t.throws(() => fs.statSync(me + '/hosted/prepare.js'))
346-
fs.statSync(me + '/hosted/index.js')
347-
})
344+
}))
345+
.then(() => g.extract(me + '/hosted'))
346+
.then(result => {
347+
t.throws(() => fs.statSync(me + '/hosted/prepare.js'))
348+
fs.statSync(me + '/hosted/index.js')
349+
})
350+
}
351+
352+
t.plan(2)
353+
t.test('with repo@ on the spec', runTest('repo@'))
354+
t.test('without repo@on the spec', runTest(''))
348355
})
349356

350357
t.test('add git sha to hosted git shorthand', t =>
351358
new GitFetcher('localhost:repo/x', {cache})
352-
.resolve().then(r => t.equal(r, `${hostedUrl}/repo-HEAD.tgz`)))
359+
.resolve().then(r => t.equal(r, `${remoteHosted}#${REPO_HEAD}`)))
353360

354361
t.test('fetch a weird ref', t => {
362+
let head3 = ''
355363
t.test('hosted', t =>
356364
new GitFetcher('localhost:repo/x#HEAD~3', {cache}).extract(me + '/h3h')
357-
.then(result => t.equal(result.resolved, `${hostedUrl}/repo-HEAD.tgz`)))
365+
.then(result => {
366+
head3 = result.resolved.split('#').pop()
367+
t.match(result.resolved, /^git:\/\/127\.0\.0\.1:[0-9]+\/repo#[a-z0-9]{40}$/,
368+
'got git url as resolved value')
369+
t.notEqual(result.resolved, `${remoteHosted}#${REPO_HEAD}`,
370+
'git url for HEAD~3 is not the same as HEAD')
371+
}))
358372

359373
t.test('reglar', t =>
360374
new GitFetcher(`${remote}#HEAD~3`, {cache}).extract(me + '/h3r')
361-
.then(result => t.notEqual(result.resolved,
362-
`${remote}#${REPO_HEAD}`, 'something other than default head')))
375+
.then(result => t.equal(result.resolved, `${remote}#${head3}`,
376+
'got the same HEAD~3 sha as before')))
363377

364378
t.end()
365379
})

0 commit comments

Comments
 (0)
Please sign in to comment.