node-gyp/lib/install.js

112 lines
2.9 KiB
JavaScript

module.exports = exports = install
/**
* Module dependencies.
*/
var fs = require('fs')
, tar = require('tar')
, path = require('path')
, zlib = require('zlib')
, mkdir = require('mkdirp')
, request = require('request')
, minimatch = require('minimatch')
, distUrl = 'http://nodejs.org/dist'
function install (gyp, argv, callback) {
if (argv.length < 1) {
return callback(new Error('need to specify a version'))
}
var version = parseFloat(argv[0])
// first create the dir for the node dev files
var devDir = path.join(process.env.HOME, '.node-gyp', version.toString())
mkdir(devDir, function (err) {
if (err) return callback(err)
console.error('created:', devDir)
// now download the node tarball
// TODO: download the newest version instead of the .0 release
var tarballUrl = distUrl + '/v' + version + '.0/node-v' + version + '.0.tar.gz'
, parser = tar.Parse()
console.error('downloading:', tarballUrl)
request(tarballUrl, downloadError)
.pipe(zlib.createGunzip())
.pipe(parser)
parser.on('entry', onEntry)
parser.on('end', function () {
// TODO: Ensure no multiple-callback
callback()
})
// something went wrong downloading the tarball?
function downloadError (err, res) {
if (err || res.statusCode != 200) {
callback(err || new Error(res.statusCode + ' status code downloading tarball'))
}
}
// handle a file from the tarball
function onEntry (entry) {
var filename = entry.props.path
, trimmed = install.trim(filename)
if (!install.valid(trimmed)) {
// skip
return
}
var dir = path.dirname(trimmed)
, devFileDir = path.join(devDir, dir)
, devFile = path.join(devDir, trimmed)
if (dir !== '.') {
// TODO: async
//console.error(devFileDir)
mkdir.sync(devFileDir)
}
// TODO: Better File detection
if (entry.props.type !== '0') {
return
}
//console.error(trimmed, entry.props)
// Finally save the file to the filesystem
// TODO: Figure out why pipe() hangs here
var ws = fs.createWriteStream(devFile, {
mode: entry.props.mode
})
entry.on('data', function (b) {
ws.write(b)
})
entry.on('end', function () {
ws.end()
console.error('saved:', devFile)
})
}
})
}
install.valid = function valid (file) {
return minimatch(file, '*.gypi')
|| minimatch(file, 'tools/*.gypi')
|| minimatch(file, 'tools/gyp_addon')
|| (minimatch(file, 'tools/gyp/**')
&& !minimatch(file, 'tools/gyp/test/**'))
// header files
|| minimatch(file, 'src/*.h')
|| minimatch(file, 'deps/v8/include/**/*.h')
|| minimatch(file, 'deps/uv/include/**/*.h')
}
install.trim = function trim (file) {
var firstSlash = file.indexOf('/')
return file.substring(firstSlash + 1)
}