Skip to content

Commit

Permalink
Update all the stuff, switch to ESM, require Node.js 12
Browse files Browse the repository at this point in the history
Also, add coverage with c8
  • Loading branch information
XhmikosR committed Jun 6, 2022
1 parent 44dca3d commit 4bc5c9e
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 85 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [6, 8, 10, 12, 14, 16]
node: [12, 14, 16, 18]
os: [ubuntu-latest, windows-latest]

steps:
- name: Clone repository
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}

- name: Install npm dependencies
run: npm install

- name: Run tests
run: npm test
run: npm run test-ci
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
yarn.lock
/coverage
62 changes: 20 additions & 42 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
'use strict';
const fs = require('fs');
const path = require('path');
const url = require('url');
const pify = require('pify');
const importLazy = require('import-lazy')(require);

const binCheck = importLazy('bin-check');
const binVersionCheck = importLazy('bin-version-check');
const download = importLazy('download');
const osFilterObj = importLazy('os-filter-obj');

const statAsync = pify(fs.stat);
const chmodAsync = pify(fs.chmod);
import {promises as fs} from 'node:fs';
import path from 'node:path';
import binCheck from 'bin-check';
import binVersionCheck from 'bin-version-check';
import download from 'download';
import osFilterObject from 'os-filter-obj';

