This repository has been archived by the owner on Jul 3, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
445 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
'use strict' | ||
|
||
const BB = require('bluebird') | ||
|
||
const git = require('../../util/git') | ||
const normalizeGitUrl = require('normalize-git-url') | ||
const optCheck = require('../../util/opt-check') | ||
const pickManifest = require('../../registry/pick-manifest') | ||
const semver = require('semver') | ||
|
||
module.exports = manifest | ||
function manifest (spec, opts) { | ||
opts = optCheck(opts) | ||
// TODO - spec.hosted url stuff should be done in hosted handler | ||
const normed = normalizeGitUrl(spec.hosted ? spec.hosted.ssh : spec.spec) | ||
const rawRef = decodeURIComponent(normed.branch) | ||
return resolve( | ||
normed.url, rawRef, spec.name, opts | ||
).then(ref => { | ||
if (ref) { | ||
return { | ||
_repo: normed.url, | ||
_resolved: `${normed.url}#${ref.sha}`, | ||
_spec: spec, | ||
_ref: ref, | ||
_rawRef: rawRef, | ||
_uniqueResolved: `${normed.url}#${ref.sha}` | ||
} | ||
} else { | ||
// We're SOL and need a full clone :( | ||
// | ||
// If we're confident enough that `rawRef` is a commit SHA, | ||
// then we can at least get `finalize-manifest` to cache its result. | ||
return { | ||
_repo: normed.url, | ||
_rawRef: rawRef, | ||
_resolved: rawRef.match(/^[a-f0-9]{40}$/) && `${normed.url}#${rawRef}`, | ||
_uniqueResolved: rawRef.match(/^[a-f0-9]{40}$/) && `${normed.url}#${rawRef}` | ||
} | ||
} | ||
}) | ||
} | ||
|
||
function resolve (url, rawRef, name, opts) { | ||
const semverMatch = rawRef.match(/^semver:v?(.*)/) | ||
const isSemver = semverMatch && semver.validRange(semverMatch[1]) | ||
return git.revs(url, opts).then(remoteRefs => { | ||
return isSemver | ||
? pickManifest({ | ||
versions: remoteRefs.versions, | ||
'dist-tags': remoteRefs['dist-tags'], | ||
name: name | ||
}, { | ||
type: 'range', | ||
spec: semverMatch[1] | ||
}, opts) | ||
: remoteRefs | ||
? BB.resolve( | ||
remoteRefs.refs[rawRef] || remoteRefs.refs[remoteRefs.shas[rawRef]] | ||
) | ||
: null | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
'use strict' | ||
|
||
const BB = require('bluebird') | ||
|
||
const cache = require('../../cache') | ||
const git = require('../../util/git') | ||
const mkdirp = BB.promisify(require('mkdirp')) | ||
const optCheck = require('../../util/opt-check') | ||
const osenv = require('osenv') | ||
const path = require('path') | ||
const pipe = BB.promisify(require('mississippi').pipe) | ||
const rimraf = BB.promisify(require('rimraf')) | ||
const tar = require('tar-fs') | ||
const through = require('mississippi').through | ||
const to = require('mississippi').to | ||
const uniqueFilename = require('unique-filename') | ||
|
||
const gitManifest = require('./manifest') | ||
|
||
module.exports = tarball | ||
function tarball (spec, opts) { | ||
opts = optCheck(opts) | ||
let streamErr = null | ||
const stream = through().on('error', e => { streamErr = e }) | ||
gitManifest(spec, opts).then(manifest => { | ||
if (streamErr) { throw streamErr } | ||
return pipe(fromManifest(manifest, spec, opts), stream) | ||
}) | ||
return stream | ||
} | ||
|
||
module.exports.fromManifest = fromManifest | ||
function fromManifest (manifest, spec, opts) { | ||
opts = optCheck(opts) | ||
let streamError | ||
const stream = through().on('error', e => { streamError = e }) | ||
const cacheStream = ( | ||
opts.cache && | ||
cache.get.stream( | ||
opts.cache, cache.key('git-clone', manifest._resolved), opts | ||
) | ||
) | ||
cacheStream.pipe(stream) | ||
cacheStream.on('error', err => { | ||
if (err.code !== 'ENOENT') { | ||
return stream.emit('error', err) | ||
} else { | ||
stream.emit('reset') | ||
withTmp(opts, tmp => { | ||
if (streamError) { throw streamError } | ||
return cloneRepo( | ||
manifest._repo, manifest._ref, manifest._rawRef, tmp, opts | ||
).then(HEAD => { | ||
if (streamError) { throw streamError } | ||
return packDir(manifest._resolved, tmp, stream, opts) | ||
}) | ||
}).catch(err => stream.emit('error', err)) | ||
} | ||
}) | ||
return stream | ||
} | ||
|
||
function withTmp (opts, cb) { | ||
if (opts.cache) { | ||
// cacache has a special facility for working in a tmp dir | ||
return cache.tmp.withTmp(opts.cache, opts, cb) | ||
} else { | ||
const tmpDir = path.join(osenv.tmpdir(), 'pacote-git-tmp') | ||
const tmpName = uniqueFilename(tmpDir, 'git-clone') | ||
const tmp = mkdirp(tmpName).then(() => tmpName).disposer(rimraf) | ||
return BB.using(tmp, cb) | ||
} | ||
} | ||
|
||
function cloneRepo (repo, resolvedRef, rawRef, tmp, opts) { | ||
// TODO - loop through alternatives for hosted specs | ||
if (resolvedRef) { | ||
return git.shallow(repo, resolvedRef.ref, tmp, opts) | ||
} else { | ||
return git.clone(repo, rawRef, tmp, opts) | ||
} | ||
} | ||
|
||
function packDir (label, tmp, target, opts) { | ||
opts = optCheck(opts) | ||
|
||
// TODO - make a better attempt at a pack | ||
const packer = tar.pack(tmp, { | ||
map: header => { | ||
header.name = 'package/' + header.name | ||
}, | ||
ignore: (name) => { | ||
name.match(/\.git/) | ||
} | ||
}) | ||
|
||
if (!opts.cache) { | ||
return pipe(packer, target) | ||
} else { | ||
const cacher = cache.put.stream( | ||
opts.cache, cache.key('git-clone', label), opts | ||
) | ||
cacher.once('error', err => packer.emit('error', err)) | ||
target.once('error', err => packer.emit('error', err)) | ||
packer.once('error', err => { | ||
cacher.emit('error', err) | ||
target.emit('error', err) | ||
}) | ||
return pipe(packer, to((chunk, enc, cb) => { | ||
cacher.write(chunk, enc, () => { | ||
target.write(chunk, enc, cb) | ||
}) | ||
}, done => { | ||
cacher.end(() => { | ||
target.end(done) | ||
}) | ||
})) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict' | ||
|
||
module.exports = require('../git/manifest') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict' | ||
|
||
module.exports = require('../git/tarball') |
Oops, something went wrong.