Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: TooTallNate/node-bindings
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e404152ee27f8478ccbc7122ee051246e8e5ec02
Choose a base ref
...
head repository: TooTallNate/node-bindings
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bcdc7cadf839ef84c9bd9e21c697f2a727b2b1d3
Choose a head ref

Commits on Nov 18, 2015

  1. Add alternative to fs.existsSync

    Fixes #18
    n-riesco committed Nov 18, 2015
    Copy the full SHA
    6dd16e5 View commit details

Commits on Apr 12, 2016

  1. Added note for how .node file is searched for

    Added a note about how `node-gyp` searches for the `.node` file; how it will begin its search in the first directory it finds which has a `package.json`. This is an important feature that is surprisingly not mentioned at all within the documentation - I, myself, had trouble figuring out what was going wrong when I ran into problems regarding this silent feature.
    nickzuber committed Apr 12, 2016
    Copy the full SHA
    f5dd613 View commit details

Commits on Jan 19, 2017

  1. Copy the full SHA
    d4bd554 View commit details

Commits on Feb 10, 2017

  1. Update bindings.js

    vihanb authored Feb 10, 2017
    Copy the full SHA
    358e3de View commit details
  2. Removed arrow function

    vihanb authored Feb 10, 2017
    Copy the full SHA
    bcc929e View commit details

Commits on Feb 22, 2017

  1. Merge pull request #30 from vihanb/patch-1

    Replaced __proto__ with Object.assign
    TooTallNate authored Feb 22, 2017
    Copy the full SHA
    d14665a View commit details
  2. Merge pull request #24 from nickzuber/master

    Added note for how .node file is searched for
    TooTallNate authored Feb 22, 2017
    Copy the full SHA
    60b27de View commit details
  3. Merge pull request #20 from n-riesco/patch-1

    Add alternative to fs.existsSync
    TooTallNate authored Feb 22, 2017
    Copy the full SHA
    b33a70e View commit details

Commits on Mar 2, 2017

  1. Add missing right paren to if statement

    Bryan Knight authored and TooTallNate committed Mar 2, 2017
    Copy the full SHA
    228973f View commit details

Commits on Jul 24, 2017

  1. whitespace

    TooTallNate committed Jul 24, 2017
    Copy the full SHA
    7fd065e View commit details
  2. v1.3.0

    TooTallNate committed Jul 24, 2017
    Copy the full SHA
    58141c6 View commit details

Commits on Nov 21, 2018

  1. Add webpack require hack

    TooTallNate committed Nov 21, 2018
    Copy the full SHA
    40dcc1f View commit details

Commits on Nov 26, 2018

  1. 1.3.1

    TooTallNate committed Nov 26, 2018
    Copy the full SHA
    81ba749 View commit details

