Giter Site home page Giter Site logo

mrmlnc / fast-glob Goto Github PK

View Code? Open in Web Editor NEW
2.5K 16.0 106.0 930 KB

:rocket: It's a very fast and efficient glob library for Node.js

License: MIT License

TypeScript 41.45% JavaScript 58.55%
glob globbing node-glob patterns wildcard glob-pattern filesystem fs readdir scandir

fast-glob's Introduction

fast-glob

It's a very fast and efficient glob library for Node.js.

This package provides methods for traversing the file system and returning pathnames that matched a defined set of a specified pattern according to the rules used by the Unix Bash shell with some simplifications, meanwhile results are returned in arbitrary order. Quick, simple, effective.

Table of Contents

Details

Highlights

  • Fast. Probably the fastest.
  • Supports multiple and negative patterns.
  • Synchronous, Promise and Stream API.
  • Object mode. Can return more than just strings.
  • Error-tolerant.

Pattern syntax

โš ๏ธ Always use forward-slashes in glob expressions (patterns and ignore option). Use backslashes for escaping characters.

There is more than one form of syntax: basic and advanced. Below is a brief overview of the supported features. Also pay attention to our FAQ.

๐Ÿ“– This package uses micromatch as a library for pattern matching.

Basic syntax

  • An asterisk (*) โ€” matches everything except slashes (path separators), hidden files (names starting with .).
  • A double star or globstar (**) โ€” matches zero or more directories.
  • Question mark (?) โ€“ matches any single character except slashes (path separators).
  • Sequence ([seq]) โ€” matches any character in sequence.

๐Ÿ“– A few additional words about the basic matching behavior.

Some examples:

  • src/**/*.js โ€” matches all files in the src directory (any level of nesting) that have the .js extension.
  • src/*.?? โ€” matches all files in the src directory (only first level of nesting) that have a two-character extension.
  • file-[01].js โ€” matches files: file-0.js, file-1.js.

Advanced syntax

๐Ÿ“– A few additional words about the advanced matching behavior.

Some examples:

  • src/**/*.{css,scss} โ€” matches all files in the src directory (any level of nesting) that have the .css or .scss extension.
  • file-[[:digit:]].js โ€” matches files: file-0.js, file-1.js, โ€ฆ, file-9.js.
  • file-{1..3}.js โ€” matches files: file-1.js, file-2.js, file-3.js.
  • file-(1|2) โ€” matches files: file-1.js, file-2.js.

Installation

npm install fast-glob

API

Asynchronous

fg.glob(patterns, [options])
fg.async(patterns, [options])

Returns a Promise with an array of matching entries.

const fg = require('fast-glob');

const entries = await fg.glob(['.editorconfig', '**/index.js'], { dot: true });

// ['.editorconfig', 'services/index.js']

Synchronous

fg.globSync(patterns, [options])

Returns an array of matching entries.

const fg = require('fast-glob');

const entries = fg.globSync(['.editorconfig', '**/index.js'], { dot: true });

// ['.editorconfig', 'services/index.js']

Stream

fg.globStream(patterns, [options])
fg.stream(patterns, [options])

Returns a ReadableStream when the data event will be emitted with matching entry.

const fg = require('fast-glob');

const stream = fg.globStream(['.editorconfig', '**/index.js'], { dot: true });

for await (const entry of stream) {
	// .editorconfig
	// services/index.js
}

patterns

  • Required: true
  • Type: string | string[]

Any correct pattern(s).

๐Ÿ”ข Pattern syntax

โš ๏ธ This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns. If you want to get a certain order of records, use sorting or split calls.

[options]

See Options section.

Helpers

generateTasks(patterns, [options])

Returns the internal representation of patterns (Task is a combining patterns by base directory).

fg.generateTasks('*');

[{
    base: '.', // Parent directory for all patterns inside this task
    dynamic: true, // Dynamic or static patterns are in this task
    patterns: ['*'],
    positive: ['*'],
    negative: []
}]
patterns
  • Required: true
  • Type: string | string[]

Any correct pattern(s).

[options]

See Options section.

isDynamicPattern(pattern, [options])

Returns true if the passed pattern is a dynamic pattern.

๐Ÿ”ข What is a static or dynamic pattern?

fg.isDynamicPattern('*'); // true
fg.isDynamicPattern('abc'); // false
pattern
  • Required: true
  • Type: string

Any correct pattern.

[options]

See Options section.

escapePath(path)

Returns the path with escaped special characters depending on the platform.

  • Posix:
    • *?|(){}[];
    • ! at the beginning of line;
    • @+! before the opening parenthesis;
    • \\ before non-special characters;
  • Windows:
    • (){}[]
    • ! at the beginning of line;
    • @+! before the opening parenthesis;
    • Characters like *?| cannot be used in the path (windows_naming_conventions), so they will not be escaped;
fg.escapePath('!abc');
// \\!abc
fg.escapePath('[OpenSource] mrmlnc โ€“ fast-glob (Deluxe Edition) 2014') + '/*.flac'
// \\[OpenSource\\] mrmlnc โ€“ fast-glob \\(Deluxe Edition\\) 2014/*.flac

fg.posix.escapePath('C:\\Program Files (x86)\\**\\*');
// C:\\\\Program Files \\(x86\\)\\*\\*\\*
fg.win32.escapePath('C:\\Program Files (x86)\\**\\*');
// Windows: C:\\Program Files \\(x86\\)\\**\\*

convertPathToPattern(path)

Converts a path to a pattern depending on the platform, including special character escaping.

  • Posix. Works similarly to the fg.posix.escapePath method.
  • Windows. Works similarly to the fg.win32.escapePath method, additionally converting backslashes to forward slashes in cases where they are not escape characters (!()+@{}[]).
