-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add io.js support #564
Add io.js support #564
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
test: build-buffertools build-leveldown | ||
|
||
build-buffertools: | ||
cd node_modules/buffertools/ && \ | ||
../../bin/node-gyp.js rebuild | ||
|
||
build-leveldown: | ||
cd node_modules/leveldown/ && \ | ||
../../bin/node-gyp.js rebuild | ||
|
||
test-docker-node: | ||
docker run \ | ||
--rm=true -i -v `pwd`:/opt/node-gyp/ \ | ||
nodesource/node:wheezy \ | ||
bash -c 'rm -rf /root/.node-gyp/ && cd /opt/node-gyp && make test' | ||
|
||
test-docker-iojs: | ||
docker run \ | ||
--rm=true -i -v `pwd`:/opt/node-gyp/ \ | ||
iojs/iojs:1.0 \ | ||
bash -c 'rm -rf /root/.node-gyp/ && cd /opt/node-gyp && make test' | ||
|
||
test-docker: test-docker-node test-docker-iojs |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,8 @@ var fs = require('graceful-fs') | |
, mkdirp = require('mkdirp') | ||
, exec = require('child_process').exec | ||
, win = process.platform == 'win32' | ||
, semver = require('semver') | ||
, runtime = semver.parse(process.version).major < 1 ? 'node' : 'iojs' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't this be a problem when node v1 is released? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can there be an override for this as an env variable? e.g. tcr/pangyp@b9209b8 If I want to enable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in iojs you can check for To set as a target I would recommend to use same notation as nvm: |
||
|
||
exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' | ||
|
||
|
@@ -181,15 +183,15 @@ function build (gyp, argv, callback) { | |
if (!win || !copyDevLib) return doBuild() | ||
|
||
var buildDir = path.resolve(nodeDir, buildType) | ||
, archNodeLibPath = path.resolve(nodeDir, arch, 'node.lib') | ||
, buildNodeLibPath = path.resolve(buildDir, 'node.lib') | ||
, archNodeLibPath = path.resolve(nodeDir, arch, runtime + '.lib') | ||
, buildNodeLibPath = path.resolve(buildDir, runtime + '.lib') | ||
|
||
mkdirp(buildDir, function (err, isNew) { | ||
if (err) return callback(err) | ||
log.verbose('"' + buildType + '" dir needed to be created?', isNew) | ||
var rs = fs.createReadStream(archNodeLibPath) | ||
, ws = fs.createWriteStream(buildNodeLibPath) | ||
log.verbose('copying "node.lib" for ' + arch, buildNodeLibPath) | ||
log.verbose('copying "' + runtime + '.lib" for ' + arch, buildNodeLibPath) | ||
rs.pipe(ws) | ||
rs.on('error', callback) | ||
ws.on('error', callback) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,50 +15,45 @@ var fs = require('graceful-fs') | |
, crypto = require('crypto') | ||
, zlib = require('zlib') | ||
, log = require('npmlog') | ||
, semver = require('semver') | ||
, fstream = require('fstream') | ||
, request = require('request') | ||
, minimatch = require('minimatch') | ||
, mkdir = require('mkdirp') | ||
, getRelease = require('./util/release') | ||
, win = process.platform == 'win32' | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any idea to support nvm custom dist url env by default? https://github.com/creationix/nvm/blob/master/nvm.sh#L73 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fengmk2 would this be to support mirrors, like in China? I'm tinkering around in there currently and it wouldn't be hard to bring in custom URLs from where my local version is at. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not only for mirrors, but also can be used in private NPM services. @rvagg There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rvagg yes, it will be very helpful for us. |
||
function install (gyp, argv, callback) { | ||
|
||
// Determine which node dev files version we are installing | ||
var release | ||
try { | ||
release = getRelease(gyp, argv[0] || gyp.opts.target) | ||
} catch (e) { | ||
return callback(e) | ||
} | ||
|
||
console.log(release) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this (I assume?) |
||
|
||
log.verbose('install', 'input version string %j', release.versionStr) | ||
|
||
// ensure no double-callbacks happen | ||
function cb (err) { | ||
if (cb.done) return | ||
cb.done = true | ||
if (err) { | ||
log.warn('install', 'got an error, rolling back install') | ||
// roll-back the install if anything went wrong | ||
gyp.commands.remove([ version ], function (err2) { | ||
gyp.commands.remove([ release.version.version ], function (err2) { | ||
callback(err) | ||
}) | ||
} else { | ||
callback(null, version) | ||
callback(null, release) | ||
} | ||
} | ||
|
||
var distUrl = gyp.opts['dist-url'] || gyp.opts.disturl || 'http://nodejs.org/dist' | ||
|
||
|
||
// Determine which node dev files version we are installing | ||
var versionStr = argv[0] || gyp.opts.target || process.version | ||
log.verbose('install', 'input version string %j', versionStr) | ||
|
||
// parse the version to normalize and ensure it's valid | ||
var version = semver.parse(versionStr) | ||
if (!version) { | ||
return callback(new Error('Invalid version number: ' + versionStr)) | ||
} | ||
|
||
if (semver.lt(versionStr, '0.8.0')) { | ||
return callback(new Error('Minimum target version is `0.8.0` or greater. Got: ' + versionStr)) | ||
} | ||
|
||
// 0.x.y-pre versions are not published yet and cannot be installed. Bail. | ||
if (version.prerelease[0] === 'pre') { | ||
log.verbose('detected "pre" node version', versionStr) | ||
if (release.version.prerelease[0] === 'pre') { | ||
log.verbose('detected "pre" node version', release.versionStr) | ||
if (gyp.opts.nodedir) { | ||
log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir) | ||
callback() | ||
|
@@ -69,23 +64,16 @@ function install (gyp, argv, callback) { | |
} | ||
|
||
// flatten version into String | ||
version = version.version | ||
log.verbose('install', 'installing version: %s', version) | ||
|
||
// distributions starting with 0.10.0 contain sha256 checksums | ||
var checksumAlgo = semver.gte(version, '0.10.0') ? 'sha256' : 'sha1' | ||
|
||
// the directory where the dev files will be installed | ||
var devDir = path.resolve(gyp.devDir, version) | ||
log.verbose('install', 'installing version: %s', release.version.version) | ||
|
||
// If '--ensure' was passed, then don't *always* install the version; | ||
// check if it is already installed, and only install when needed | ||
if (gyp.opts.ensure) { | ||
log.verbose('install', '--ensure was passed, so won\'t reinstall if already installed') | ||
fs.stat(devDir, function (err, stat) { | ||
fs.stat(release.devDir, function (err, stat) { | ||
if (err) { | ||
if (err.code == 'ENOENT') { | ||
log.verbose('install', 'version not already installed, continuing with install', version) | ||
log.verbose('install', 'version not already installed, continuing with install', release.versionStr) | ||
go() | ||
} else if (err.code == 'EACCES') { | ||
eaccesFallback() | ||
|
@@ -95,7 +83,7 @@ function install (gyp, argv, callback) { | |
return | ||
} | ||
log.verbose('install', 'version is already installed, need to check "installVersion"') | ||
var installVersionFile = path.resolve(devDir, 'installVersion') | ||
var installVersionFile = path.resolve(release.devDir, 'installVersion') | ||
fs.readFile(installVersionFile, 'ascii', function (err, ver) { | ||
if (err && err.code != 'ENOENT') { | ||
return cb(err) | ||
|
@@ -156,7 +144,7 @@ function install (gyp, argv, callback) { | |
} | ||
|
||
function getContentSha(res, callback) { | ||
var shasum = crypto.createHash(checksumAlgo) | ||
var shasum = crypto.createHash(release.checksumAlgo) | ||
res.on('data', function (chunk) { | ||
shasum.update(chunk) | ||
}).on('end', function () { | ||
|
@@ -166,10 +154,10 @@ function install (gyp, argv, callback) { | |
|
||
function go () { | ||
|
||
log.verbose('ensuring nodedir is created', devDir) | ||
log.verbose('ensuring nodedir is created', release.devDir) | ||
|
||
// first create the dir for the node dev files | ||
mkdir(devDir, function (err, created) { | ||
mkdir(release.devDir, function (err, created) { | ||
if (err) { | ||
if (err.code == 'EACCES') { | ||
eaccesFallback() | ||
|
@@ -184,33 +172,32 @@ function install (gyp, argv, callback) { | |
} | ||
|
||
// now download the node tarball | ||
var tarPath = gyp.opts['tarball'] | ||
var tarballUrl = tarPath ? tarPath : distUrl + '/v' + version + '/node-v' + version + '.tar.gz' | ||
var tarPath = gyp.opts.tarball | ||
, badDownload = false | ||
, extractCount = 0 | ||
, gunzip = zlib.createGunzip() | ||
, extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid }) | ||
, extracter = tar.Extract({ path: release.devDir, strip: 1, filter: isValid }) | ||
|
||
var contentShasums = {} | ||
var expectShasums = {} | ||
|
||
// checks if a file to be extracted from the tarball is valid. | ||
// only .h header files and the gyp files get extracted | ||
function isValid () { | ||
var name = this.path.substring(devDir.length + 1) | ||
var isValid = valid(name) | ||
var name = this.path.substring(release.devDir.length + 1) | ||
var validName = valid(name) | ||
if (name === '' && this.type === 'Directory') { | ||
// the first directory entry is ok | ||
return true | ||
} | ||
if (isValid) { | ||
if (validName) { | ||
log.verbose('extracted file from tarball', name) | ||
extractCount++ | ||
} else { | ||
// invalid | ||
log.silly('ignoring from tarball', name) | ||
} | ||
return isValid | ||
return validName | ||
} | ||
|
||
gunzip.on('error', cb) | ||
|
@@ -220,12 +207,12 @@ function install (gyp, argv, callback) { | |
// download the tarball, gunzip and extract! | ||
|
||
if (tarPath) { | ||
var input = fs.createReadStream(tarballUrl) | ||
var input = fs.createReadStream(release.sourceUrl) | ||
input.pipe(gunzip).pipe(extracter) | ||
return | ||
} | ||
|
||
var req = download(tarballUrl) | ||
var req = download(release.sourceUrl) | ||
if (!req) return | ||
|
||
// something went wrong downloading the tarball? | ||
|
@@ -248,7 +235,7 @@ function install (gyp, argv, callback) { | |
} | ||
// content checksum | ||
getContentSha(res, function (_, checksum) { | ||
var filename = path.basename(tarballUrl).trim() | ||
var filename = path.basename(release.sourceUrl).trim() | ||
contentShasums[filename] = checksum | ||
log.verbose('content checksum', filename, checksum) | ||
}) | ||
|
@@ -274,7 +261,7 @@ function install (gyp, argv, callback) { | |
|
||
// write the "installVersion" file | ||
async++ | ||
var installVersionPath = path.resolve(devDir, 'installVersion') | ||
var installVersionPath = path.resolve(release.devDir, 'installVersion') | ||
fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref) | ||
|
||
// download SHASUMS.txt | ||
|
@@ -306,13 +293,11 @@ function install (gyp, argv, callback) { | |
} | ||
|
||
function downloadShasums(done) { | ||
var shasumsFile = (checksumAlgo === 'sha256') ? 'SHASUMS256.txt' : 'SHASUMS.txt' | ||
log.verbose('check download content checksum, need to download `' + shasumsFile + '`...') | ||
var shasumsPath = path.resolve(devDir, shasumsFile) | ||
, shasumsUrl = distUrl + '/v' + version + '/' + shasumsFile | ||
log.verbose('check download content checksum, need to download `' + release.shasumsFile + '`...') | ||
var shasumsPath = path.resolve(release.devDir, release.shasumsFile) | ||
|
||
log.verbose('checksum url', shasumsUrl) | ||
var req = download(shasumsUrl) | ||
log.verbose('checksum url', release.shasumsUrl) | ||
var req = download(release.shasumsUrl) | ||
if (!req) return | ||
req.on('error', done) | ||
req.on('response', function (res) { | ||
|
@@ -343,36 +328,38 @@ function install (gyp, argv, callback) { | |
} | ||
|
||
function downloadNodeLib (done) { | ||
log.verbose('on Windows; need to download `node.lib`...') | ||
var dir32 = path.resolve(devDir, 'ia32') | ||
, dir64 = path.resolve(devDir, 'x64') | ||
, nodeLibPath32 = path.resolve(dir32, 'node.lib') | ||
, nodeLibPath64 = path.resolve(dir64, 'node.lib') | ||
, nodeLibUrl32 = distUrl + '/v' + version + '/node.lib' | ||
, nodeLibUrl64 = distUrl + '/v' + version + '/x64/node.lib' | ||
|
||
log.verbose('32-bit node.lib dir', dir32) | ||
log.verbose('64-bit node.lib dir', dir64) | ||
log.verbose('`node.lib` 32-bit url', nodeLibUrl32) | ||
log.verbose('`node.lib` 64-bit url', nodeLibUrl64) | ||
log.verbose('on Windows; need to download `' + runtime + '.lib`...') | ||
var dir32 = path.resolve(release.devDir, 'ia32') | ||
, dir64 = path.resolve(release.devDir, 'x64') | ||
, nodeLibPath32 = path.resolve(dir32, runtime + '.lib') | ||
, nodeLibPath64 = path.resolve(dir64, runtime + '.lib') | ||
, nodeLibUrlFile32 = (runtime == 'node' ? 'node.lib' : 'win-x86/iojs.lib') | ||
, nodeLibUrlFile64 = (runtime == 'node' ? 'x64/node.lib' : 'win-x64/iojs.lib') | ||
, nodeLibUrl32 = distUrl + '/v' + version + '/' + nodeLibUrlFile32 | ||
, nodeLibUrl64 = distUrl + '/v' + version + '/' + nodeLibUrlFile64 | ||
|
||
log.verbose('32-bit ' + runtime + '.lib dir', dir32) | ||
log.verbose('64-bit ' + runtime + '.lib dir', dir64) | ||
log.verbose('`' + runtime + '.lib` 32-bit url', nodeLibUrl32) | ||
log.verbose('`' + runtime + '.lib` 64-bit url', nodeLibUrl64) | ||
|
||
var async = 2 | ||
mkdir(dir32, function (err) { | ||
if (err) return done(err) | ||
log.verbose('streaming 32-bit node.lib to:', nodeLibPath32) | ||
log.verbose('streaming 32-bit ' + runtime + '.lib to:', nodeLibPath32) | ||
|
||
var req = download(nodeLibUrl32) | ||
if (!req) return | ||
req.on('error', done) | ||
req.on('response', function (res) { | ||
if (res.statusCode !== 200) { | ||
done(new Error(res.statusCode + ' status code downloading 32-bit node.lib')) | ||
done(new Error(res.statusCode + ' status code downloading 32-bit ' + runtime + '.lib')) | ||
return | ||
} | ||
|
||
getContentSha(res, function (_, checksum) { | ||
contentShasums['node.lib'] = checksum | ||
log.verbose('content checksum', 'node.lib', checksum) | ||
contentShasums[nodeLibUrlFile32] = checksum | ||
log.verbose('content checksum', nodeLibUrlFile32, checksum) | ||
}) | ||
|
||
var ws = fs.createWriteStream(nodeLibPath32) | ||
|
@@ -385,20 +372,20 @@ function install (gyp, argv, callback) { | |
}) | ||
mkdir(dir64, function (err) { | ||
if (err) return done(err) | ||
log.verbose('streaming 64-bit node.lib to:', nodeLibPath64) | ||
log.verbose('streaming 64-bit ' + runtime + '.lib to:', nodeLibPath64) | ||
|
||
var req = download(nodeLibUrl64) | ||
if (!req) return | ||
req.on('error', done) | ||
req.on('response', function (res) { | ||
if (res.statusCode !== 200) { | ||
done(new Error(res.statusCode + ' status code downloading 64-bit node.lib')) | ||
done(new Error(res.statusCode + ' status code downloading 64-bit ' + runtime + '.lib')) | ||
return | ||
} | ||
|
||
getContentSha(res, function (_, checksum) { | ||
contentShasums['x64/node.lib'] = checksum | ||
log.verbose('content checksum', 'x64/node.lib', checksum) | ||
contentShasums[nodeLibUrlFile64] = checksum | ||
log.verbose('content checksum', nodeLibUrlFile64, checksum) | ||
}) | ||
|
||
var ws = fs.createWriteStream(nodeLibPath64) | ||
|
@@ -437,7 +424,7 @@ function install (gyp, argv, callback) { | |
function eaccesFallback () { | ||
var tmpdir = osenv.tmpdir() | ||
gyp.devDir = path.resolve(tmpdir, '.node-gyp') | ||
log.warn('EACCES', 'user "%s" does not have permission to access the dev dir "%s"', osenv.user(), devDir) | ||
log.warn('EACCES', 'user "%s" does not have permission to access the dev dir "%s"', osenv.user(), release.devDir) | ||
log.warn('EACCES', 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir) | ||
if (process.cwd() == tmpdir) { | ||
log.verbose('tmpdir == cwd', 'automatically will remove dev files after to save disk space') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and
build-leveldown
should probably depend on annpm install
task if you want these tests to be self-contained for CI.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
howso? that's why they are in devDependencies, doesn't that suffice?