Skip to content

Commit

Permalink
Merge pull request #187 from mrmlnc/ISSUE-163_second_refactor
Browse files Browse the repository at this point in the history
ISSUE-163: Use `@nodelib/fs.walk` instead of `readdir-enhanced`
  • Loading branch information
mrmlnc authored May 25, 2019
2 parents 785d8b6 + 62be608 commit 811db58
Show file tree
Hide file tree
Showing 27 changed files with 313 additions and 274 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ fg.sync(['(special-*file).txt']) // → [] for files: ['(special-*file).txt']
Refers to Bash. You need to escape special characters:

```js
fg.sync(['\(special-*file\).txt']) // → ['(special-*file).txt']
fg.sync(['\\(special-*file\\).txt']) // → ['(special-*file).txt']
```

Read more about [«Matching special characters as literals»](https://github.com/micromatch/picomatch#matching-special-characters-as-literals).
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"implementation"
],
"devDependencies": {
"@nodelib/fs.macchiato": "^1.0.0",
"@types/compute-stdev": "^1.0.0",
"@types/easy-table": "^0.0.32",
"@types/execa": "^0.9.0",
Expand Down Expand Up @@ -48,7 +49,8 @@
"dependencies": {
"@mrmlnc/readdir-enhanced": "^2.2.1",
"@nodelib/fs.stat": "^2.0.0",
"glob-parent": "^3.1.0",
"@nodelib/fs.walk": "^1.1.0",
"glob-parent": "^5.0.0",
"is-glob": "^4.0.0",
"merge2": "^1.2.3",
"micromatch": "^4.0.2"
Expand All @@ -64,9 +66,9 @@
"bench": "npm run bench-async && npm run bench-sync",
"bench-async": "npm run bench-async-flatten && npm run bench-async-deep",
"bench-sync": "npm run bench-sync-flatten && npm run bench-sync-deep",
"bench-async-flatten": "node ./out/benchmark --type async --pattern *",
"bench-async-deep": "node ./out/benchmark --type async --pattern **",
"bench-sync-flatten": "node ./out/benchmark --type sync --pattern *",
"bench-sync-deep": "node ./out/benchmark --type sync --pattern **"
"bench-async-flatten": "node ./out/benchmark --type async --pattern \"*\"",
"bench-async-deep": "node ./out/benchmark --type async --pattern \"**\"",
"bench-sync-flatten": "node ./out/benchmark --type sync --pattern \"*\"",
"bench-sync-deep": "node ./out/benchmark --type sync --pattern \"**\""
}
}
19 changes: 6 additions & 13 deletions src/adapters/fs-stream.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as assert from 'assert';
import * as fs from 'fs';

import { Stats } from '@nodelib/fs.macchiato';

import Settings from '../settings';
import { Entry, Pattern } from '../types/index';
import FileSystemStream from './fs-stream';
Expand All @@ -11,7 +13,7 @@ class FileSystemStreamFake extends FileSystemStream {
}

public getStat(): Promise<fs.Stats> {
return getStats(1);
return Promise.resolve(new Stats());
}
}

Expand All @@ -25,14 +27,10 @@ class FileSystemStreamThrowStatError extends FileSystemStreamFake {
return Promise.reject(new Error('something'));
}

return getStats(1);
return Promise.resolve(new Stats());
}
}

function getStats(uid: number): Promise<fs.Stats> {
return Promise.resolve({ uid } as fs.Stats);
}

