Skip to content

Commit

Permalink
Major improvements
Browse files Browse the repository at this point in the history
* Introduce semver version checks
* Use new `download` API
* Get the full path to the binary using the `.path()` method
* Use underscored names for private methods
  • Loading branch information
kevva committed Aug 11, 2014
1 parent 19ee5a3 commit 85a9d04
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 75 deletions.
49 changes: 25 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,61 @@ $ npm install --save bin-wrapper

```js
var BinWrapper = require('bin-wrapper');
var bin = new BinWrapper({ global: true });

bin
var bin = new BinWrapper();
.src('https://raw.github.com/yeoman/node-jpegtran-bin/0.2.4/vendor/win/x64/jpegtran.exe', 'win32', 'x64')
.src('https://raw.github.com/yeoman/node-jpegtran-bin/0.2.4/vendor/win/x64/libjpeg-62.dll', 'win32', 'x64')
.dest('vendor')
.use('jpegtran.exe')
.run(['--version'], function (err) {
if (err) {
throw err;
}
.version('>=1.3.0');

console.log('jpegtran is working');
});
bin.run(['--version'], function (err) {
if (err) {
throw err;
}

console.log('jpegtran is working');
});
```

Get the path to your binary with `bin.use()`:
Get the path to your binary with `bin.path()`:

```js
console.log(bin.use()); // => path/to/vendor/jpegtran.exe
console.log(bin.path()); // => path/to/vendor/jpegtran.exe
```

## API

### new BinWrapper(opts)
### new BinWrapper()

Creates a new `BinWrapper` instance. Use the `global` option to enable or disable global checking.
Creates a new `BinWrapper` instance.

### .src(str)
### .src(url, os, arch)

Accepts a URL pointing to a file to download.

### .dest(str)
### .dest(dest)

Accepts a path which the files will be downloaded to.

### .use(str)
### .use(bin)

Define which file to use as the binary.

### .run(cmd, cb)
### .path()

Runs the search for the binary. If no binary is found it will download the file using the URL
provided in `.src()`. It will also check that the binary is working by running it using `cmd`
and checking it's exit code.
Get the full path to your binary.

## Options
### .version(range)