fg.convertPathToPattern('[OpenSource] mrmlnc โ€“ fast-glob (Deluxe Edition) 2014') + '/*.flac';
// \\[OpenSource\\] mrmlnc โ€“ fast-glob \\(Deluxe Edition\\) 2014/*.flac

fg.convertPathToPattern('C:/Program Files (x86)/**/*');
// Posix: C:/Program Files \\(x86\\)/\\*\\*/\\*
// Windows: C:/Program Files \\(x86\\)/**/*

fg.convertPathToPattern('C:\\Program Files (x86)\\**\\*');
// Posix: C:\\\\Program Files \\(x86\\)\\*\\*\\*
// Windows: C:/Program Files \\(x86\\)/**/*

fg.posix.convertPathToPattern('\\\\?\\c:\\Program Files (x86)') + '/**/*';
// Posix: \\\\\\?\\\\c:\\\\Program Files \\(x86\\)/**/* (broken pattern)
fg.win32.convertPathToPattern('\\\\?\\c:\\Program Files (x86)') + '/**/*';
// Windows: //?/c:/Program Files \\(x86\\)/**/*

Options

Common options

cwd

  • Type: string
  • Default: process.cwd()

The current working directory in which to search.

deep

  • Type: number
  • Default: Infinity

Specifies the maximum depth of a read directory relative to the start directory.

For example, you have the following tree:

dir/
โ””โ”€โ”€ one/            // 1
    โ””โ”€โ”€ two/        // 2
        โ””โ”€โ”€ file.js // 3
// With base directory
fg.globSync('dir/**', { onlyFiles: false, deep: 1 }); // ['dir/one']
fg.globSync('dir/**', { onlyFiles: false, deep: 2 }); // ['dir/one', 'dir/one/two']

// With cwd option
fg.globSync('**', { onlyFiles: false, cwd: 'dir', deep: 1 }); // ['one']
fg.globSync('**', { onlyFiles: false, cwd: 'dir', deep: 2 }); // ['one', 'one/two']

๐Ÿ“– If you specify a pattern with some base directory, this directory will not participate in the calculation of the depth of the found directories. Think of it as a cwd option.

followSymbolicLinks

  • Type: boolean
  • Default: true

Indicates whether to traverse descendants of symbolic link directories when expanding ** patterns.

๐Ÿ“– Note that this option does not affect the base directory of the pattern. For example, if ./a is a symlink to directory ./b and you specified ['./a**', './b/**'] patterns, then directory ./a will still be read.

๐Ÿ“– If the stats option is specified, the information about the symbolic link (fs.lstat) will be replaced with information about the entry (fs.stat) behind it.

fs

  • Type: FileSystemAdapter
  • Default: fs.*

Custom implementation of methods for working with the file system. Supports objects with enumerable properties only.

export interface FileSystemAdapter {
    lstat?: typeof fs.lstat;
    stat?: typeof fs.stat;
    lstatSync?: typeof fs.lstatSync;
    statSync?: typeof fs.statSync;
    readdir?: typeof fs.readdir;
    readdirSync?: typeof fs.readdirSync;
}

ignore

  • Type: string[]
  • Default: []

An array of glob patterns to exclude matches. This is an alternative way to use negative patterns.

dir/
โ”œโ”€โ”€ package-lock.json
โ””โ”€โ”€ package.json
fg.globSync(['*.json', '!package-lock.json']);            // ['package.json']
fg.globSync('*.json', { ignore: ['package-lock.json'] }); // ['package.json']

suppressErrors

  • Type: boolean
  • Default: false

By default this package suppress only ENOENT errors. Set to true to suppress any error.

๐Ÿ“– Can be useful when the directory has entries with a special level of access.

throwErrorOnBrokenSymbolicLink

  • Type: boolean
  • Default: false

Throw an error when symbolic link is broken if true or safely return lstat call if false.

๐Ÿ“– This option has no effect on errors when reading the symbolic link directory.

Output control

absolute

  • Type: boolean
  • Default: false

Return the absolute path for entries.

fg.globSync('*.js', { absolute: false }); // ['index.js']
fg.globSync('*.js', { absolute: true });  // ['/home/user/index.js']

