Skip to content

Commit

Permalink
Merge pull request #3 from cnpm/merge-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored Feb 8, 2017
2 parents 9305ace + 4f3da5a commit ef77cd8
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 99 deletions.
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
sudo: false
language: node_js
node_js:
- "7"
- "6"
- "4"
- "iojs"
- "0.12"
- "0.11"
- "0.10"
script:
- npm test
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2015 Mathias Buus
Copyright (c) 2016 - 2017 cnpm

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
46 changes: 39 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# node-gyp-install
# node-gyp-install-cn

___This is a fork `node-gyp-install` using [cnpm mirrors](https://npm.taobao.org/mirrors).___

Manually download node/iojs header files for usage with node-gyp.

``` sh
npm install node-gyp-install-cn -g
npm install -g node-gyp-install-cn
```

[![build status](http://img.shields.io/travis/mafintosh/node-gyp-install.svg?style=flat)](http://travis-ci.org/mafintosh/node-gyp-install)
[![build status](http://img.shields.io/travis/cnpm/node-gyp-install.svg?style=flat)](http://travis-ci.org/cnpm/node-gyp-install)

## Usage

Expand All @@ -22,20 +22,52 @@ node-gyp-install
Afterwards installing native modules that uses node-gyp using iojs should *just work*

``` sh
# assuming you are using iojs
node-gyp-install
npm install level # does not explode \o/
```

Per default node-gyp-install will install header files for your current node version.
To see all available options see `node-gyp-install --help`.

### Download From Mirrors

To use a mirror of the node/iojs header files, set `$NVM_NODEJS_ORG_MIRROR` and `$NVM_IOJS_ORG_MIRROR`.

Take an exapmle for users from China:
Take an example for users from China:

``` sh
export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
export NVM_IOJS_ORG_MIRROR=https://npm.taobao.org/mirrors/iojs
```

### Download From Secure Mirrors

To use private mirrors that need some https/tls configuration e.g. for client authentification you
can pass some more environment settings:

``` sh
export NVM_NODEJS_ORG_MIRROR=http://npm.taobao.org/mirrors/node
export NVM_IOJS_ORG_MIRROR=http://npm.taobao.org/mirrors/iojs
export NODE_GYP_INSTALL_PASSPHRASE=mysecret
export NODE_GYP_INSTALL_REJECTUNAUTHORIZED=false
export NODE_GYP_INSTALL_PFX=/path/to/my/key.p12
export NODE_GYP_INSTALL_CERT=/path/to/my/cert.crt
export NODE_GYP_INSTALL_KEY=/path/to/my/key.key
export NODE_GYP_INSTALL_CA=/path/to/my/ca.crt
```

This variables refers to the according options of the https.request() function.
Please have a look to [nodejs tls api documentation](https://nodejs.org/api/tls.html)
for more details.


## Programmatic usage

You can also use this as a module

``` js
var install = require('node-gyp-install')
install(function (err) {
console.log('header files installed', err)
})
```

## License
Expand Down
113 changes: 25 additions & 88 deletions bin.js
Original file line number Diff line number Diff line change
@@ -1,92 +1,29 @@
#!/usr/bin/env node

var request = require('request')
var map = require('tar-map-stream')
var tar = require('tar-fs')
var zlib = require('zlib')
var fs = require('fs')
var path = require('path')

// var io = parseInt(process.version.slice(1), 10) >= 1 // yolo
var io = process.env.IOJS === 'TRUE'
var iojsDistUrl = process.env.NVM_IOJS_ORG_MIRROR || 'http://npm.taobao.org/mirrors/iojs/'
if (iojsDistUrl[iojsDistUrl.length - 1] !== '/') {
iojsDistUrl += '/'
}
var nodeDistUrl = process.env.NVM_NODEJS_ORG_MIRROR || 'http://npm.taobao.org/mirrors/node/'
if (nodeDistUrl[nodeDistUrl.length - 1] !== '/') {
nodeDistUrl += '/'
}

var url = io ?
iojsDistUrl + process.version + '/iojs-' + process.version + '.tar.gz' :
nodeDistUrl + process.version + '/node-' + process.version + '.tar.gz'

var target = path.join(process.env.HOME || process.env.USERPROFILE, '.node-gyp', process.version.slice(1))

if (fs.existsSync(path.join(target, 'installVersion'))) {
console.log('Header files already fetched')
console.log('node-gyp should now work for %s', process.version)
process.exit(1)
var install = require('./')
var minimist = require('minimist')
var log = require('npmlog')
var argv = minimist(process.argv, {
booleans: ['iojs', 'nightly', 'quiet', 'force'],
alias: {iojs: 'io', v: 'version', p: 'platform', d: 'dist', q: 'quiet', n: 'nightly', f: 'force'}
})

log.heading = 'node-gyp-install'
argv.log = !argv.quiet && log

if (argv.help) {
console.error(
'node-gyp-install [options]\n' +
' --version, -v (' + process.version + ')\n' +
' --platform, -p (' + process.platform + ')\n' +
' --force, -f\n' +
' --nightly, -n\n' +
' --quiet, -q\n' +
' --iojs\n'
)
process.exit(0)
}

console.log('Fetching header files from %s', url)

request(url)
.pipe(zlib.createGunzip())
.pipe(map(function (entry) {
return /(\.gypi$)|(\.h$)/.test(entry.name) ? entry : null
}))
.pipe(tar.extract(target, {strip: 1}))
.on('finish', function () {
downloadLibs(function () {
fs.writeFileSync(path.join(target, 'installVersion'), '9') // yolo
console.log('node-gyp should now work for %s', process.version)
})
})

function downloadLibs (callback) {
if (process.platform !== 'win32') {
return callback()
}

var urls
if (io) {
urls = [
iojsDistUrl + process.version + '/win-x86/iojs.lib',
iojsDistUrl + process.version + '/win-x64/iojs.lib'
]
} else {
urls = [
nodeDistUrl + process.version + '/node.lib',
nodeDistUrl + process.version + '/x64/node.lib'
]
}

var count = 0
var done = function () {
count++
if (count === 2) {
callback()
}
}
urls.forEach(function (url, index) {
var arch = index === 0 ? 'ia32' : 'x64'
console.log('Fetching windows %s lib from %s', arch, url)
var nodeLib = path.join(process.env.HOME || process.env.USERPROFILE, '.node-gyp',
process.version.slice(1), arch, 'node.lib')
var parentDir = path.dirname(nodeLib)
if (!fs.existsSync(parentDir)) {
fs.mkdirSync(parentDir)
}
request(url).pipe(fs.createWriteStream(nodeLib)).on('finish', function () {
if (io) {
// copy node.lib to iojs.lib
var iojsLib = path.join(parentDir, 'iojs.lib')
fs.createReadStream(nodeLib).pipe(fs.createWriteStream(iojsLib)).on('finish', done)
} else {
done()
}
})
})
}
install(argv, function (err) {
if (err) console.error('Error: ' + err.message)
})
153 changes: 153 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/env node

var get = require('simple-get')
var map = require('tar-map-stream')
var tar = require('tar-fs')
var zlib = require('zlib')
var fs = require('fs')
var path = require('path')
var pump = require('pump')
var after = require('after-all')
var multi = require('multi-write-stream')
var semver = require('semver')

module.exports = install

function install (opts, cb) {
if (typeof opts === 'function') return install(null, opts)
if (!opts) opts = {}
if (!cb) cb = noop

var log = opts.log
var version = opts.version || process.version
if (version[0] !== 'v') version = 'v' + version

var nightly = opts.nightly !== undefined ? opts.nightly : version.indexOf('nightly') > -1
var io = opts.iojs !== undefined ? opts.iojs : iojsVersion(version)
var platform = opts.platform || process.platform

var defaultIojsUrl = nightly ? 'https://iojs.org/download/nightly/' : 'https://npm.taobao.org/mirrors/iojs/'
var iojsDistUrl = pad(process.env.NVM_IOJS_ORG_MIRROR || defaultIojsUrl)
var nodeDistUrl = pad(process.env.NVM_NODEJS_ORG_MIRROR || 'https://npm.taobao.org/mirrors/node/')

var url = io
? iojsDistUrl + version + '/iojs-' + version + '.tar.gz'
: nodeDistUrl + version + '/node-' + version + '.tar.gz'

var target = path.join(process.env.HOME || process.env.USERPROFILE, '.node-gyp', version.slice(1))

exists(function (err) {
if (!err && !opts.force) {
if (log) log.info('install', 'Header files already fetched')
if (log) log.info('install', 'node-gyp should now work for ' + version)
return cb(null)
}

if (log) log.http('request', url)
get(tlsopts(url), function (err, res) {
if (err) return cb(err)
if (log) log.http(res.statusCode, url)
pump(res, zlib.createGunzip(), map(mapEntry), tar.extract(target, {strip: 1}), function (err) {
if (err) return cb(err)
fetchWindows(function (err) {
if (err) return cb(err)
fs.writeFile(path.join(target, 'installVersion'), '9', function (err) {
if (err) return cb(err)
if (log) log.info('install', 'node-gyp should now work for ' + version)
cb()
})
})
})
})
})

function exists (cb) {
fs.exists(path.join(target, 'installVersion'), function (exists) {
if (!exists) return cb(new Error('missing installVersion'))
fs.exists(path.join(target, 'common.gypi'), function (exists) {
cb(exists ? null : new Error('missing common.gypi'))
})
})
}

function mapEntry (entry) {
return /(\.gypi$)|(\.h$)/.test(entry.name) ? entry : null
}

function fetchWindows (cb) {
if (platform !== 'win32') return cb()

var urls
if (io) {
urls = [
iojsDistUrl + version + '/win-x86/iojs.lib',
iojsDistUrl + version + '/win-x64/iojs.lib'
]
} else if (semver.satisfies(version, '>=4.0.0')) {
urls = [
nodeDistUrl + version + '/win-x86/node.lib',
nodeDistUrl + version + '/win-x64/node.lib'
]
} else {
urls = [
nodeDistUrl + version + '/node.lib',
nodeDistUrl + version + '/x64/node.lib'
]
}

var next = after(cb)

urls.forEach(function (url, index) {
var arch = index === 0 ? 'ia32' : 'x64'
var nodeLib = path.join(target, arch, 'node.lib')
var ioLib = path.join(target, arch, 'iojs.lib')
var parentDir = path.dirname(nodeLib)
var done = next()

if (log) log.http('request', url)
fs.mkdir(parentDir, function () {
get(tlsopts(url), function (err, res) {
if (err) return done(err)
log.http(res.statusCode, url)
pump(res, multi([fs.createWriteStream(nodeLib), fs.createWriteStream(ioLib)]), done)
})
})
})
}

function tlsopts (url) {
var getOpts = {
url: url,
passphrase: process.env.NODE_GYP_INSTALL_PASSPHRASE,
requestCert: true,
rejectUnauthorized: process.env.NODE_GYP_INSTALL_REJECTUNAUTHORIZED === 'true'
}

if (process.env.NODE_GYP_INSTALL_PFX) {
getOpts.pfx = fs.readFileSync(process.env.NODE_GYP_INSTALL_PFX)
}

if (process.env.NODE_GYP_INSTALL_CERT) {
getOpts.cert = fs.readFileSync(process.env.NODE_GYP_INSTALL_CERT)
}

if (process.env.NODE_GYP_INSTALL_KEY) {
getOpts.cert = fs.readFileSync(process.env.NODE_GYP_INSTALL_KEY)
}

if (process.env.NODE_GYP_INSTALL_CA) {
getOpts.ca = [fs.readFileSync(process.env.NODE_GYP_INSTALL_CA)]
}
return getOpts
}
}

function iojsVersion (v) {
return semver.satisfies(v, '>=1.0.0 <4.0.0')
}

function pad (url) {
return url[url.length - 1] === '/' ? url : url + '/'
}

function noop () {}
Loading

0 comments on commit ef77cd8

Please sign in to comment.