Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require Node.js 12.20 and move to ESM #181

Merged
merged 4 commits into from Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
65 changes: 34 additions & 31 deletions bench.js
@@ -1,95 +1,98 @@
'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 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);
}
},
}, {
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, '');
}
});
for (const directory of ['a', 'b']
antongolub marked this conversation as resolved.
Show resolved Hide resolved
.map(directory => `${directory}/`)) {
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));
}
});
});
}
45 changes: 23 additions & 22 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 getIsIgnoredPredecate = (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,23 +77,21 @@ 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 gitignore = 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)));
Expand All @@ -105,16 +100,22 @@ module.exports = async options => {
return getIsIgnoredPredecate(ignores, options.cwd);
};

module.exports.sync = options => {
export const gitignoreSync = 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);
};

// Legacy API
gitignore.sync = gitignoreSync;
antongolub marked this conversation as resolved.
Show resolved Hide resolved

export default gitignore;
antongolub marked this conversation as resolved.
Show resolved Hide resolved

15 changes: 9 additions & 6 deletions gitignore.test.js
@@ -1,7 +1,10 @@
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 {gitignore} from './gitignore.js';

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

test('gitignore', async t => {
const cwd = path.join(__dirname, 'fixtures/gitignore');
Expand Down Expand Up @@ -75,7 +78,7 @@ test('multiple negation', async t => {
'!!!unicorn.js',
'!!unicorn.js',
'!unicorn.js',
'unicorn.js'
'unicorn.js',
].filter(file => !isIgnored(file));

const expected = ['!!unicorn.js', '!unicorn.js'];
Expand All @@ -90,7 +93,7 @@ test('multiple negation - sync', t => {
'!!!unicorn.js',
'!!unicorn.js',
'!unicorn.js',
'unicorn.js'
'unicorn.js',
].filter(file => !isIgnored(file));

const expected = ['!!unicorn.js', '!unicorn.js'];
Expand Down
2 changes: 2 additions & 0 deletions index.d.ts
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/member-ordering, @typescript-eslint/no-redeclare */

import {Options as FastGlobOptions, Entry as FastGlobEntry} from 'fast-glob';

declare namespace globby {
Expand Down