Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working anymore since 4.0.0 #67

Closed
sinedied opened this issue Apr 21, 2016 · 9 comments
Closed

Not working anymore since 4.0.0 #67

sinedied opened this issue Apr 21, 2016 · 9 comments

Comments

@sinedied
Copy link

I have this gulp task that works perfectly with gulp-filter@3.x:

gulp.task('build:sources', ['inject'], function() {
  var htmlFilter = $.filter('*.html', {restore: true});
  var jsFilter = $.filter('**/*.js', {restore: true});
  var cssFilter = $.filter('**/*.css', {restore: true});

  return gulp.src(path.join(conf.paths.tmp, 'index.html'))
    .pipe($.replace(/<html/g, '<html ng-strict-di'))
    .pipe($.useref())
    .pipe($.if('**/app*.js', $.intercept(setEnvironment)))
    .pipe(jsFilter)
    .pipe($.ngAnnotate())
    .pipe($.uglify({preserveComments: $.uglifySaveLicense})).on('error', conf.errorHandler('Uglify'))
    .pipe($.rev())
    .pipe(jsFilter.restore)
    .pipe(cssFilter)
    .pipe($.cleanCss({processImport: false}))
    .pipe($.rev())
    .pipe(cssFilter.restore)
    .pipe($.revReplace())
    .pipe(htmlFilter)
    .pipe($.htmlmin({
      removeComments: true,
      collapseWhitespace: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest(path.join(conf.paths.dist, '/')))
    .pipe($.size({title: path.join(conf.paths.dist, '/'), showFiles: true}));
});

Once I upgrade gulp-filter to 4.x, files do not get filtered anymore... I've read through the docs and I could not find any breaking change, what could I be missing?

@nfroidure
Copy link
Contributor

There are similar issues in the closed ones: https://github.com/sindresorhus/gulp-filter/issues?q=is%3Aissue+is%3Aclosed

@sinedied
Copy link
Author

I am aware, but it does not solve my issue.

Is there a good reason to force using process.cwd(), as it is not desirable in my case.
The issue seems to lies in the restore part, as my build seems to be working and receiving files, but it seems they are somehow reverted back to before their processing somehow...

@nfroidure
Copy link
Contributor

It is more probable that the filter was just applied for unexpected files ;). To be honest i have no idea of the implications of that change, i'm not an expert of the node-glob edge cases. Try to poke the commit author.

@sinedied
Copy link
Author

@cb1kenobi could you please explain why using cwd was needed in the first place? (I did not saw an issue reference in your PR)

I saw many projects that are sticking to 3.x due to this new behavior, maybe it would be nice to be able to chose whether or not to use a path relative to cwd or not? If it seems ok for you, I can prepare a PR for this, to make it optional.

@nfroidure
Copy link
Contributor

@sinedied more info for you here #61

@cb1kenobi
Copy link
Contributor

cb1kenobi commented Apr 22, 2016

@sinedied I wrote a decent description in the PR of the rationale behind the change: #59.

I believe my change is more correct than before my change.

Before my change, minimatch would be comparing your **/*.js filter to file.relative which contains just the filename and no path info. I believe this is a design flaw in gulp. This means gulp-filter was never performing the correct match, but you probably didn't notice or care as long as all of your *.js files passed through the filter.

However, I agree there is still an issue. If the relative path resolves outside the current directory tree, then minimatch will not properly match it. In other words, minimatch doesn't appear to like it if the path starts with ... I don't know if that's a bug in minimatch or what.

For example:

var minimatch = require('minimatch');
console.log(minimatch('../bar.js', '**/*.js')); // false
console.log(minimatch('/bar.js', '**/*.js')); // true

I did a quick test and said if the relative path starts with .. (it's outside the current directory), then resolve it to an absolute path before calling minimatch:

// change this:
var match = typeof pattern === 'function' ? pattern(file) :
    multimatch(path.relative(file.cwd, file.path), pattern, options).length > 0;

// to this:
var match;
if (typeof pattern === 'function') {
    match = pattern(file);
} else {
    var relPath = path.relative(file.cwd, file.path);
    if (relPath.indexOf('..') === 0) {
        relPath = path.resolve(relPath);
    }
    match = multimatch(relPath, pattern, options).length > 0;
}

This seems to work for me regardless if the input glob is absolute or relative. If you could try dropping that into your gulp-filter's index.js and see if that solves the problem. I'm not sure what sort of side effects this will cause when converting relative paths to absolute.

Update: removed relPath = file.relative; from code. It was accidentally left in there.

@sinedied
Copy link
Author

I tried your fix, and it effectively solves the issue. 👍

Resolving to absolute path seems dodgy though, maybe the real issue here lies with multimatch not properly matching paths containing .. in the first place? (maybe because of missing an escape of the . character in the regex?)

I'm not sure what's the best fix here...

@cb1kenobi
Copy link
Contributor

Well, well... isaacs/minimatch#30 (comment).

@sinedied
Copy link
Author

Nice :)

Until then, is there any workaround I could use, except for modifying directly the gulp-filter source or sticking to @3.x?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants