Search code examples
gulpglob

gulp.src (glob-stream) positive glob after negative glob kills match


I was under the impression and also from looking at the code that the a positive glob would only be restricted by negative globs that come AFTER IT.

So how comes that

gulp.src([
           '../WebContent/g/css/ng-client.css'
        ],{base: '../WebContent'}).pipe(using()) 

results in ng-client.css being listed.

While

gulp.src([
           '!../WebContent/g/css/*',
           '../WebContent/g/css/ng-client.css'
        ],{base: '../WebContent'}).pipe(using())  

does not list the same file?

I want to figure out what is wrong with the way I am thinking of those glob streams that is causing me to expect the second code block to return the file as well - not a solution to how to overcome this scenario, I have seen suggestions like the one In: Glob / minimatch: how to gulp.src() everything, then exclude folder but keep one file in it

and I know that I can do something similar like:

gulp.src([
       '!../WebContent/g/css/!(ng-client.css)',
       '../WebContent/g/css/ng-client.css'
    ],{base: '../WebContent'}).pipe(using())  

The Q is why doesn't the second return the file as I expect it to?


Solution

  • This is interesting.

    Your reading of the glob-stream source code seems to be correct. It also matches the documentation of glob-stream itself. But then why is gulp behaving differently than expected? I think it's because you're not running the code you have been reading.

    Even on a fresh install of gulp you're not using the newest version of glob-stream. Here's the relevant excerpt of npm list from a project I just created:

    ├─┬ [email protected]
    │ └─┬ [email protected]
    │   ├─┬ [email protected]
    

    That means [email protected] is being used. The source code you linked is from [email protected].

    Going through the version tags of glob-stream on GitHub the first mention of glob order in the documentation is in 4.0.1. So it looks like a backwards-incompatible change in behavior was made between major versions 3.x and 4.x.

    We can check this by running glob-stream directly:

    var gs = require('glob-stream');
    gs.create([
      '!../WebContent/g/css/ng*',
      '../WebContent/g/css/ng-client.css'
    ]).pipe(using());
    

    Running this with [email protected] (the last release of 3.x) returns no files. Running it with [email protected] does return the ng-client.css file.

    The thing that makes me wonder is that the gulp documentation explicitly mentions the behavior you have been expecting all along. But in fact running the very same example code they use in their documenation doesn't yield the results they claim:

    gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js'])
    

    Running this with [email protected] only returns client/a.js, but not client/bad.js.

    It looks like somebody else was having the same problem. There's a module called gulp-src-ordered-globs (which refers to this a GitHub issue). Using this module both your example and the one from the Gulp.js documentation work as expected.

    If you really want to get to the bottom of all this, it's probably best to open an issue on GitHub or ask somebody on the Gulp.js Gitter.