From cc7660dd571110e5792e8bfdb13e0feab0df0950 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sat, 14 Mar 2015 22:27:49 +0000 Subject: [PATCH 1/8] Added editorconfig --- .editorconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5d12634 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From 4eacfeb0f3939de6e612a19b7e8a1a385b19a61b Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sat, 14 Mar 2015 22:28:31 +0000 Subject: [PATCH 2/8] Emit error on file not found with singular globs --- index.js | 30 ++++++++++++++++++++++++++++-- test/main.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 60dd858..d6f59b7 100644 --- a/index.js +++ b/index.js @@ -26,11 +26,19 @@ var gs = { // create stream and map events from globber to it var stream = through2.obj(negatives.length ? filterNegatives : undefined); + var found = false; + globber.on('error', stream.emit.bind(stream, 'error')); - globber.on('end', function(/* some args here so can't use bind directly */){ + globber.on('end', function(){ + if (opt.allowEmpty !== true && !found && globIsSingular(globber)) { + stream.emit('error', new Error('File not found with singular glob')); + } + stream.end(); }); globber.on('match', function(filename) { + found = true; + stream.write({ cwd: opt.cwd, base: basePath, @@ -87,7 +95,11 @@ var gs = { if (positives.length === 0) throw new Error('Missing positive glob'); // only one positive glob no need to aggregate - if (positives.length === 1) return streamFromPositive(positives[0]); + if (positives.length === 1) { + return streamFromPositive(positives[0]); + } else { + opt.allowEmpty = true; + } // create all individual streams var streams = positives.map(streamFromPositive); @@ -134,4 +146,18 @@ function toGlob(obj) { return obj.glob; } +function globIsSingular(glob) { + var globSet = glob.minimatch.set; + + if (globSet.length !== 1) { + return false; + } + + return globSet[0].every(isString); +} + +function isString(value) { + return typeof value === 'string'; +} + module.exports = gs; diff --git a/test/main.js b/test/main.js index 4e3df25..4184cc3 100644 --- a/test/main.js +++ b/test/main.js @@ -484,5 +484,37 @@ describe('glob-stream', function() { gs.create.bind(gs, ['!a', '!b'], {cwd: __dirname}).should.throw(/Missing positive glob/); }); + it('should emit error on singular glob when file not found', function(done) { + var stream = gs.create('notfound'); + should.exist(stream); + stream.on('error', function(err) { + err.should.match(/File not found with singular glob/); + done(); + }); + }); + + it('should not emit error when multiple globs not found', function(done) { + var stream = gs.create(['notfound', 'alsonotfound']); + should.exist(stream); + stream.on('error', function() { + should.fail(); + }); + + // For some reason `end` isn't called unless `data` is first? + stream.on('data', function(){}); + stream.once('end', done); + }); + + it('should not emit error on singular glob when allowEmpty is true', function(done) { + var stream = gs.create('notfound', { allowEmpty: true }); + should.exist(stream); + stream.on('error', function() { + should.fail(); + }); + + stream.on('data', function(){}); + stream.once('end', done); + }); + }); }); From 7c321c5e4aff378507e8b7f81267caae6f7d22f0 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sat, 14 Mar 2015 22:35:30 +0000 Subject: [PATCH 3/8] Added a test for {} in globs --- test/main.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/main.js b/test/main.js index 4184cc3..073498d 100644 --- a/test/main.js +++ b/test/main.js @@ -505,6 +505,18 @@ describe('glob-stream', function() { stream.once('end', done); }); + it('should not emit error on glob containing {} when not found', function(done) { + var stream = gs.create('notfound{a,b}'); + should.exist(stream); + stream.on('error', function() { + should.fail(); + }); + + // For some reason `end` isn't called unless `data` is first? + stream.on('data', function(){}); + stream.once('end', done); + }); + it('should not emit error on singular glob when allowEmpty is true', function(done) { var stream = gs.create('notfound', { allowEmpty: true }); should.exist(stream); From 0216b076a633c8f0249492ceb74ae67d8c1c13e1 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sat, 14 Mar 2015 23:01:41 +0000 Subject: [PATCH 4/8] inlined isString --- index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index d6f59b7..93e85e0 100644 --- a/index.js +++ b/index.js @@ -153,11 +153,9 @@ function globIsSingular(glob) { return false; } - return globSet[0].every(isString); -} - -function isString(value) { - return typeof value === 'string'; + return globSet[0].every(function isString(value) { + return typeof value === 'string'; + }); } module.exports = gs; From e13964941794b5a4a0efa5c41de6760979535804 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sun, 15 Mar 2015 12:29:42 +0000 Subject: [PATCH 5/8] Improved tests --- test/main.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/main.js b/test/main.js index 073498d..12d79b1 100644 --- a/test/main.js +++ b/test/main.js @@ -509,11 +509,10 @@ describe('glob-stream', function() { var stream = gs.create('notfound{a,b}'); should.exist(stream); stream.on('error', function() { - should.fail(); + throw new Error('Error was emitted'); }); - // For some reason `end` isn't called unless `data` is first? - stream.on('data', function(){}); + stream.resume(); stream.once('end', done); }); @@ -521,10 +520,10 @@ describe('glob-stream', function() { var stream = gs.create('notfound', { allowEmpty: true }); should.exist(stream); stream.on('error', function() { - should.fail(); + throw new Error('Error was emitted'); }); - stream.on('data', function(){}); + stream.resume(); stream.once('end', done); }); From f9e7bd802097d7898b7b2be6e1f06a3da30ba9ea Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sun, 15 Mar 2015 12:30:39 +0000 Subject: [PATCH 6/8] Whoops, missed that resume. --- test/main.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/main.js b/test/main.js index 12d79b1..0ee108f 100644 --- a/test/main.js +++ b/test/main.js @@ -500,8 +500,7 @@ describe('glob-stream', function() { should.fail(); }); - // For some reason `end` isn't called unless `data` is first? - stream.on('data', function(){}); + stream.resume(); stream.once('end', done); }); From 006467faf667c56df38671b783812abc7c5ad22f Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Sun, 15 Mar 2015 23:13:15 +0000 Subject: [PATCH 7/8] Now errors if any singular blog isn't found --- index.js | 13 +++++++------ test/main.js | 18 ++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 93e85e0..e351051 100644 --- a/index.js +++ b/index.js @@ -95,11 +95,7 @@ var gs = { if (positives.length === 0) throw new Error('Missing positive glob'); // only one positive glob no need to aggregate - if (positives.length === 1) { - return streamFromPositive(positives[0]); - } else { - opt.allowEmpty = true; - } + if (positives.length === 1) return streamFromPositive(positives[0]); // create all individual streams var streams = positives.map(streamFromPositive); @@ -107,8 +103,13 @@ var gs = { // then just pipe them to a single unique stream and return it var aggregate = new Combine(streams); var uniqueStream = unique('path'); + var returnStream = aggregate.pipe(uniqueStream); + + aggregate.on('error', function (err) { + returnStream.emit('error', err); + }); - return aggregate.pipe(uniqueStream); + return returnStream; function streamFromPositive(positive) { var negativeGlobs = negatives.filter(indexGreaterThan(positive.index)).map(toGlob); diff --git a/test/main.js b/test/main.js index 0ee108f..bca757f 100644 --- a/test/main.js +++ b/test/main.js @@ -75,7 +75,7 @@ describe('glob-stream', function() { var baseDir = join(__dirname, './fixtures'); var globArray = [ - './whatsgoingon/key/isaidhey/whatsgoingon/test.txt', + './whatsgoingon/hey/isaidhey/whatsgoingon/test.txt', './test.coffee', './whatsgoingon/test.js' ]; @@ -97,7 +97,7 @@ describe('glob-stream', function() { var baseDir = join(__dirname, './fixtures'); var globArray = [ - './whatsgoingon/key/isaidhey/whatsgoingon/test.txt', + './whatsgoingon/hey/isaidhey/whatsgoingon/test.txt', './test.coffee', './whatsgoingon/test.js' ]; @@ -307,7 +307,7 @@ describe('glob-stream', function() { var baseDir = join(__dirname, './fixtures'); var globArray = [ - './whatsgoingon/key/isaidhey/whatsgoingon/test.txt', + './whatsgoingon/hey/isaidhey/whatsgoingon/test.txt', './test.coffee', './whatsgoingon/test.js' ]; @@ -493,15 +493,13 @@ describe('glob-stream', function() { }); }); - it('should not emit error when multiple globs not found', function(done) { - var stream = gs.create(['notfound', 'alsonotfound']); + it('should emit error when a glob in multiple globs not found', function(done) { + var stream = gs.create(['notfound', './fixtures/whatsgoingon'], {cwd: __dirname}); should.exist(stream); - stream.on('error', function() { - should.fail(); + stream.on('error', function(err) { + err.should.match(/File not found with singular glob/); + done(); }); - - stream.resume(); - stream.once('end', done); }); it('should not emit error on glob containing {} when not found', function(done) { From e7777928c8d3974e3ce6ace37a99d82b99faa734 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Mon, 16 Mar 2015 14:05:41 +0000 Subject: [PATCH 8/8] Added allowEmpty docs --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3dc0faf..b36d7fe 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ You can pass any combination of globs. One caveat is that you can not only pass - cwdbase - Default is `false` - When true it is the same as saying opt.base = opt.cwd +- allowEmpty + - Default is `false` + - If true, won't emit an error when a glob pointing at a single file fails to match This argument is passed directly to [node-glob](https://github.com/isaacs/node-glob) so check there for more options