### global
Define a [semver range](https://github.com/isaacs/node-semver#ranges) to check
the binary against.

Type: `Boolean`
Default: `true`
### .run(cmd, cb)

Whether to check for a binary globally or not.
Runs the search for the binary. If no binary is found it will download the file using the URL
provided in `.src()`. It will also check that the binary is working by running it using `cmd`
and checking it's exit code.

## License

Expand Down
128 changes: 82 additions & 46 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
'use strict';

var binCheck = require('bin-check');
var binVersionCheck = require('bin-version-check');
var find = require('find-file');
var path = require('path');

/**
* Initialize a new `BinWrapper` with opts
* Initialize a new `BinWrapper`
*
* @param {Object} opts
* @api public
*/

function BinWrapper(opts) {
if (!(this instanceof BinWrapper)) {
return new BinWrapper();
}

opts = opts || {};
this.opts = opts;
this.global = opts.global !== false;
function BinWrapper() {
this._src = [];
}

/**
* Define a binary to download
* Add a file to download
*
* @param {String} src
* @param {String} os
Expand Down Expand Up @@ -51,115 +44,159 @@ BinWrapper.prototype.src = function (src, os, arch) {
};

/**
* Define where to download the binary to
* Define where to download the file to
*
* @param {String} str
* @param {String} dest
* @api public
*/

BinWrapper.prototype.dest = function (str) {
BinWrapper.prototype.dest = function (dest) {
if (!arguments.length) {
return this._dest;
}

this._dest = str;
this._dest = dest;
return this;
};

/**
* Define which file to use as a binary
*
* @param {String} str
* @param {String} bin
* @api public
*/

BinWrapper.prototype.use = function (str) {
BinWrapper.prototype.use = function (bin) {
if (!arguments.length) {
return this._use;
}

this._use = bin;
return this;
};

/**
* Get the bin path
*
* @api public
*/

BinWrapper.prototype.path = function () {
var opts = { path: this.dest(), global: this.global, exclude: 'node_modules/.bin' };
var bin = find(str, opts);
var bin = find(this.use(), opts);
var dir;

if (bin && bin.length > 0) {
this._use = bin[0];
dir = bin[0];
} else {
this._use = path.join(this.dest(), str);
dir = path.join(this.dest(), this.use());
}

return dir;
};

/**
* Define a semver range to test the binary against
*
* @param {String} range
* @api public
*/

BinWrapper.prototype.version = function (range) {
if (!arguments.length) {
return this._version;
}

this._version = range;
return this;
};

/**
* Run
* Run bin-wrapper
*
* @param {Array} cmd
* @param {Function} cb
* @api public
*/

BinWrapper.prototype.run = function (cmd, cb) {
var download = require('download');
var Download = require('download');
var files = this._parse(this.src());
var self = this;

this.parse(this.src());
this.test(cmd, function (err) {
this._test(cmd, function (err) {
if (err) {
return download(self.src(), self.dest(), { mode: '0755' })
.on('error', function (err) {
var download = new Download();

files.forEach(function (file) {
download.get(file, self.dest());
});

return download.run(function (err) {
if (err) {
return cb(err);
})
.on('close', function () {
self.test(cmd, function (err) {
if (err) {
return cb(err);
}

cb();
});
}

self._test(cmd, function (err) {
if (err) {
return cb(err);
}

cb();
});
});
}

cb();
});
};

/**
* Test
* Test binary
*
* @param {Array} cmd
* @param {Function} cb
* @api public
* @api private
*/

BinWrapper.prototype.test = function (cmd, cb) {
BinWrapper.prototype._test = function (cmd, cb) {
var self = this;

if (this.use()) {
return binCheck(self.use(), cmd, function (err, works) {
if (this.path()) {
return binCheck(self.path(), cmd, function (err, works) {
if (err) {
return cb(err);
}

if (!works) {
return cb('command failed');
return cb(new Error('The `' + self.use() + '` binary doesn\'t seem to work correctly.'));
}

if (self.version()) {
return binVersionCheck(self.path(), self.version(), function (err) {
if (err) {
return cb(err);
}

cb();
});
}

cb();
});
}

cb('no binary found');
cb(new Error('Couldn\'t find the `' + this.use() + '` binary. Make sure it\'s installed and in your $PATH.'));
};

/**
* Parse
*
* @param {Object} obj
* @api public
* @api private
*/

BinWrapper.prototype.parse = function (obj) {
BinWrapper.prototype._parse = function (obj) {
var arch = process.arch === 'x64' ? 'x64' : process.arch === 'arm' ? 'arm' : 'x86';
var ret = [];

Expand All @@ -173,8 +210,7 @@ BinWrapper.prototype.parse = function (obj) {
}
});

this._src = ret;
return this;
return ret;
};

/**
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
],
"dependencies": {
"bin-check": "^0.1.0",
"download": "^0.1.2",
"bin-version-check": "^0.1.0",
"download": "^0.2.0",
"find-file": "^0.1.2"
},
"devDependencies": {
Expand Down
28 changes: 24 additions & 4 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,35 @@ describe('BinWrapper()', function () {

it('should verify that a binary is working', function (cb) {
var bin = new Bin()
.src('https://raw.github.com/yeoman/node-gifsicle/0.1.5/vendor/osx/gifsicle', 'darwin')
.src('https://raw.github.com/yeoman/node-gifsicle/0.1.5/vendor/linux/x64/gifsicle', 'linux', 'x64')
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/osx/gifsicle', 'darwin')
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/linux/x64/gifsicle', 'linux', 'x64')
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/win/x64/gifsicle.exe', 'win32', 'x64')
.dest(path.join(__dirname, 'tmp'))
.use('gifsicle');
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');

bin.run(['--version'], function (err) {
assert(!err);

fs.exists(bin.use(), function (exists) {
fs.exists(bin.path(), function (exists) {
assert(exists);
cb();
});
});
});

it('should meet the desired version', function (cb) {
var bin = new Bin()
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/osx/gifsicle', 'darwin')
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/linux/x64/gifsicle', 'linux', 'x64')
.src('https://github.com/imagemin/gifsicle-bin/raw/master/vendor/win/x64/gifsicle.exe', 'win32', 'x64')
.dest(path.join(__dirname, 'tmp'))
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle')
.version('>=1.71');

bin.run(['--version'], function (err) {
assert(!err);

fs.exists(bin.path(), function (exists) {
assert(exists);
cb();
});
Expand Down

0 comments on commit 85a9d04

Please sign in to comment.