๐Ÿ“– This option is required if you want to use negative patterns with absolute path, for example, !${__dirname}/*.js.

markDirectories

  • Type: boolean
  • Default: false

Mark the directory path with the final slash.

fg.globSync('*', { onlyFiles: false, markDirectories: false }); // ['index.js', 'controllers']
fg.globSync('*', { onlyFiles: false, markDirectories: true });  // ['index.js', 'controllers/']

objectMode

  • Type: boolean
  • Default: false

Returns objects (instead of strings) describing entries.

fg.globSync('*', { objectMode: false }); // ['src/index.js']
fg.globSync('*', { objectMode: true });  // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent> }]

The object has the following fields:

  • name (string) โ€” the last part of the path (basename)
  • path (string) โ€” full path relative to the pattern base directory
  • dirent (fs.Dirent) โ€” instance of fs.Dirent

๐Ÿ“– An object is an internal representation of entry, so getting it does not affect performance.

onlyDirectories

  • Type: boolean
  • Default: false

Return only directories.

fg.globSync('*', { onlyDirectories: false }); // ['index.js', 'src']
fg.globSync('*', { onlyDirectories: true });  // ['src']

๐Ÿ“– If true, the onlyFiles option is automatically false.

onlyFiles

  • Type: boolean
  • Default: true

Return only files.

fg.globSync('*', { onlyFiles: false }); // ['index.js', 'src']
fg.globSync('*', { onlyFiles: true });  // ['index.js']

stats

  • Type: boolean
  • Default: false

Enables an object mode with an additional field:

  • stats (fs.Stats) โ€” instance of fs.Stats
fg.globSync('*', { stats: false }); // ['src/index.js']
fg.globSync('*', { stats: true });  // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent>, stats: <fs.Stats> }]

๐Ÿ“– Returns fs.stat instead of fs.lstat for symbolic links when the followSymbolicLinks option is specified.

unique

  • Type: boolean
  • Default: true

Ensures that the returned entries are unique.

fg.globSync(['*.json', 'package.json'], { unique: false }); // ['package.json', 'package.json']
fg.globSync(['*.json', 'package.json'], { unique: true });  // ['package.json']

If true and similar entries are found, the result is the first found.

Matching control

braceExpansion

  • Type: boolean
  • Default: true

Enables Bash-like brace expansion.

๐Ÿ”ข Syntax description or more detailed description.

dir/
โ”œโ”€โ”€ abd
โ”œโ”€โ”€ acd
โ””โ”€โ”€ a{b,c}d
fg.globSync('a{b,c}d', { braceExpansion: false }); // ['a{b,c}d']
fg.globSync('a{b,c}d', { braceExpansion: true });  // ['abd', 'acd']

caseSensitiveMatch

  • Type: boolean
  • Default: true

Enables a case-sensitive mode for matching files.

dir/
โ”œโ”€โ”€ file.txt
โ””โ”€โ”€ File.txt
fg.globSync('file.txt', { caseSensitiveMatch: false }); // ['file.txt', 'File.txt']
fg.globSync('file.txt', { caseSensitiveMatch: true });  // ['file.txt']

dot

  • Type: boolean
  • Default: false

Allow patterns to match entries that begin with a period (.).

๐Ÿ“– Note that an explicit dot in a portion of the pattern will always match dot files.

dir/
โ”œโ”€โ”€ .editorconfig
โ””โ”€โ”€ package.json
fg.globSync('*', { dot: false }); // ['package.json']
fg.globSync('*', { dot: true });  // ['.editorconfig', 'package.json']

extglob

  • Type: boolean
  • Default: true

Enables Bash-like extglob functionality.

๐Ÿ”ข Syntax description.

dir/
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ package.json
fg.globSync('*.+(json|md)', { extglob: false }); // []
fg.globSync('*.+(json|md)', { extglob: true });  // ['README.md', 'package.json']

globstar

  • Type: boolean
  • Default: true

Enables recursively repeats a pattern containing **. If false, ** behaves exactly like *.

dir/
โ””โ”€โ”€ a
    โ””โ”€โ”€ b
fg.globSync('**', { onlyFiles: false, globstar: false }); // ['a']
fg.globSync('**', { onlyFiles: false, globstar: true });  // ['a', 'a/b']

baseNameMatch

  • Type: boolean
  • Default: false

If set to true, then patterns without slashes will be matched against the basename of the path if it contains slashes.

dir/
โ””โ”€โ”€ one/
    โ””โ”€โ”€ file.md
fg.globSync('*.md', { baseNameMatch: false }); // []
fg.globSync('*.md', { baseNameMatch: true });  // ['one/file.md']

FAQ

What is a static or dynamic pattern?

All patterns can be divided into two types:

  • static. A pattern is considered static if it can be used to get an entry on the file system without using matching mechanisms. For example, the file.js pattern is a static pattern because we can just verify that it exists on the file system.
  • dynamic. A pattern is considered dynamic if it cannot be used directly to find occurrences without using a matching mechanisms. For example, the * pattern is a dynamic pattern because we cannot use this pattern directly.

A pattern is considered dynamic if it contains the following characters (โ€ฆ โ€” any characters or their absence) or options:

  • The caseSensitiveMatch option is disabled
  • \\ (the escape character)
  • *, ?, ! (at the beginning of line)
  • [โ€ฆ]
  • (โ€ฆ|โ€ฆ)
  • @(โ€ฆ), !(โ€ฆ), *(โ€ฆ), ?(โ€ฆ), +(โ€ฆ) (respects the extglob option)
  • {โ€ฆ,โ€ฆ}, {โ€ฆ..โ€ฆ} (respects the braceExpansion option)

How to write patterns on Windows?

Always use forward-slashes in glob expressions (patterns and ignore option). Use backslashes for escaping characters. With the cwd option use a convenient format.

Bad

[
	'directory\\*',
	path.join(process.cwd(), '**')
]

Good

[
	'directory/*',
	fg.convertPathToPattern(process.cwd()) + '/**'
]

๐Ÿ“– Use the .convertPathToPattern package to convert Windows-style path to a Unix-style path.

Read more about matching with backslashes.

Why are parentheses match wrong?

dir/
โ””โ”€โ”€ (special-*file).txt
fg.globSync(['(special-*file).txt']) // []

Refers to Bash. You need to escape special characters:

fg.globSync(['\\(special-*file\\).txt']) // ['(special-*file).txt']

Read more about matching special characters as literals. Or use the .escapePath.

How to exclude directory from reading?

You can use a negative pattern like this: !**/node_modules or !**/node_modules/**. Also you can use ignore option. Just look at the example below.

first/
โ”œโ”€โ”€ file.md
โ””โ”€โ”€ second/
    โ””โ”€โ”€ file.txt

If you don't want to read the second directory, you must write the following pattern: !**/second or !**/second/**.

fg.globSync(['**/*.md', '!**/second']);                 // ['first/file.md']
fg.globSync(['**/*.md'], { ignore: ['**/second/**'] }); // ['first/file.md']

โš ๏ธ When you write !**/second/**/* it means that the directory will be read, but all the entries will not be included in the results.

You have to understand that if you write the pattern to exclude directories, then the directory will not be read under any circumstances.

How to use UNC path?

You cannot use Uniform Naming Convention (UNC) paths as patterns (due to syntax) directly, but you can use them as cwd directory or use the fg.convertPathToPattern method.

// cwd
fg.globSync('*', { cwd: '\\\\?\\C:\\Python27' /* or //?/C:/Python27 */ });
fg.globSync('Python27/*', { cwd: '\\\\?\\C:\\' /* or //?/C:/ */ });