Commits on Jan 23, 2019

  1. README++

    TooTallNate committed Jan 23, 2019
    Copy the full SHA
    b591acd View commit details
  2. Handle filenames with 'file://' shema

    For Electron.
    
    Fixes #29.
    Closes #40.
    
    Co-authored-by: Mathias Jakobsen <mathiasjakobsen@me.com>
    Co-authored-by: Vilius Sutkus <ViliusSutkus89@gmail.com>
    3 people committed Jan 23, 2019
    Copy the full SHA
    d0bd6f8 View commit details
  3. Add LICENSE.md file

    TooTallNate committed Jan 23, 2019
    Copy the full SHA
    3346bcb View commit details
  4. Support for node-qbs build system (#46)

    See: npmjs.com/node-qbs
    
    Fixes #45.
    anion155 authored and TooTallNate committed Jan 23, 2019
    Copy the full SHA
    e18d8f0 View commit details
  5. Add node-pre-gyp path to search paths

    Fixes #11.
    Closes #32.
    
    Squashed commit of the following:
    
    commit d58451e
    Author: Bryan Knight <bryan.knight@MLDUR1611403.local>
    Date:   Thu Mar 2 14:03:50 2017 -0500
    
        Add node-pre-gyp path to search paths
    
        The node-pre-gyp docs have the binary go into `./lib/binding/{node_abi}-{platform}-{arch}`
    
    Co-authored-by: Bryan Knight <bryan.knight@tanium.com>
    TooTallNate and Bryan Knight committed Jan 23, 2019
    Copy the full SHA
    68dae57 View commit details
  6. Prettier

    TooTallNate committed Jan 23, 2019
    1
    Copy the full SHA
    98350ce View commit details
  7. 1.4.0

    TooTallNate committed Jan 23, 2019
    Copy the full SHA
    e121358 View commit details

Commits on Feb 27, 2019

  1. Copy the full SHA
    ed7e626 View commit details
  2. Add back the old module not found check

    So that we don't have to do a major version bump by dropping support for
    older Node.js versions.
    TooTallNate committed Feb 27, 2019
    Copy the full SHA
    f49851e View commit details
  3. 1.5.0

    TooTallNate committed Feb 27, 2019
    Copy the full SHA
    bcdc7ca View commit details
Showing with 180 additions and 99 deletions.
  1. +22 −0 LICENSE.md
  2. +6 −5 README.md
  3. +147 −92 bindings.js
  4. +5 −2 package.json
22 changes: 22 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(The MIT License)

Copyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
node-bindings
=============
### Helper module for loading your native module's .node file
### Helper module for loading your native module's `.node` file

This is a helper module for authors of Node.js native addon modules.
It is basically the "swiss army knife" of `require()`ing your native module's
`.node` file.

Throughout the course of Node's native addon history, addons have ended up being
compiled in a variety of different places, depending on which build tool and which
version of node was used. To make matters worse, now the _gyp_ build tool can
produce either a _Release_ or _Debug_ build, each being built into different
version of node was used. To make matters worse, now the `gyp` build tool can
produce either a __Release__ or __Debug__ build, each being built into different
locations.

This module checks _all_ the possible locations that a native addon would be built
@@ -22,10 +22,10 @@ Installation
Install with `npm`:

``` bash
$ npm install bindings
$ npm install --save bindings
```

Or add it to the `"dependencies"` section of your _package.json_ file.
Or add it to the `"dependencies"` section of your `package.json` file.


Example
@@ -69,6 +69,7 @@ Error: Could not load the bindings file. Tried:
...
```

The searching for the `.node` file will originate from the first directory in which has a `package.json` file is found.

License
-------
239 changes: 147 additions & 92 deletions bindings.js
Original file line number Diff line number Diff line change
@@ -1,137 +1,186 @@

/**
* Module dependencies.
*/

var fs = require('fs')
, path = require('path')
, join = path.join
, dirname = path.dirname
, exists = fs.existsSync || path.existsSync
, defaults = {
arrow: process.env.NODE_BINDINGS_ARROW || ' → '
, compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled'
, platform: process.platform
, arch: process.arch
, version: process.versions.node
, bindings: 'bindings.node'
, try: [
// node-gyp's linked version in the "build" dir
[ 'module_root', 'build', 'bindings' ]
// node-waf and gyp_addon (a.k.a node-gyp)
, [ 'module_root', 'build', 'Debug', 'bindings' ]
, [ 'module_root', 'build', 'Release', 'bindings' ]
// Debug files, for development (legacy behavior, remove for node v0.9)
, [ 'module_root', 'out', 'Debug', 'bindings' ]
, [ 'module_root', 'Debug', 'bindings' ]
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
, [ 'module_root', 'out', 'Release', 'bindings' ]
, [ 'module_root', 'Release', 'bindings' ]
// Legacy from node-waf, node <= 0.4.x
, [ 'module_root', 'build', 'default', 'bindings' ]
// Production "Release" buildtype binary (meh...)
, [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ]
]
}
var fs = require('fs'),
path = require('path'),
fileURLToPath = require('file-uri-to-path'),
join = path.join,
dirname = path.dirname,
exists =
(fs.accessSync &&
function(path) {
try {
fs.accessSync(path);
} catch (e) {
return false;
}
return true;
}) ||
fs.existsSync ||
path.existsSync,
defaults = {
arrow: process.env.NODE_BINDINGS_ARROW || ' → ',
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled',
platform: process.platform,
arch: process.arch,
nodePreGyp:
'node-v' +
process.versions.modules +
'-' +
process.platform +
'-' +
process.arch,
version: process.versions.node,
bindings: 'bindings.node',
try: [
// node-gyp's linked version in the "build" dir
['module_root', 'build', 'bindings'],
// node-waf and gyp_addon (a.k.a node-gyp)
['module_root', 'build', 'Debug', 'bindings'],
['module_root', 'build', 'Release', 'bindings'],
// Debug files, for development (legacy behavior, remove for node v0.9)
['module_root', 'out', 'Debug', 'bindings'],
['module_root', 'Debug', 'bindings'],
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
['module_root', 'out', 'Release', 'bindings'],
['module_root', 'Release', 'bindings'],
// Legacy from node-waf, node <= 0.4.x
['module_root', 'build', 'default', 'bindings'],
// Production "Release" buildtype binary (meh...)
['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'],
// node-qbs builds
['module_root', 'addon-build', 'release', 'install-root', 'bindings'],
['module_root', 'addon-build', 'debug', 'install-root', 'bindings'],
['module_root', 'addon-build', 'default', 'install-root', 'bindings'],
// node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings']
]
};

/**
* The main `bindings()` function loads the compiled bindings for a given module.
* It uses V8's Error API to determine the parent filename that this function is
* being invoked from, which is then used to find the root directory.
*/

function bindings (opts) {

function bindings(opts) {
// Argument surgery
if (typeof opts == 'string') {
opts = { bindings: opts }
opts = { bindings: opts };
} else if (!opts) {
opts = {}
opts = {};
}
opts.__proto__ = defaults

// maps `defaults` onto `opts` object
Object.keys(defaults).map(function(i) {
if (!(i in opts)) opts[i] = defaults[i];
});

// Get the module root
if (!opts.module_root) {
opts.module_root = exports.getRoot(exports.getFileName())
opts.module_root = exports.getRoot(exports.getFileName());
}

// Ensure the given bindings name ends with .node
if (path.extname(opts.bindings) != '.node') {
opts.bindings += '.node'
opts.bindings += '.node';
}

var tries = []
, i = 0
, l = opts.try.length
, n
, b
, err

for (; i<l; i++) {
n = join.apply(null, opts.try[i].map(function (p) {
return opts[p] || p
}))
tries.push(n)
// https://github.com/webpack/webpack/issues/4175#issuecomment-342931035
var requireFunc =
typeof __webpack_require__ === 'function'
? __non_webpack_require__
: require;

var tries = [],
i = 0,
l = opts.try.length,
n,
b,
err;

for (; i < l; i++) {
n = join.apply(
null,
opts.try[i].map(function(p) {
return opts[p] || p;
})
);
tries.push(n);
try {
b = opts.path ? require.resolve(n) : require(n)
b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
if (!opts.path) {
b.path = n
b.path = n;
}
return b
return b;
} catch (e) {
if (!/not find/i.test(e.message)) {
throw e
if (e.code !== 'MODULE_NOT_FOUND' &&
e.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED' &&
!/not find/i.test(e.message)) {
throw e;
}
}
}

err = new Error('Could not locate the bindings file. Tried:\n'
+ tries.map(function (a) { return opts.arrow + a }).join('\n'))
err.tries = tries
throw err
err = new Error(
'Could not locate the bindings file. Tried:\n' +
tries
.map(function(a) {
return opts.arrow + a;
})
.join('\n')
);
err.tries = tries;
throw err;
}
module.exports = exports = bindings

module.exports = exports = bindings;

/**
* Gets the filename of the JavaScript file that invokes this function.
* Used to help find the root directory of a module.
* Optionally accepts an filename argument to skip when searching for the invoking filename
*/

exports.getFileName = function getFileName (calling_file) {
var origPST = Error.prepareStackTrace
, origSTL = Error.stackTraceLimit
, dummy = {}
, fileName
exports.getFileName = function getFileName(calling_file) {
var origPST = Error.prepareStackTrace,
origSTL = Error.stackTraceLimit,
dummy = {},
fileName;

Error.stackTraceLimit = 10
Error.stackTraceLimit = 10;

Error.prepareStackTrace = function (e, st) {
for (var i=0, l=st.length; i<l; i++) {
fileName = st[i].getFileName()
Error.prepareStackTrace = function(e, st) {
for (var i = 0, l = st.length; i < l; i++) {
fileName = st[i].getFileName();
if (fileName !== __filename) {
if (calling_file) {
if (fileName !== calling_file) {
return
}
if (fileName !== calling_file) {
return;
}
} else {
return
return;
}
}
}
}
};

// run the 'prepareStackTrace' function above
Error.captureStackTrace(dummy)
dummy.stack
Error.captureStackTrace(dummy);
dummy.stack;

// cleanup
Error.prepareStackTrace = origPST
Error.stackTraceLimit = origSTL
Error.prepareStackTrace = origPST;
Error.stackTraceLimit = origSTL;

return fileName
}
// handle filename that starts with "file://"
var fileSchema = 'file://';
if (fileName.indexOf(fileSchema) === 0) {
fileName = fileURLToPath(fileName);
}

return fileName;
};

/**
* Gets the root directory of a module, given an arbitrary filename
@@ -142,25 +191,31 @@ exports.getFileName = function getFileName (calling_file) {
* Out: /home/nate/node-native-module
*/

exports.getRoot = function getRoot (file) {
var dir = dirname(file)
, prev
exports.getRoot = function getRoot(file) {
var dir = dirname(file),
prev;
while (true) {
if (dir === '.') {
// Avoids an infinite loop in rare cases, like the REPL
dir = process.cwd()
dir = process.cwd();
}
if (exists(join(dir, 'package.json')) || exists(join(dir, 'node_modules'))) {
if (
exists(join(dir, 'package.json')) ||
exists(join(dir, 'node_modules'))
) {
// Found the 'package.json' file or 'node_modules' dir; we're done
return dir
return dir;
}
if (prev === dir) {
// Got to the top
throw new Error('Could not find module root given file: "' + file
+ '". Do you have a `package.json` file? ')
throw new Error(
'Could not find module root given file: "' +
file +
'". Do you have a `package.json` file? '
);
}
// Try the parent dir next
prev = dir
dir = join(dir, '..')
prev = dir;
dir = join(dir, '..');
}
}
};
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
"c",
"c++"
],
"version": "1.2.1",
"version": "1.5.0",
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://tootallnate.net)",
"repository": {
"type": "git",
@@ -21,5 +21,8 @@
"url": "https://github.com/TooTallNate/node-bindings/issues"
},
"homepage": "https://github.com/TooTallNate/node-bindings",
"license": "MIT"
"license": "MIT",
"dependencies": {
"file-uri-to-path": "1.0.0"
}
}