Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Require Node.js 12.20 and move to ESM (#181)
  • Loading branch information
antongolub committed Jul 22, 2021
1 parent 94e192c commit 5c32b4a
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 334 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Expand Up @@ -10,16 +10,16 @@ jobs:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
- 10
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
69 changes: 37 additions & 32 deletions bench.js
@@ -1,95 +1,100 @@
'use strict';
/* global after, before, bench, suite */
const fs = require('fs');
const rimraf = require('rimraf');
const globbyMainBranch = require('globby');
const gs = require('glob-stream');
const fastGlob = require('fast-glob');
const globby = require('.');
import fs from 'node:fs';
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import rimraf from 'rimraf';
import globbyMainBranch from 'globby';
import gs from 'glob-stream';
import fastGlob from 'fast-glob';
import {globby, globbySync} from './index.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const BENCH_DIR = 'bench';

const runners = [{
name: 'globby async (working directory)',
run: async (patterns, callback) => {
await globby(patterns);
callback();
}
},
}, {
name: 'globby async (upstream/main)',
run: async (patterns, callback) => {
await globbyMainBranch(patterns);
callback();
}
},
}, {
name: 'globby sync (working directory)',
run: patterns => {
globby.sync(patterns);
}
globbySync(patterns);
},
}, {
name: 'globby sync (upstream/main)',
run: patterns => {
globbyMainBranch.sync(patterns);
}
},
}, {
name: 'glob-stream',
run: (patterns, cb) => {
gs(patterns).on('data', () => {}).on('end', cb);
}
},
}, {
name: 'fast-glob async',
run: async (patterns, callback) => {
await fastGlob(patterns);
callback();
}
},
}, {
name: 'fast-glob sync',
run: patterns => {
fastGlob.sync(patterns);
}
},
}];
const benchs = [{
name: 'negative globs (some files inside dir)',
patterns: [
'a/*',
'!a/c*'
]
'!a/c*',
],
}, {
name: 'negative globs (whole dir)',
patterns: [
'a/*',
'!a/**'
]
'!a/**',
],
}, {
name: 'multiple positive globs',
patterns: [
'a/*',
'b/*'
]
'b/*',
],
}];

before(() => {
process.chdir(__dirname);
rimraf.sync(BENCH_DIR);
fs.mkdirSync(BENCH_DIR);
process.chdir(BENCH_DIR);
['a', 'b']
.map(directory => `${directory}/`)
.forEach(directory => {
fs.mkdirSync(directory);
for (let i = 0; i < 500; i++) {
fs.writeFileSync(directory + (i < 100 ? 'c' : 'd') + i, '');
}
});
const directories = ['a', 'b']
.map(directory => `${directory}/`);

for (const directory of directories) {
fs.mkdirSync(directory);
for (let i = 0; i < 500; i++) {
fs.writeFileSync(directory + (i < 100 ? 'c' : 'd') + i, '');
}
}
});

after(() => {
process.chdir(__dirname);
rimraf.sync(BENCH_DIR);
});

benchs.forEach(benchmark => {
for (const benchmark of benchs) {
suite(benchmark.name, () => {
runners.forEach(runner => bench(runner.name, runner.run.bind(null, benchmark.patterns)));
for (const runner of runners) {
bench(runner.name, runner.run.bind(null, benchmark.patterns));
}
});
});
}
44 changes: 20 additions & 24 deletions gitignore.js
@@ -1,16 +1,15 @@
'use strict';
const {promisify} = require('util');
const fs = require('fs');
const path = require('path');
const fastGlob = require('fast-glob');
const gitIgnore = require('ignore');
const slash = require('slash');
import {promisify} from 'node:util';
import fs from 'node:fs';
import path from 'node:path';
import fastGlob from 'fast-glob';
import gitIgnore from 'ignore';
import slash from 'slash';

const DEFAULT_IGNORE = [
'**/node_modules/**',
'**/flow-typed/**',
'**/coverage/**',
'**/.git'
'**/.git',
];

const readFileP = promisify(fs.readFile);
Expand Down Expand Up @@ -38,7 +37,7 @@ const reduceIgnore = files => {
for (const file of files) {
ignores.add(parseGitIgnore(file.content, {
cwd: file.cwd,
fileName: file.filePath
fileName: file.filePath,
}));
}

Expand All @@ -58,9 +57,7 @@ const ensureAbsolutePathForCwd = (cwd, p) => {
return path.join(cwd, p);
};

const getIsIgnoredPredecate = (ignores, cwd) => {
return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p.path || p))));
};
const getIsIgnoredPredicate = (ignores, cwd) => p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p.path || p))));

