blob: 36cf7b67079b60bbe24d65fbefe0083cb2290c1a [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var inherits = require('util').inherits;
4
5var glob = require('glob');
6var extend = require('extend');
7var Readable = require('readable-stream').Readable;
8var globParent = require('glob-parent');
9var toAbsoluteGlob = require('to-absolute-glob');
10var removeTrailingSeparator = require('remove-trailing-separator');
11
12var globErrMessage1 = 'File not found with singular glob: ';
13var globErrMessage2 = ' (if this was purposeful, use `allowEmpty` option)';
14
15function getBasePath(ourGlob, opt) {
16 return globParent(toAbsoluteGlob(ourGlob, opt));
17}
18
19function globIsSingular(glob) {
20 var globSet = glob.minimatch.set;
21 if (globSet.length !== 1) {
22 return false;
23 }
24
25 return globSet[0].every(function isString(value) {
26 return typeof value === 'string';
27 });
28}
29
30function GlobStream(ourGlob, negatives, opt) {
31 if (!(this instanceof GlobStream)) {
32 return new GlobStream(ourGlob, negatives, opt);
33 }
34
35 var ourOpt = extend({}, opt);
36
37 Readable.call(this, {
38 objectMode: true,
39 highWaterMark: ourOpt.highWaterMark || 16,
40 });
41
42 // Delete `highWaterMark` after inheriting from Readable
43 delete ourOpt.highWaterMark;
44
45 var self = this;
46
47 function resolveNegatives(negative) {
48 return toAbsoluteGlob(negative, ourOpt);
49 }
50
51 var ourNegatives = negatives.map(resolveNegatives);
52 ourOpt.ignore = ourNegatives;
53
54 var cwd = ourOpt.cwd;
55 var allowEmpty = ourOpt.allowEmpty || false;
56
57 // Extract base path from glob
58 var basePath = ourOpt.base || getBasePath(ourGlob, ourOpt);
59
60 // Remove path relativity to make globs make sense
61 ourGlob = toAbsoluteGlob(ourGlob, ourOpt);
62 // Delete `root` after all resolving done
63 delete ourOpt.root;
64
65 var globber = new glob.Glob(ourGlob, ourOpt);
66 this._globber = globber;
67
68 var found = false;
69
70 globber.on('match', function(filepath) {
71 found = true;
72 var obj = {
73 cwd: cwd,
74 base: basePath,
75 path: removeTrailingSeparator(filepath),
76 };
77 if (!self.push(obj)) {
78 globber.pause();
79 }
80 });
81
82 globber.once('end', function() {
83 if (allowEmpty !== true && !found && globIsSingular(globber)) {
84 var err = new Error(globErrMessage1 + ourGlob + globErrMessage2);
85
86 return self.destroy(err);
87 }
88
89 self.push(null);
90 });
91
92 function onError(err) {
93 self.destroy(err);
94 }
95
96 globber.once('error', onError);
97}
98inherits(GlobStream, Readable);
99
100GlobStream.prototype._read = function() {
101 this._globber.resume();
102};
103
104GlobStream.prototype.destroy = function(err) {
105 var self = this;
106
107 this._globber.abort();
108
109 process.nextTick(function() {
110 if (err) {
111 self.emit('error', err);
112 }
113 self.emit('close');
114 });
115};
116
117module.exports = GlobStream;