sindresorhus / gulp-filter

Filter files in a `vinyl` stream
MIT License
315 stars 37 forks source link

The first usage example is incorrect and gives the wrong impression about how gulp-filter matches files. #55

Closed lddubeau closed 8 years ago

lddubeau commented 8 years ago

I'm referring to this

var gulp = require('gulp');
var jscs = require('gulp-jscs');
var gulpFilter = require('gulp-filter');

gulp.task('default', function () {
    // create filter instance inside task function
    var filter = gulpFilter(['*', '!src/vendor']);

    return gulp.src('src/*.js')
        // filter a subset of the files
        .pipe(filter)
        // run them through a plugin
        .pipe(jscs())
        .pipe(gulp.dest('dist'));
});

The intent seems to process everything in src but to exclude the files in src/vendor. Problems:

  1. The filter does no work because src/*.js won't go into subdirectories in the first place. You could remove the filter and you'd still not get anything from src/vendor into dest.
  2. If we amend to src/**/*.js then this pattern will cover every .js file in src, including subdirectories but the filter still gives the wrong impression. It does the work of excluding files in src/vendor not because of !src/vendor but because of *, which matches only files that are not in a subdirectory. You could reduce the filter to gulpFilter('*') and it would still exclude src/vendor and everything in it.
  3. If we amend the filter so that we have ** instead of *, then the filter no longer works because !src/vendor does not match anything. Why? Because gulp-filter matches against the file's relative path.

Ultimately, the code I see doing what the example seems to be illustrating should be:

var gulp = require('gulp');
var jscs = require('gulp-jscs');
var gulpFilter = require('gulp-filter');

gulp.task('default', function () {
    // create filter instance inside task function
    var filter = gulpFilter(['**', '!vendor/**']);

    return gulp.src('src/**/*.js')
        // filter a subset of the files
        .pipe(filter)
        // run them through a plugin
        .pipe(jscs())
        .pipe(gulp.dest('dist'));
});

The examples based off of this one should also be fixed.

mix3d commented 8 years ago

THANK YOU!!!! This finally fixed the problem's I'd been having trying to use this plugin, and was very confused why a single * would work, since both glob patterns didn't match the rest of gulp's glob styles.

leocaseiro commented 8 years ago

Perfect! This fix my issue as well. The documentation should be updated.

:+1:

nfroidure commented 8 years ago

I agree, submitting a PR would help to clean it quicker.

VAggrippino commented 8 years ago

Hah! One lousy asterisk caused my problem and it took me several hours to figure it out. Thank you, @lddubeau, for posting this issue. It helped me solve a problem that was driving me crazy.

ref: http://stackoverflow.com/q/35911876/2948042

sindresorhus commented 8 years ago

This was fixed in https://github.com/leocaseiro/gulp-filter/commit/922496e5507c39ed44f181f209b1e3866c71ae24.

ghost commented 8 years ago

The "Usage" section on the npm page still shows the example with a single asterisk: https://www.npmjs.com/package/gulp-filter#filter-only

const f = filter(['*', '!src/vendor']);