const getFile = async (file, cwd) => {
const filePath = path.join(cwd, file);
Expand All @@ -69,7 +66,7 @@ const getFile = async (file, cwd) => {
return {
cwd,
filePath,
content
content,
};
};

Expand All @@ -80,41 +77,40 @@ const getFileSync = (file, cwd) => {
return {
cwd,
filePath,
content
content,
};
};

const normalizeOptions = ({
ignore = [],
cwd = slash(process.cwd())
} = {}) => {
return {ignore, cwd};
};
cwd = slash(process.cwd()),
} = {}) => ({ignore, cwd});

module.exports = async options => {
export const isGitIgnored = async options => {
options = normalizeOptions(options);

const paths = await fastGlob('**/.gitignore', {
ignore: DEFAULT_IGNORE.concat(options.ignore),
cwd: options.cwd
cwd: options.cwd,
});

const files = await Promise.all(paths.map(file => getFile(file, options.cwd)));
const ignores = reduceIgnore(files);

return getIsIgnoredPredecate(ignores, options.cwd);
return getIsIgnoredPredicate(ignores, options.cwd);
};

module.exports.sync = options => {
export const isGitIgnoredSync = options => {
options = normalizeOptions(options);

const paths = fastGlob.sync('**/.gitignore', {
ignore: DEFAULT_IGNORE.concat(options.ignore),
cwd: options.cwd
cwd: options.cwd,
});

const files = paths.map(file => getFileSync(file, options.cwd));
const ignores = reduceIgnore(files);

return getIsIgnoredPredecate(ignores, options.cwd);
return getIsIgnoredPredicate(ignores, options.cwd);
};

35 changes: 19 additions & 16 deletions gitignore.test.js
@@ -1,31 +1,34 @@
const path = require('path');
const test = require('ava');
const slash = require('slash');
const gitignore = require('./gitignore');
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import test from 'ava';
import slash from 'slash';
import {isGitIgnored, isGitIgnoredSync} from './gitignore.js';

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

test('gitignore', async t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const isIgnored = await gitignore({cwd});
const isIgnored = await isGitIgnored({cwd});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['bar.js'];
t.deepEqual(actual, expected);
});

test('gitignore - mixed path styles', async t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const isIgnored = await gitignore({cwd});
const isIgnored = await isGitIgnored({cwd});
t.true(isIgnored(slash(path.resolve(cwd, 'foo.js'))));
});

test('gitignore - os paths', async t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const isIgnored = await gitignore({cwd});
const isIgnored = await isGitIgnored({cwd});
t.true(isIgnored(path.resolve(cwd, 'foo.js')));
});

test('gitignore - sync', t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const isIgnored = gitignore.sync({cwd});
const isIgnored = isGitIgnoredSync({cwd});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['bar.js'];
t.deepEqual(actual, expected);
Expand All @@ -35,7 +38,7 @@ test('ignore ignored .gitignore', async t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const ignore = ['**/.gitignore'];

const isIgnored = await gitignore({cwd, ignore});
const isIgnored = await isGitIgnored({cwd, ignore});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['foo.js', 'bar.js'];
t.deepEqual(actual, expected);
Expand All @@ -45,37 +48,37 @@ test('ignore ignored .gitignore - sync', t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
const ignore = ['**/.gitignore'];

const isIgnored = gitignore.sync({cwd, ignore});
const isIgnored = isGitIgnoredSync({cwd, ignore});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['foo.js', 'bar.js'];
t.deepEqual(actual, expected);
});

test('negative gitignore', async t => {
const cwd = path.join(__dirname, 'fixtures/negative');
const isIgnored = await gitignore({cwd});
const isIgnored = await isGitIgnored({cwd});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['foo.js'];
t.deepEqual(actual, expected);
});

test('negative gitignore - sync', t => {
const cwd = path.join(__dirname, 'fixtures/negative');
const isIgnored = gitignore.sync({cwd});
const isIgnored = isGitIgnoredSync({cwd});
const actual = ['foo.js', 'bar.js'].filter(file => !isIgnored(file));
const expected = ['foo.js'];
t.deepEqual(actual, expected);
});

test('multiple negation', async t => {
const cwd = path.join(__dirname, 'fixtures/multiple-negation');
const isIgnored = await gitignore({cwd});
const isIgnored = await isGitIgnored({cwd});

const actual = [
'!!!unicorn.js',
'!!unicorn.js',
'!unicorn.js',
'unicorn.js'
'unicorn.js',
].filter(file => !isIgnored(file));

const expected = ['!!unicorn.js', '!unicorn.js'];
Expand All @@ -84,13 +87,13 @@ test('multiple negation', async t => {

test('multiple negation - sync', t => {
const cwd = path.join(__dirname, 'fixtures/multiple-negation');
const isIgnored = gitignore.sync({cwd});
const isIgnored = isGitIgnoredSync({cwd});

const actual = [
'!!!unicorn.js',
'!!unicorn.js',
'!unicorn.js',
'unicorn.js'
'unicorn.js',
].filter(file => !isIgnored(file));

const expected = ['!!unicorn.js', '!unicorn.js'];
Expand Down

0 comments on commit 5c32b4a

Please sign in to comment.