// .convertPathToPattern
fg.globSync(fg.convertPathToPattern('\\\\?\\c:\\Python27') + '/*');

Compatible with node-glob?

node-glob fast-glob
cwd cwd
root โ€“
dot dot
nomount โ€“
mark markDirectories
nosort โ€“
nounique unique
nobrace braceExpansion
noglobstar globstar
noext extglob
nocase caseSensitiveMatch
matchBase baseNameMatch
nodir onlyFiles
ignore ignore
follow followSymbolicLinks
realpath โ€“
absolute absolute

Benchmarks

You can see results here for every commit into the main branch.

  • Product benchmark โ€“ comparison with the main competitors.
  • Regress benchmark โ€“ regression between the current version and the version from the npm registry.

Changelog

See the Releases section of our GitHub project for changelog for each release version.

License

This software is released under the terms of the MIT license.

fast-glob's People

Contributors

agentender avatar amitdahan avatar bluelovers avatar dudagod avatar emelyanovtv avatar fky2015 avatar garyking avatar indera avatar ivanhofer avatar jamiebuilds avatar josh-hemphill avatar lukeis avatar mairaw avatar marcellothearcane avatar markelog avatar maugares avatar mrmlnc avatar randombyte avatar rijnhard avatar sipayrt avatar tehshrike avatar trott avatar vladshcherbin avatar xhmikosr avatar yarastqt avatar yozman avatar yuriydobryanskyyempeek avatar zkochan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-glob's Issues

Change double-negative options

Double-negative options is a bad developer experience. It's better to just invert the default.

nobrace => brace
noglobstar => globstar
noext => ext (Or Maybe even extension to be totally clear)
nocase => case

I realize these are brought over from node-glob, but we can do better.


We are now using fast-glob in globby. ๐Ÿ˜

FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal with sync function

Environment

  • OS Version: Mac OS 10.12.6
  • Node.js Version: v9.4.0

Actual behavior

git clone https://github.com/sindresorhus/globby
npm install
node -e "const fg = require('fast-glob'); fg.sync('**/index.js')"

FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.
 1: node::Abort() [/usr/local/bin/node]
 2: node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/local/bin/node]
 4: node::ReadDir(v8::FunctionCallbackInfo<v8::Value> const&) [/usr/local/bin/node]
 5: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
 6: v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/usr/local/bin/node]
 7: v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/bin/node]
 8: 0x11e5eea842fd

When excluding node_modules it works as expected:

node -e "const fg = require('fast-glob'); fg.sync('**/index.js', {ignore: 'node_modules'})" 

With async function is also works:

node -e "const fg = require('fast-glob'); fg('**/index.js', {ignore: 'node_modules'}).then(console.log)" 

Expected behavior

To return the index.js file and not errors out.

Directories end with `/` with `markDirectories: false` and `//` with `markDirectories: true`

With the following directory tree:

+-- test/
|   +-- dir
|       +-- file.js
fg.sync('test/**', {onlyFiles: false, markDirectories: false});

// Result => ['test/dir/', 'test/dir/file.js']
// Should be => ['test/dir', 'test/dir/file.js']
fg.sync('test/**', {onlyFiles: false, markDirectories: true});

// Result => ['test/dir//', 'test/dir/file.js']
// Should be => ['test/dir/', 'test/dir/file.js']

Doesn't exclude entries when pattern ends with globstar or includes pattern

Environment

  • OS Version: 10.13.3 (macOS)
  • Node.js Version: 9.5.0

Actual behavior

['fixtures/directory']

Expected behavior

[]

Steps to reproduce

fixtures/
โ”œโ”€โ”€ directory
โ”œโ”€โ”€ file.md
โ””โ”€โ”€ file.txt

Code sample

const entries1 = globby.sync(['fixtures/directory', '!fixtures/**', '!fixtures/directory'], { nodir: false });
const entries2 = fg.sync(['fixtures/directory', '!fixtures/**', '!fixtures/directory'], { onlyFiles: false });

console.log('GLOBBY@7', entries1); // []
console.log('FAST-GLOB@2', entries2); // ['fixtures/directory']

`FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.` on node 8

I started getting this error when updating from node 6 to node 8. I can reproduce running this code on my large repository but I haven't yet tracked it down to which files are exactly causing it:

const glob = require('fast-glob');

const files = glob.sync('**/*.js', {
    bashNative: [],
    onlyFiles: true,
    cwd: process.cwd(),
    ignore: ['node_modules/**'],
});

console.log(files);
FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::V8::ToLocalEmpty() [/usr/local/bin/node]
 4: node::ReadDir(v8::FunctionCallbackInfo<v8::Value> const&) [/usr/local/bin/node]
 5: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
 6: v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/usr/local/bin/node]
 7: v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/bin/node]
 8: 0x2b0d0ee0463d
 9: 0x2b0d0eef474a

node v8.9.3, macOS 10.13.2

Release v2.1.0 [25.02.2018]

Issues

  • Update micromatch package
  • #60
  • #54 (additional options)

Before

  • Manual smoke tests
  • README review
  • Run benchmark

After

  • git tag
  • npm publish
  • Twitter announce

Micromatch performance

We need fix performance for the micromatch package.

So, we spend about 30ms (for 400 entries with 50 depth) to find the regular expression for the pattern in the cache when we pass options. Proof:

Before:

fast-glob-current.js
(TIME) 81.862ms ยฑ2.573% | (MEMORY) 8.357MB ยฑ0.081% | Entries: 200 | Errors: 0 | Retries: 1
fast-glob-previous.js
(TIME) 60.310ms ยฑ1.405% | (MEMORY) 10.533MB ยฑ0.073% | Entries: 200 | Errors: 0 | Retries: 1

After (Transform patterns to RegExps once in Reader class):
1 bash 2018-01-15 21-58-32