function getAdapter(): FileSystemStreamFake {
return new FileSystemStreamFake();
}
Expand Down Expand Up @@ -91,15 +89,10 @@ describe('Adapters → FileSystemStream', () => {
it('should return created entry', async () => {
const adapter = getAdapter();

const expected: Entry = {
path: 'pattern',
depth: 1,
uid: 1
} as Entry;

const actual = await adapter.getEntry('filepath', 'pattern');

assert.deepStrictEqual(actual, expected);
assert.strictEqual((actual as Entry).name, 'pattern');
assert.strictEqual((actual as Entry).path, 'pattern');
});

it('should return null when lstat throw error', async () => {
Expand Down
19 changes: 6 additions & 13 deletions src/adapters/fs-sync.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as assert from 'assert';
import * as fs from 'fs';

import { Stats } from '@nodelib/fs.macchiato';

import Settings from '../settings';
import { Entry, Pattern } from '../types/index';
import FileSystemSync from './fs-sync';
Expand All @@ -11,7 +13,7 @@ class FileSystemSyncFake extends FileSystemSync {
}

public getStat(): fs.Stats {
return getStats(1);
return new Stats();
}
}

Expand All @@ -28,14 +30,10 @@ class FileSystemSyncThrowStatError extends FileSystemSyncFake {
throw new Error('Something');
}

return getStats(1);
return new Stats();
}
}

function getStats(uid: number): fs.Stats {
return { uid } as fs.Stats;
}

function getAdapter(): FileSystemSyncFake {
return new FileSystemSyncFake();
}
Expand Down Expand Up @@ -85,15 +83,10 @@ describe('Adapters → FileSystemSync', () => {
it('should return created entry', () => {
const adapter = getAdapter();

const expected: Entry = {
path: 'pattern',
depth: 1,
uid: 1
} as Entry;

const actual = adapter.getEntry('filepath', 'pattern');

assert.deepStrictEqual(actual, expected);
assert.strictEqual((actual as Entry).name, 'pattern');
assert.strictEqual((actual as Entry).path, 'pattern');
});

it('should return null when lstat throw error', () => {
Expand Down
15 changes: 4 additions & 11 deletions src/adapters/fs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as assert from 'assert';
import * as path from 'path';

import { Stats } from '@nodelib/fs.macchiato';

import Settings from '../settings';
import * as tests from '../tests/index';
import FileSystem from './fs';

class FileSystemFake extends FileSystem<never[]> {
Expand Down Expand Up @@ -53,18 +54,10 @@ describe('Adapters → FileSystem', () => {
const adapter = getAdapter();

const filepath = path.join('base', 'file.json');
const actual = adapter.makeEntry(tests.getFileEntry(), filepath);
const actual = adapter.makeEntry(new Stats(), filepath);

assert.strictEqual(actual.path, filepath);
assert.strictEqual(actual.depth, 2);
});

it('issue-144: should return entry with methods from fs.Stats', () => {
const adapter = getAdapter();

const actual = adapter.makeEntry(tests.getFileEntry(), 'file.json');

assert.ok(actual.isFile());
assert.ok(actual.dirent.isFile());
});
});
});
16 changes: 12 additions & 4 deletions src/adapters/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as path from 'path';

import Settings from '../settings';
import { Entry, EntryFilterFunction, Pattern } from '../types/index';
import * as utils from '../utils/index';

export default abstract class FileSystem<T> {
constructor(private readonly _settings: Settings) { }
Expand All @@ -22,10 +23,17 @@ export default abstract class FileSystem<T> {
/**
* Return an implementation of the Entry interface.
*/
public makeEntry(stat: fs.Stats, pattern: Pattern): Entry {
(stat as Entry).path = pattern;
(stat as Entry).depth = pattern.split(path.sep).length;
public makeEntry(stats: fs.Stats, pattern: Pattern): Entry {
const entry: Entry = {
name: pattern,
path: pattern,
dirent: utils.fs.createDirentFromStats(pattern, stats)
};

return stat as Entry;
if (this._settings.stats) {
entry.stats = stats;
}

return entry;
}
}
6 changes: 3 additions & 3 deletions src/providers/async.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class TestReaderStream extends ReaderStream {
}

class TestProviderAsync extends ProviderAsync {
protected readonly _reader: TestReaderStream = new TestReaderStream(this.settings);
protected readonly _reader: TestReaderStream = new TestReaderStream(this._settings);

constructor(public settings: Settings = new Settings()) {
super(settings);
constructor(protected _settings: Settings = new Settings()) {
super(_settings);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/providers/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Entry, EntryItem, ReaderOptions } from '../types/index';
import Provider from './provider';

export default class ProviderAsync extends Provider<Promise<EntryItem[]>> {
protected _reader: ReaderStream = new ReaderStream(this.settings);
protected _reader: ReaderStream = new ReaderStream(this._settings);

/**
* Use async API to read entries for Task.
Expand All @@ -23,7 +23,7 @@ export default class ProviderAsync extends Provider<Promise<EntryItem[]>> {
stream.pause();
});

stream.on('data', (entry: Entry) => entries.push(this.transform(entry)));
stream.on('data', (entry: Entry) => entries.push(options.transform(entry)));
stream.on('end', () => resolve(entries));
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/providers/filters/deep.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function getDeepFilterInstance(options?: Options): DeepFilter {
}

function getFilter(positive: Pattern[], negative: Pattern[], options?: Options): EntryFilterFunction {
return getDeepFilterInstance(options).getFilter(positive, negative);
return getDeepFilterInstance(options).getFilter('base', positive, negative);
}

describe('Providers → Filters → Deep', () => {
Expand Down
17 changes: 11 additions & 6 deletions src/providers/filters/deep.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as path from 'path';

import Settings from '../../settings';
import { Entry, EntryFilterFunction, MicromatchOptions, Pattern, PatternRe } from '../../types/index';
import * as utils from '../../utils/index';
Expand All @@ -8,11 +10,11 @@ export default class DeepFilter {
/**
* Returns filter for directories.
*/
public getFilter(positive: Pattern[], negative: Pattern[]): EntryFilterFunction {
public getFilter(basePath: string, positive: Pattern[], negative: Pattern[]): EntryFilterFunction {
const maxPatternDepth = this._getMaxPatternDepth(positive);
const negativeRe: PatternRe[] = this._getNegativePatternsRe(negative);

return (entry: Entry) => this._filter(entry, negativeRe, maxPatternDepth);
return (entry: Entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth);
}

/**
Expand All @@ -36,12 +38,15 @@ export default class DeepFilter {
/**
* Returns «true» for directory that should be read.
*/
private _filter(entry: Entry, negativeRe: PatternRe[], maxPatternDepth: number): boolean {
if (this._isSkippedByDeepOption(entry.depth)) {
private _filter(basePath: string, entry: Entry, negativeRe: PatternRe[], maxPatternDepth: number): boolean {
const basePathDepth = basePath.split(path.posix.sep).length;
const depth = entry.path.split(path.sep).length - (basePath === '' ? 0 : basePathDepth) - 1;

if (this._isSkippedByDeepOption(depth)) {
return false;
}

if (this._isSkippedByMaxPatternDepth(entry.depth, maxPatternDepth)) {
if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) {
return false;
}

Expand Down Expand Up @@ -74,7 +79,7 @@ export default class DeepFilter {
* Returns «true» for symlinked directory if the «followSymlinkedDirectories» option is disabled.
*/
private _isSkippedSymlinkedDirectory(entry: Entry): boolean {
return !this._settings.followSymlinkedDirectories && entry.isSymbolicLink();
return !this._settings.followSymlinkedDirectories && entry.dirent.isSymbolicLink();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/providers/filters/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ export default class EntryFilter {
* Returns true for non-files if the «onlyFiles» option is enabled.
*/
private _onlyFileFilter(entry: Entry): boolean {
return this._settings.onlyFiles && !entry.isFile();
return this._settings.onlyFiles && !entry.dirent.isFile();
}

/**
* Returns true for non-directories if the «onlyDirectories» option is enabled.
*/
private _onlyDirectoryFilter(entry: Entry): boolean {
return this._settings.onlyDirectories && !entry.isDirectory();
return this._settings.onlyDirectories && !entry.dirent.isDirectory();
}

/**
Expand Down
Loading

0 comments on commit 811db58

Please sign in to comment.