node-gyp-build
Advanced tools
Comparing version 3.8.0 to 4.0.0
35
bin.js
@@ -8,4 +8,7 @@ #!/usr/bin/env node | ||
if (!buildFromSource()) { | ||
proc.exec('node-gyp-build-test', function (err) { | ||
if (err) preinstall() | ||
proc.exec('node-gyp-build-test', function (err, stdout, stderr) { | ||
if (err) { | ||
if (verbose()) console.error(stderr) | ||
preinstall() | ||
} | ||
}) | ||
@@ -16,12 +19,2 @@ } else { | ||
function buildFromSource () { | ||
if (!process.env.npm_config_argv) return false | ||
try { | ||
return JSON.parse(process.env.npm_config_argv).cooked.indexOf('--build-from-source') !== -1 | ||
} catch (_) { | ||
return false | ||
} | ||
} | ||
function build () { | ||
@@ -67,1 +60,19 @@ var args = [ os.platform() === 'win32' ? 'node-gyp.cmd' : 'node-gyp', 'rebuild' ] | ||
} | ||
function buildFromSource () { | ||
return hasFlag('--build-from-source') | ||
} | ||
function verbose () { | ||
return hasFlag('--verbose') | ||
} | ||
function hasFlag (flag) { | ||
if (!process.env.npm_config_argv) return false | ||
try { | ||
return JSON.parse(process.env.npm_config_argv).original.indexOf(flag) !== -1 | ||
} catch (_) { | ||
return false | ||
} | ||
} |
122
index.js
@@ -14,2 +14,3 @@ var fs = require('fs') | ||
var armv = process.env.ARM_VERSION || (arch === 'arm64' ? '8' : process.config.variables.arm_version) || '' | ||
var uv = (process.versions.uv || '').split('.')[0] | ||
@@ -36,52 +37,103 @@ module.exports = load | ||
var names = [platform + '-' + arch] | ||
if (libc) names.push(platform + libc + '-' + arch) | ||
if ((arch === 'arm' || arch === 'arm64') && armv) { | ||
names.forEach(function (name) { | ||
names.push(name + '-v' + armv) | ||
}) | ||
} | ||
// Find most specific flavor first | ||
for (var i = names.length; i--;) { | ||
var prebuild = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchPrebuild) | ||
if (prebuild) return prebuild | ||
var prebuilds = path.join(dir, 'prebuilds', platform + '-' + arch) | ||
var parsed = readdirSync(prebuilds).map(parseTags) | ||
var candidates = parsed.filter(matchTags(runtime, abi)) | ||
var winner = candidates.sort(compareTags(runtime))[0] | ||
if (winner) return path.join(prebuilds, winner.file) | ||
var napiRuntime = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchNapiRuntime) | ||
if (napiRuntime) return napiRuntime | ||
var target = [ | ||
'platform=' + platform, | ||
'arch=' + arch, | ||
'runtime=' + runtime, | ||
'abi=' + abi, | ||
'uv=' + uv, | ||
armv ? 'armv=' + armv : '', | ||
'libc=' + libc | ||
].filter(Boolean).join(' ') | ||
var napi = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchNapi) | ||
if (napi) return napi | ||
} | ||
throw new Error('No native build was found for runtime=' + runtime + ' abi=' + abi + ' platform=' + platform + libc + ' arch=' + arch) | ||
throw new Error('No native build was found for ' + target) | ||
} | ||
function getFirst (dir, filter) { | ||
function readdirSync (dir) { | ||
try { | ||
var files = fs.readdirSync(dir).filter(filter) | ||
return files[0] && path.join(dir, files[0]) | ||
return fs.readdirSync(dir) | ||
} catch (err) { | ||
return null | ||
return [] | ||
} | ||
} | ||
function matchNapiRuntime (name) { | ||
return name === runtime + '-napi.node' | ||
function getFirst (dir, filter) { | ||
var files = readdirSync(dir).filter(filter) | ||
return files[0] && path.join(dir, files[0]) | ||
} | ||
function matchNapi (name) { | ||
return name === 'node-napi.node' | ||
function matchBuild (name) { | ||
return /\.node$/.test(name) | ||
} | ||
function matchPrebuild (name) { | ||
var parts = name.split('-') | ||
return parts[0] === runtime && parts[1] === abi + '.node' | ||
function parseTags (file) { | ||
var arr = file.split('.') | ||
var extension = arr.pop() | ||
var tags = { file: file, specificity: 0 } | ||
if (extension !== 'node') return | ||
for (var i = 0; i < arr.length; i++) { | ||
var tag = arr[i] | ||
if (tag === 'node' || tag === 'electron' || tag === 'node-webkit') { | ||
tags.runtime = tag | ||
} else if (tag === 'napi') { | ||
tags.napi = true | ||
} else if (tag.slice(0, 3) === 'abi') { | ||
tags.abi = tag.slice(3) | ||
} else if (tag.slice(0, 2) === 'uv') { | ||
tags.uv = tag.slice(2) | ||
} else if (tag.slice(0, 4) === 'armv') { | ||
tags.armv = tag.slice(4) | ||
} else if (tag === 'glibc' || tag === 'musl') { | ||
tags.libc = tag | ||
} else { | ||
continue | ||
} | ||
tags.specificity++ | ||
} | ||
return tags | ||
} | ||
function matchBuild (name) { | ||
return /\.node$/.test(name) | ||
function matchTags (runtime, abi) { | ||
return function (tags) { | ||
if (tags == null) return false | ||
if (tags.runtime !== runtime && !runtimeAgnostic(tags)) return false | ||
if (tags.abi !== abi && !tags.napi) return false | ||
if (tags.uv && tags.uv !== uv) return false | ||
if (tags.armv && tags.armv !== armv) return false | ||
if (tags.libc && tags.libc !== libc) return false | ||
return true | ||
} | ||
} | ||
function runtimeAgnostic (tags) { | ||
return tags.runtime === 'node' && tags.napi | ||
} | ||
function compareTags (runtime) { | ||
// Precedence: non-agnostic runtime, abi over napi, then by specificity. | ||
return function (a, b) { | ||
if (a.runtime !== b.runtime) { | ||
return a.runtime === runtime ? -1 : 1 | ||
} else if (a.abi !== b.abi) { | ||
return a.abi ? -1 : 1 | ||
} else if (a.specificity !== b.specificity) { | ||
return a.specificity > b.specificity ? -1 : 1 | ||
} else { | ||
return 0 | ||
} | ||
} | ||
} | ||
function isElectron () { | ||
@@ -96,1 +148,7 @@ if (process.versions && process.versions.electron) return true | ||
} | ||
// Exposed for unit tests | ||
// TODO: move to lib | ||
load.parseTags = parseTags | ||
load.matchTags = matchTags | ||
load.compareTags = compareTags |
{ | ||
"name": "node-gyp-build", | ||
"version": "3.8.0", | ||
"version": "4.0.0", | ||
"description": "Build tool and bindings loader for node-gyp that supports prebuilds", | ||
"main": "index.js", | ||
"devDependencies": { | ||
"standard": "^8.6.0" | ||
"array-shuffle": "^1.0.1", | ||
"standard": "^8.6.0", | ||
"tape": "^4.10.1" | ||
}, | ||
"scripts": { | ||
"test": "standard" | ||
"test": "standard && node test" | ||
}, | ||
@@ -19,3 +21,3 @@ "bin": { | ||
"type": "git", | ||
"url": "https://github.com/mafintosh/node-gyp-build.git" | ||
"url": "https://github.com/prebuild/node-gyp-build.git" | ||
}, | ||
@@ -25,5 +27,5 @@ "author": "Mathias Buus (@mafintosh)", | ||
"bugs": { | ||
"url": "https://github.com/mafintosh/node-gyp-build/issues" | ||
"url": "https://github.com/prebuild/node-gyp-build/issues" | ||
}, | ||
"homepage": "https://github.com/mafintosh/node-gyp-build" | ||
"homepage": "https://github.com/prebuild/node-gyp-build" | ||
} |
# node-gyp-build | ||
Build tool and bindings loader for node-gyp that supports prebuilds. | ||
> Build tool and bindings loader for [`node-gyp`][node-gyp] that supports prebuilds. | ||
@@ -9,10 +9,14 @@ ``` | ||
Use together with [prebuildify](https://github.com/mafintosh/prebuildify) to easily support prebuilds for your native modules. | ||
[![Build Status](https://travis-ci.org/prebuild/node-gyp-build.svg?branch=master)](https://travis-ci.org/prebuild/node-gyp-build) | ||
Use together with [`prebuildify`][prebuildify] to easily support prebuilds for your native modules. | ||
## Usage | ||
`node-gyp-build` works similar to `node-gyp build` except that it will check if a build or prebuild is present before rebuilding your project. | ||
> **Note.** Prebuild names have changed in [`prebuildify@3`][prebuildify] and `node-gyp-build@4`. Please see the documentation below. | ||
It's main intended use is as an npm install script and bindings loader for native modules that bundle prebuilds using [prebuildify](https://github.com/mafintosh/prebuildify). | ||
`node-gyp-build` works similar to [`node-gyp build`][node-gyp] except that it will check if a build or prebuild is present before rebuilding your project. | ||
It's main intended use is as an npm install script and bindings loader for native modules that bundle prebuilds using [`prebuildify`][prebuildify]. | ||
First add `node-gyp-build` as an install script to your native project | ||
@@ -29,3 +33,3 @@ | ||
Then in your `index.js`, instead of using the [bindings module](https://www.npmjs.com/package/bindings) use `node-gyp-build` to load your binding. | ||
Then in your `index.js`, instead of using the [`bindings`](https://www.npmjs.com/package/bindings) module use `node-gyp-build` to load your binding. | ||
@@ -36,3 +40,3 @@ ``` js | ||
If you do these two things and bundle prebuilds [prebuildify](https://github.com/mafintosh/prebuildify) your native module will work for most platforms | ||
If you do these two things and bundle prebuilds with [`prebuildify`][prebuildify] your native module will work for most platforms | ||
without having to compile on install time AND will work in both node and electron without the need to recompile between usage. | ||
@@ -46,14 +50,11 @@ | ||
These prebuilds can be bundled in addition to generic prebuilds; `node-gyp-build` will try to find the most specific flavor first. In order of precedence: | ||
These prebuilds can be bundled in addition to generic prebuilds; `node-gyp-build` will try to find the most specific flavor first. Prebuild filenames are composed of _tags_. The runtime tag takes precedence, as does an `abi` tag over `napi`. For more details on tags, please see [`prebuildify`][prebuildify]. | ||
- If `arch` is `'arm'` or `'arm64'`: | ||
- `${platform}${libc}-${arch}-v${arm_version}` | ||
- `${platform}-${arch}-v${arm_version}` | ||
- `${platform}${libc}-${arch}` | ||
- `${platform}-${arch}` | ||
Values for the `libc` and `armv` tags are auto-detected but can be overridden through the `LIBC` and `ARM_VERSION` environment variables, respectively. | ||
The `libc` flavor and `arm_version` are auto-detected but can be overridden through the `LIBC` and `ARM_VERSION` environment variables, respectively. | ||
## License | ||
MIT | ||
[prebuildify]: https://github.com/prebuild/prebuildify | ||
[node-gyp]: https://www.npmjs.com/package/node-gyp |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
10698
207
57
14
3
2