P.S: You need to look at the diff between numbers.

The next performance improvements

Node.js

  • Use fs.scandir from nodejs/node#15699. Most likely it will give double performance increase for work with FS (not on all platforms). Right now I can use the scandir-native package, but this is native module and it requires compilation.

Algorithm

  • Reduce search time for ยซconstantยป patterns (#60).

Code

  • Write your own package for recursive directory reading. The readdir-enhanced is poorly maintained (code, architecture).

Release v2.2.1 [22.04.2018]

Issues

Before release

  • Review of the README.md file
  • Benchmark
  • Checking on projects that already use fast-glob
    • sindresorhus/globby
    • stylelint/stylelint
    • facebook/relay
    • zkochan/find-packages
    • mrmlnc/syncy

After release

  • Run git tag
  • Run npm publish
  • Twitter announce

Release v2.2.0 [11.03.2018]

Issues

Before release

  • Manual smoke tests
  • Checking on projects that already use fast-glob
    • sindresorhus/globby
    • facebook/relay
    • zkochan/find-packages
    • mrmlnc/syncy
  • README review
  • Run benchmark

After

  • git tag
  • npm publish
  • Twitter announce

Incorrect filter for static patterns

Source

Actual behavior

const matches = await fg(['../files/foo.json', '../files/bar.json']);
console.log(matches);
// Output: [ ]

Expected behavior

const matches = await fg(['../files/foo.json', '../files/bar.json']);
console.log(matches);
// Output: ['../files/foo.json', '../files/bar.json']

Description

When we work with static patterns, we use the ** pattern. Unfortunately, this does not cover cases with relative paths. We have to work with real patterns.

Issue with folder and file paths that don't have glob patterns

I have some instances where the glob pattern is not a glob at all and is a path to a directory/file.

Example

const glob = require("fast-glob");
glob.sync("node_modules/zone.js");

Error

โ€‹โ€‹Maximum call stack size exceededโ€‹โ€‹

I expect that this doesn't break and return the path.

Ignore patterns don't work in `ignore` option

Environment

  • OS Version: ubuntu 17.10
  • Node.js Version: latest

Actual behavior

Ignore patterns don't work in ignore option.

Expected behavior

Ignore patterns should be work in ignore option. node-glob works perfect.

Steps to reproduce

  1. Create file.txt with any contents.
  2. Create file.yaml with any contents.

Code sample

const fg = require('fast-glob');

fg(['**/*'], {
  absolute: true,
  dot: true,
  ignore: [`!{**/*,*}.txt`],
  onlyFiles: true
})
  .then((entries) => console.log(entries));

Incorrect deep filtering with negate patterns.

Environment

  • OS Version: ubuntu 16
  • Node.js Version: 9.7.1

It's impossible to mitigate a negate pattern with a positive one. Commit 8ce21ee breaks previous behavior.

Actual behavior (after 8ce21ee)

> fg.sync(['src/*', 'src/foo/**'], { cwd, ignore: ['**/foo/**'] })
[ 'src/index.js' ]

Expected behavior (before 8ce21ee)

> fg.sync(['src/*', 'src/foo/**'], { cwd, ignore: ['**/foo/**'] })
[ 'src/index.js', 'src/foo/bar.js' ]

Steps to reproduce

There is simple folders tree:

 src
 โ”œโ”€โ”€ foo
 โ”‚ย ย  โ””โ”€โ”€ bar.js
 โ””โ”€โ”€ index.js

I want to have both files - index.js and bar.js. Also, i have negate pattern **/foo/**.

Bug since v2.0.0 โ€” RangeError: Maximum call stack size exceeded

Environment

  • OS Version: Fedora Linux 4.14.14-300.fc27.x86_64
  • Node.js Version: v9.4.0

Actual behavior

Since v2.0.0 an error is thrown when run on a filesystem. Number of files/dirs is 54/18 in my case.

Call stack:

yarn run v1.3.2
$ OVERRIDE_ENV=development npm run build

> [email protected] build /home/max/Development/example/packages/app
> APP_RELEASE=$(git describe --always) NODE_ENV=production node build/build.js

/home/max/Development/example/node_modules/fast-glob/out/providers/reader-sync.js:40
            throw err;
            ^

RangeError: Maximum call stack size exceeded
    at call.safe (/home/max/Development/example/node_modules/readdir-enhanced/lib/stat.js:26:26)
    at onceWrapper (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:45:17)
    at onceWrapper (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:45:17)
    at exports.lstat (/home/max/Development/example/node_modules/readdir-enhanced/lib/sync/fs.js:59:5)
    at Object.safeCall [as safe] (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:24:8)
    at stat (/home/max/Development/example/node_modules/readdir-enhanced/lib/stat.js:19:8)
    at DirectoryReader.processItem (/home/max/Development/example/node_modules/readdir-enhanced/lib/directory-reader.js:171:5)
    at array.forEach.item (/home/max/Development/example/node_modules/readdir-enhanced/lib/sync/for-each.js:14:5)
    at Array.forEach (<anonymous>)
    at Object.syncForEach [as forEach] (/home/max/Development/example/node_modules/readdir-enhanced/lib/sync/for-each.js:13:9)
    at call.safe (/home/max/Development/example/node_modules/readdir-enhanced/lib/directory-reader.js:80:16)
    at onceWrapper (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:45:17)
    at onceWrapper (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:45:17)
    at exports.readdir (/home/max/Development/example/node_modules/readdir-enhanced/lib/sync/fs.js:19:5)
    at Object.safeCall [as safe] (/home/max/Development/example/node_modules/readdir-enhanced/lib/call.js:24:8)
    at DirectoryReader.readNextDirectory (/home/max/Development/example/node_modules/readdir-enhanced/lib/directory-reader.js:71:10)

npm ERR! Linux 4.14.14-300.fc27.x86_64
npm ERR! argv "/usr/bin/node" "/home/max/.config/yarn/global/node_modules/.bin/npm" "run" "build"
npm ERR! node v9.4.0
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `APP_RELEASE=$(git describe --always) NODE_ENV=production node build/build.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script 'APP_RELEASE=$(git describe --always) NODE_ENV=production node build/build.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the app package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     APP_RELEASE=$(git describe --always) NODE_ENV=production node build/build.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs app
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls app
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/max/Development/example/packages/app/npm-debug.log
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Looks to be related to readdir-enhanced.

Expected behavior

fast-glob runs without any error thrown.

Steps to reproduce

  1. Nothing specific, just run fast-glob.

Code sample

const fastGlob = require('fast-glob');

const paths = fastGlob.sync([
  path.join(__dirname, './**/*.html'),
  path.join(__dirname, './**/*.js'),
]);