/**
* Initialize a new `BinWrapper`
*
* @param {Object} options
* @api public
*/
module.exports = class BinWrapper {
export default class BinWrapper {
constructor(options = {}) {
this.options = options;

Expand Down Expand Up @@ -47,7 +39,7 @@ module.exports = class BinWrapper {
this._src.push({
url: src,
os,
arch
arch,
});

return this;
Expand Down Expand Up @@ -138,8 +130,6 @@ module.exports = class BinWrapper {
if (this.version()) {
return binVersionCheck(this.path(), this.version());
}

return Promise.resolve();
});
}

Expand All @@ -149,12 +139,12 @@ module.exports = class BinWrapper {
* @api private
*/
findExisting() {
return statAsync(this.path()).catch(error => {
return fs.stat(this.path()).catch(error => {
if (error && error.code === 'ENOENT') {
return this.download();
}

return Promise.reject(error);
throw error;
});
}

Expand All @@ -164,45 +154,33 @@ module.exports = class BinWrapper {
* @api private
*/
download() {
const files = osFilterObj(this.src() || []);
const urls = [];
const files = osFilterObject(this.src() || []);

if (files.length === 0) {
return Promise.reject(new Error('No binary found matching your system. It\'s probably not supported.'));
}

files.forEach(file => urls.push(file.url));
const urls = [];
for (const file of files) {
urls.push(file.url);
}

return Promise.all(urls.map(url => download(url, this.dest(), {
extract: true,
strip: this.options.strip
strip: this.options.strip,
}))).then(result => {
const resultingFiles = flatten(result.map((item, index) => {
const resultingFiles = result.flatMap((item, index) => {
if (Array.isArray(item)) {
return item.map(file => file.path);
}

const parsedUrl = url.parse(files[index].url);
const parsedUrl = new URL(files[index].url);
const parsedPath = path.parse(parsedUrl.pathname);

return parsedPath.base;
}));
});

return Promise.all(resultingFiles.map(fileName => {
return chmodAsync(path.join(this.dest(), fileName), 0o755);
}));
return Promise.all(resultingFiles.map(fileName => fs.chmod(path.join(this.dest(), fileName), 0o755)));
});
}
};

function flatten(arr) {
return arr.reduce((acc, elem) => {
if (Array.isArray(elem)) {
acc.push(...elem);
} else {
acc.push(elem);
}

return acc;
}, []);
}
39 changes: 26 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@
"url": "https://github.com/kevva"
},
"engines": {
"node": ">=6"
"node": "^12.20.0 || ^14.14.0 || >=16.0.0"
},
"scripts": {
"test": "xo && ava"
"ava": "ava",
"xo": "xo",
"test": "npm run xo && npm run ava",
"test-ci": "npm run xo && c8 ava"
},
"main": "index.js",
"type": "module",
"exports": {
".": "./index.js"
},
"files": [
"index.js"
Expand All @@ -24,21 +32,26 @@
"local",
"wrapper"
],
"c8": {
"reporter": [
"lcovonly",
"text"
]
},
"dependencies": {
"bin-check": "^4.1.0",
"bin-version-check": "^4.0.0",
"download": "^7.1.0",
"import-lazy": "^3.1.0",
"os-filter-obj": "^2.0.0",
"pify": "^4.0.1"
"bin-version-check": "^5.0.0",
"download": "^8.0.0",
"os-filter-obj": "^2.0.0"
},
"devDependencies": {
"ava": "*",
"ava": "^4.3.0",
"c8": "^7.11.3",
"executable": "^4.1.1",
"nock": "^10.0.2",
"path-exists": "^3.0.0",
"rimraf": "^2.6.2",
"tempy": "^0.2.1",
"xo": "*"
"nock": "^13.2.6",
"path-exists": "^5.0.0",
"rimraf": "^3.0.2",
"tempy": "^2.0.0",
"xo": "^0.49.0"
}
}
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ npm install bin-wrapper
## Usage

```js
const BinWrapper = require('bin-wrapper');
import path from 'node:path';
import BinWrapper from 'bin-wrapper';

const base = 'https://github.com/imagemin/gifsicle-bin/raw/main/vendor';
const bin = new BinWrapper()
Expand Down
55 changes: 30 additions & 25 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import fs from 'fs';
import path from 'path';
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import {promisify} from 'node:util';
import {fileURLToPath} from 'node:url';
import executable from 'executable';
import nock from 'nock';
import pathExists from 'path-exists';
import pify from 'pify';
import {pathExists} from 'path-exists';
import rimraf from 'rimraf';
import test from 'ava';
import tempy from 'tempy';
import executable from 'executable';
import Fn from '.';
import test from 'ava';
import BinWrapper from './index.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));

const rimrafP = pify(rimraf);
const rimrafP = promisify(rimraf);
const fixture = path.join.bind(path, __dirname, 'fixtures');

test.beforeEach(() => {
nock('http://foo.com')
.get('/gifsicle.tar.gz')
.replyWithFile(200, fixture('gifsicle-' + process.platform + '.tar.gz'))
.replyWithFile(200, fixture(`gifsicle-${process.platform}.tar.gz`))
.get('/gifsicle-darwin.tar.gz')
.replyWithFile(200, fixture('gifsicle-darwin.tar.gz'))
.get('/gifsicle-win32.tar.gz')
Expand All @@ -25,44 +30,44 @@ test.beforeEach(() => {
});

test('expose a constructor', t => {
t.is(typeof Fn, 'function');
t.is(typeof BinWrapper, 'function');
});

test('add a source', t => {
const bin = new Fn().src('http://foo.com/bar.tar.gz');
const bin = new BinWrapper().src('http://foo.com/bar.tar.gz');
t.is(bin._src[0].url, 'http://foo.com/bar.tar.gz');
});

test('add a source to a specific os', t => {
const bin = new Fn().src('http://foo.com', process.platform);
const bin = new BinWrapper().src('http://foo.com', process.platform);
t.is(bin._src[0].os, process.platform);
});

test('set destination directory', t => {
const bin = new Fn().dest(path.join(__dirname, 'foo'));
const bin = new BinWrapper().dest(path.join(__dirname, 'foo'));
t.is(bin._dest, path.join(__dirname, 'foo'));
});

test('set which file to use as the binary', t => {
const bin = new Fn().use('foo');
const bin = new BinWrapper().use('foo');
t.is(bin._use, 'foo');
});

test('set a version range to test against', t => {
const bin = new Fn().version('1.0.0');
const bin = new BinWrapper().version('1.0.0');
t.is(bin._version, '1.0.0');
});

test('get the binary path', t => {
const bin = new Fn()
const bin = new BinWrapper()
.dest('tmp')
.use('foo');

t.is(bin.path(), path.join('tmp', 'foo'));
});

test('verify that a binary is working', async t => {
const bin = new Fn()
const bin = new BinWrapper()
.src('http://foo.com/gifsicle.tar.gz')
.dest(tempy.directory())
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');
Expand All @@ -73,7 +78,7 @@ test('verify that a binary is working', async t => {
});

test('meet the desired version', async t => {
const bin = new Fn()
const bin = new BinWrapper()
.src('http://foo.com/gifsicle.tar.gz')
.dest(tempy.directory())
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle')
Expand All @@ -85,7 +90,7 @@ test('meet the desired version', async t => {
});

test('download files even if they are not used', async t => {
const bin = new Fn({strip: 0, skipCheck: true})
const bin = new BinWrapper({strip: 0, skipCheck: true})
.src('http://foo.com/gifsicle-darwin.tar.gz')
.src('http://foo.com/gifsicle-win32.tar.gz')
.src('http://foo.com/test.js')
Expand All @@ -104,7 +109,7 @@ test('download files even if they are not used', async t => {
});

test('skip running binary check', async t => {
const bin = new Fn({skipCheck: true})
const bin = new BinWrapper({skipCheck: true})
.src('http://foo.com/gifsicle.tar.gz')
.dest(tempy.directory())
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');
Expand All @@ -115,15 +120,15 @@ test('skip running binary check', async t => {
});

test('error if no binary is found and no source is provided', async t => {
const bin = new Fn()
const bin = new BinWrapper()
.dest(tempy.directory())
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');

await t.throws(bin.run(), 'No binary found matching your system. It\'s probably not supported.');
await t.throwsAsync(bin.run(), undefined, 'No binary found matching your system. It\'s probably not supported.');
});

test('downloaded files are set to be executable', async t => {
const bin = new Fn({strip: 0, skipCheck: true})
const bin = new BinWrapper({strip: 0, skipCheck: true})
.src('http://foo.com/gifsicle-darwin.tar.gz')
.src('http://foo.com/gifsicle-win32.tar.gz')
.src('http://foo.com/test.js')
Expand All @@ -134,7 +139,7 @@ test('downloaded files are set to be executable', async t => {

const files = fs.readdirSync(bin.dest());

files.forEach(fileName => {
for (const fileName of files) {
t.true(executable.sync(path.join(bin.dest(), fileName)));
});
}
});

0 comments on commit 4bc5c9e

Please sign in to comment.