NOTE

Since v2.0.0 has removed bashNative mode, I'm actually going to pin my fast-glob version to 1.0.1 anyway since I want that native level of performance. That was actually the reason why I started using fast-glob in the first place!

Document behaviour with "dot" folders

First thanks a lot for this package. It's much faster than node-glob with a much lower memory usage!

One issue I faced while migrating is that node-glob skips all folders that start with a dot, probably in case they're not traversable. fast-glob doesn't skip them which can lead to permission issues like Error: EACCES: permission denied, scandir 'test/.foo' (fails the whole scan).

This can be fixed using:

fastGlob(pattern, {
  deep: stats => stats.path.charAt(0) !== '.'
})

Maybe you could document this in the README in the Compatible with node-glob section?

[proposal] Include debug

Would be cool to include debug for filters, providers and other places. This will help catching bugs easier.

Roadmap to [email protected]

โœ… Common

  • Drop bash-glob (many questions)
  • Provide Stream API

โœ… Performance (File System)

  • Combine multiple patterns by base directory of each pattern (further tasks)
  • Implement recursive fs.readdir
    • Cache between workers in the same run, when there are multiple tasks
  • Use fs.scandir instead of fs.readdir + fs.stat
    • Blocked by nodejs/node#15699 (PR?)
    • ~If Node.js will be against fs.scandir then create (scandir|readdir)-native package~~ (native package is a bad idea)
  • Sort found files by inode for fs.stats calls with stats option
  • Add ability to skip ignored directories (like node_modules) during the scan

โœ… Benchmark

  • Rewrite benchmark to TypeScript
  • Add previous version of fast-glob to benchmark to compare performance between versions
  • Add benchmark suites for small, medium and large count of entries in the directory

Release

  • Smoke compare with globby
  • Test on real projects
    • tartifacts
    • Relay #23
  • Git Tag & Release announcement
  • Publish 2.0.0 to npm
  • Change fast-glob previous version in the benchmark
  • Use @types/readdir-enhanced
  • Twitter

[proposal] Ability to import/export tasks

Would be cool to provide ability to return tasks from the package. Something like:

import * as fg from 'fast-glob';

const tasks = fg.getTasks(['pattern1', 'pattern2'], options);

Maybe also we need think about ability to import tasks instead of patterns:

import * as fg from 'fast-glob';

const tasks = fg.sync([task1, task2], options);

Fails on Windows

Hi! I'm seeing a fail on Windows related to micromatch/micromatch#95 (comment) and path.sep. Does this sound like something fast-glob is doing?

The error stack is:

C:\projects\esm\node_modules\snapdragon\lib\parser.js:473
        throw new Error('no parsers registered for: "' + self.input.slice(0, 5) + '"');
        ^

.cac": no parsers registered for: "
    at parse (C:\projects\esm\node_modules\snapdragon\lib\parser.js:473:15)
    at Parser.parse (C:\projects\esm\node_modules\snapdragon\lib\parser.js:477:24)
    at Snapdragon.parse (C:\projects\esm\node_modules\snapdragon\index.js:122:28)
    at Snapdragon.<anonymous> (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\lib\utils.js:47:45)
    at parse (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:741:26)
    at memoize (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:861:13)
    at Function.micromatch.parse (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:747:10)
    at create (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:688:44)
    at C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:697:16
    at memoize (C:\projects\esm\node_modules\fast-glob\node_modules\micromatch\index.js:861:13)
npm ERR! Test failed.  See above for more details.

A very long initialization time of filters (deep + entry)

Environment

  • OS Version: macOS 10.13.3
  • Node.js Version: 8.9.0

Source

The problem

We have to figure out a way to reduce the initialization time of filters. Something like 14ms for the following tasks:

{ base: 'src/types/one',
  dynamic: true,
  patterns: [ 'src/types/one/*/sub/y/y.json' ],
  positive: [ 'src/types/one/*/sub/y/y.json' ],
  negative: [] }
Prepare reader options: 8.445ms
{ base: 'src/types/two',
  dynamic: true,
  patterns: [ 'src/types/two/*/sub/y/y.json' ],
  positive: [ 'src/types/two/*/sub/y/y.json' ],
  negative: [] }
Prepare reader options: 1.802ms
{ base: 'src/types/three',
  dynamic: true,
  patterns: [ 'src/types/three/*/sub/y/y.json' ],
  positive: [ 'src/types/three/*/sub/y/y.json' ],
  negative: [] }
Prepare reader options: 1.400ms
{ base: 'src/types/four',
  dynamic: true,
  patterns: [ 'src/types/four/*/sub/y/y.json' ],
  positive: [ 'src/types/four/*/sub/y/y.json' ],
  negative: [] }
Prepare reader options: 0.794ms
{ base: 'src/types/five',
  dynamic: true,
  patterns: [ 'src/types/five/*/sub/y/y.json' ],
  positive: [ 'src/types/five/*/sub/y/y.json' ],
  negative: [] }
Prepare reader options: 2.111ms

Feature request: Cancel long tasks

Environment

  • OS Version: W10 x64
  • Node.js Version: c8.9.4

Actual behavior

Not implemented

Expected behavior

I'm building a search for 50k files on a network share and each query takes about 10s.
It would be nice to cancel requests if the user changes his input. Is this possible?

Slower than `node-glob` when ignoring a directory with `dir/**`

See benchmark file: https://gist.github.com/pvdlg/8f72824d81263efc71b30fd443aa8b0e

npm install matcha, fast-glob, glob
./node_modules/.bin/matcha fast-blog-bench.js
patterns: 'a/*', ignore: ['a']

231 op/s ยป fast-glob sync
136 op/s ยป glob sync

patterns: 'a/*', ignore: ['a/**']

302 op/s ยป fast-glob sync
31,096 op/s ยป glob sync

It's quite an edge case as it seems the performance difference happens only when the the ignore pattern make so that no pattern will match. It seems that node-glob is able to figure out that nothing will ever with pattern 'a/*' and ignore ['a/**'], while fast-glob still goes through the directory.

With pattern 'a/*' and ignore ['a'] it seems neither fast-glob nor node-glob figure out that nothing would match and both attempt to go through the directory.
I thought the directory would be ignored completely in such case.

I'm not sure it's a big issue as it concerns a pattern/ignore config that doesn't make much sense, but I though it worth mentioning in case the perf improvement is really simple to do. Maybe ignoring patterns that are included within ignore pattern can bring other more useful performance improvements.

Time to find a non glob path increase with number of files in the same directory

Environment

  • OS Version: OSX 10.12.6
  • Node.js Version: 9.50

Actual behavior

When searching for a single file (no glob parts in the path), the time increase with as the number of files in the same directory increase. With node-glob this time is constant.

Find 1 file in a directory with 1 file (ran 500 times):

  • node-glob: 48.868ms
  • fast-glob: 118.218ms

Find 1 file in a directory with 500 file (ran 500 times):

  • node-glob: 45.647ms
  • fast-glob: 1935.108ms

Find 1 file in a directory with 2000 file (ran 500 times):

  • node-glob: 48.535ms
  • fast-glob: 7538.522ms

Expected behavior

Globbing a static path (with no wildcards) is a something that can happen sometimes in modules that get the glob patterns from user input, as users can pass a list of file path (e.g, mymodule file1.js file2.js file3.js ).

It seems that node-glob has a way to detect those cases and optimize them. There is potential gain of perf in fast-glob by implementing the same type of optimization.

Steps to reproduce

Use the code below and change the TOTAL_FILES to measure the changes in the globbing time between fast-glob and node-glob.

Code sample

const fs = require('fs');
const path = require('path');
const glob = require('glob');
const fg = require('fast-glob');

const TOTAL_FILES = 2000;

fs.mkdirSync('test')
for (let i = 0; i < TOTAL_FILES; i++) {
  const filepath = path.join('test', `file-${i}`);
  fs.writeFileSync(filepath, '');
}

console.time('node-glob');
for (let i = 0; i < 500; i++) {
  glob.sync('test/file-1')
}
console.timeEnd('node-glob');

console.time('fast-glob');
for (let i = 0; i < 500; i++) {
  fg.sync('test/file-1')
}
console.timeEnd('fast-glob');

bash native Error: spawn /usr/local/bin/bash ENOENT

Glob works fine when I force it to not use bashNative via { bashNative: [] }, but fails otherwise

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: spawn /usr/local/bin/bash ENOENT
    at exports._errnoException (util.js:1018:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
    at onErrorNT (internal/child_process.js:367:16)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)

This is on OSX

Incorrect deep filtering

Environment

  • OS Version: 10.13.3 (macOS)
  • Node.js Version: 9.5.0

Actual behaviour

Where we set the cwd option, the packages path is passed to the depth filter and this is matched to the * negative pattern. After that, we do not read this directory.

If you pass patterns without cwd option (like app/**/node_modules/**), then we work with app/packages and it's works fine.

[]

Expected behaviour

[
  'packages/bar/node_modules',
  'packages/bar/node_modules/baz',
  'packages/bar/node_modules/baz/c.json',
  'packages/bar/node_modules/baz/node_modules',
  'packages/bar/node_modules/baz/node_modules/d.json',
  'packages/bar/node_modules/baz/node_modules/something'
]

Steps to reproduce

app
โ””โ”€โ”€ packages
    โ”œโ”€โ”€ bar
    โ”‚ย ย  โ”œโ”€โ”€ b.json
    โ”‚ย ย  โ””โ”€โ”€ node_modules
    โ”‚ย ย      โ””โ”€โ”€ baz
    โ”‚ย ย          โ”œโ”€โ”€ c.json
    โ”‚ย ย          โ””โ”€โ”€ node_modules
    โ”‚ย ย              โ”œโ”€โ”€ d.json
    โ”‚ย ย              โ””โ”€โ”€ something
    โ””โ”€โ”€ foo
        โ””โ”€โ”€ a.json

Code sample

const globby = require('globby');
const fg = require('fast-glob');
const fgNext = require('../../OpenSource/fast-glob');

const entries1 = globby.sync(['**/node_modules/**', '!*'], { cwd: 'app', nodir: false });
const entries2 = fg.sync(['**/node_modules/**', '!*'], { cwd: 'app', onlyFiles: false });
const entries3 = fgNext.sync(['**/node_modules/**', '!*'], { cwd: 'app', onlyFiles: false });

console.log('GLOBBY@7', entries1); // Expected behaviour 
console.log('FAST-GLOB@2', entries2); // []
console.log('FAST-GLOB@NEXT', entries3); // []

Find `folder` that is not inside `folder`

Say you want to find all node_modules folders, but not node_modules folders nested inside them.

E.g.

- app
  - packages
    - foo
    - bar
      - node_modules <- Return this and don't search anything inside it.
        - baz
          - node_modules <- Don't return this, and don't even search it.

Can this be done with fast-glob?

It is impossible with node-glob, but would be cool if it were possible in fast-glob.

Callback on every file found

It'd be nice to have the ability to run a callback on every file, something like this:

fastGlob('sources/*', filename => {
    // do some asynchronous stuff
}).then(filenames => {
    console.log('done')
})

Incorrect deep filtering with `*` negative pattern

Environment

  • OS Version: 10.13.3 (macOS)
  • Node.js Version: 9.5.0

Actual behaviour

We excluding from reading any entries that match to the negative pattern, even directories.

FIXTURES                                  NODE_GLOB  FAST_GLOB
----------------------------------------  ---------  ---------
fixtures/first/file.md                    +          -
fixtures/first/nested                     +          -
fixtures/first/nested/directory           +          -
fixtures/first/nested/directory/file.md   +          -
fixtures/first/nested/file.md             +          -
fixtures/second/file.md                   +          -
fixtures/second/nested                    +          -
fixtures/second/nested/directory          +          -
fixtures/second/nested/directory/file.md  +          -
fixtures/second/nested/file.md            +          -

Expected behavior

We shouldn't excluding from reading directories when the positive patterns has more then one accepted depth level.

FIXTURES                                  NODE_GLOB  FAST_GLOB
----------------------------------------  ---------  ---------
fixtures/first/file.md                    +          +
fixtures/first/nested                     +          +
fixtures/first/nested/directory           +          +
fixtures/first/nested/directory/file.md   +          +
fixtures/first/nested/file.md             +          +
fixtures/second/file.md                   +          +
fixtures/second/nested                    +          +
fixtures/second/nested/directory          +          +
fixtures/second/nested/directory/file.md  +          +
fixtures/second/nested/file.md            +          +

Steps to reproduce

fixtures/
โ”œโ”€โ”€ file.md
โ”œโ”€โ”€ first
โ”‚ย ย  โ”œโ”€โ”€ file.md
โ”‚ย ย  โ””โ”€โ”€ nested
โ”‚ย ย      โ”œโ”€โ”€ directory
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ file.md
โ”‚ย ย      โ””โ”€โ”€ file.md
โ””โ”€โ”€ second
    โ”œโ”€โ”€ file.md
    โ””โ”€โ”€ nested
        โ”œโ”€โ”€ directory
        โ”‚ย ย  โ””โ”€โ”€ file.md
        โ””โ”€โ”€ file.md

Code sample

const entries = fg.sync(['fixtures/**', '!fixtures/*']);

console.log(entries);

Swallowing errors

Errors are being swallowed here:

if (this.isEnoentCodeError(err)) {

I had a:

ENOENT: no such file or directory, lstat '/dev/fd/12'

but the err.prev was:

EBADF: bad file descriptor, lstat '/dev/fd/12'

Admittedly, I am using the memfs and unionfs. Perhaps the prev is unique to their custom Error object. But maybe there should be a {throwErrors} option?

Environment

  • OS Version: macOS
  • Node.js Version: ^8

Code sample

const glob = require('fast-glob');
const nodeGlob = require('glob');
const {Volume} = require('../lib/volume');
const {patchFs} = require('fs-monkey');
const {ufs} = require('unionfs');
const fs = require('fs');
var readdir = require('readdir-enhanced');

let vol

function start() {
  vol = new Volume()
  ufs.use(fs).use(vol);
  patchFs(ufs)
}

start()

function reset() {
  vol.reset()
}

vol.writeFileSync('/app/foo.json', 'foo')
glob.sync('/app')
vol.symlinkSync('/app', '/app/foo')
glob.sync('/app') // This is empty array.
nodeGlob.sync('/app/**') // Works

mock-fs compatibility

Environment

  • OS Version: macOS 10.13.3
  • Node.js Version: 8.9.4

Actual behavior

I've written a gulp-like file transformer to glob for files, read them, modify them, and write them back to the file system. I've also included delete functionality. As this functionality can be highly dangerous when there's a bug, I test using mock-fs.

I had been using globby, but switched to using fast-glob directly. When I was using globby v7 (backed by node-glob) I was able to use mock-fs. Now, using fast-glob, I get ENOENT errors thrown.

Expected behavior

Allow file-system to be mocked for testing using something like mock-fs or by passing a mock file system object to fast-glob as an option.

Steps to reproduce

  1. git clone https://github.com/shannonmoeller/ygor.git
  2. cd ygor
  3. npm it

Sample Code

https://github.com/shannonmoeller/ygor/blob/bcf063038fbecb7279468dbd32eecb44322d5e30/packages/files/test/files.js#L12

image

With `onlyFiles: false` directories at the root are not included

With the following directory tree:

+-- test/
|   +-- dir
|       +-- file.js
fg.sync('test/**', {onlyFiles: false});

// Result => ['test/dir/', 'test/dir/file.js']
// Should be => ['test', 'test/dir', 'test/dir/file.js']

For example with node-glob:

glob.sync('test/**', {nodir: false});

// Result => ['test', 'test/dir', 'test/dir/file.js']

Introduce smoke tests

We need to introduce smoke tests.

Now the package has some bugs that we don't even know about. We need to introduce the test of comparison with node-glob.

File not being captured with valid glob pattern

I have an issue that if my glob pattern is

src/**/*.html

And the file is directly under src/index.html it is not being captured.

Code:
return sync("src/**/*.html", { bashNative: [] });

My OS is OS Sierra.

Doesn't work on Windows with absolute paths

When I tried to use this on Windows with an absolute path, it appends the cwd to the absolute path

fastGlob.sync("C:/foo/*.bar");

Causes

Error: ENOENT: no such file or directory, scandir 'C:\my\current\working\dir\C:\foo'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.