Gulp: Can't exclude directories using src glob

Created on 16 Jan 2014  路  28Comments  路  Source: gulpjs/gulp

I can't exclude a directory from being copied over when using a src glob. Here's my task:

gulp.task('copy', function() {
    return gulp.src(['app/**', '!app/_tmp/**'])
        .pipe(gulp.dest('dist'));
});

Gulp copies over app/**, but app/_tmp/ is still being copied.

Expected:

+ app/
  + tmp/
      file1
      file2
  + css/
      styles.css
  + js/
      app.js
+ dist/
  + css/
      styles.css
  + js/
      app.js

Gulp output:

+ app/
  + tmp/
      file1
      file2
  + css/
      styles.css
  + js/
      app.js
+ dist/
  + tmp/
  + css/
      styles.css
  + js/
      app.js

Update: Clarified that the dist/_tmp/ directory does not contain any files

Most helpful comment

@aaronbushnell

gulp.src(['app/**', '!app/{_tmp,_tmp/**}'])

why?

  • !app/_tmp would match only the folder, but not any file within it - since it's not a globbing expression (a bug?)
  • !app/_tmp/** would match the files IN the _tmp folder, but not the folder itself, so the empty folder would be created

using the !app/{_tmp,_tmp/**} pattern uses a pattern to combine the both requirements and says:

give me all the dirs/files in app folder EXCEPT for _tmp folder content and the _tmp directory itself

:-)

All 28 comments

so tmp or _tmp ?

You're globbing for files, if you want to ignore the dir you need to: gulp.src(['app/**', '!app/_tmp/'])

@sindresorhus No dice. Now the dist/_tmp/ directory has the files from app/_tmp/ inside it.

Just an update: I updated to gulp 3.4.0 and am still having the same issue.

@aaronbushnell can you create a repo so we can clone it and work on the same dir structure? :)

The way I've made this work is to exclude the directory and the contents like so: gulp.src(['app/**', '!app/_tmp', '!app/_tmp/**'])

@gfloyd Hm, doing that _still_ copied over the tmp/ directory to dist/ (it was empty though).

@aaronbushnell

gulp.src(['app/**', '!app/{_tmp,_tmp/**}'])

why?

  • !app/_tmp would match only the folder, but not any file within it - since it's not a globbing expression (a bug?)
  • !app/_tmp/** would match the files IN the _tmp folder, but not the folder itself, so the empty folder would be created

using the !app/{_tmp,_tmp/**} pattern uses a pattern to combine the both requirements and says:

give me all the dirs/files in app folder EXCEPT for _tmp folder content and the _tmp directory itself

:-)

seems like that it is not clear - maybe we should create a recipe with that?

/cc @Contra

@stryju That worked perfectly! Thanks for the help. Will this be simplified in the future or should I plan on always writing exclusions like this?

more of a question @ https://github.com/isaacs/minimatch :-)


issue resolved? ;-)

Resolved. I'll bring the issue there. Thanks, all!

happy to help :)

It can be golfed further to !app/_tmp{,/**} so you don't need to repeat the directory name.

Does not work for me:

  gulp.src([
    'client/public/**/*',
    '!client/public/{vendor, vendor/**}',
    ], { base: './' })
    .pipe(gulp.dest('./dist'));

I'm still getting a populated vendor directory.

@chovy You have a space there that messes things up: {vendor, vendor/**}.

['!node_modules', '!node_modules/**', './**'] Worked for me, though I do like @aaronbushnell 's proposition in https://github.com/isaacs/minimatch/issues/25

I want to match everything except bower_components and anything inside.
So, I used the following code as suggested, but this still matches any folder that has .html files inside, together with those files.

return gulp.src([
        'src/*',
        '!src/**/*.html',
        '!src/bower_components{,/**}'
    ]

Any suggestions?

@alexpi this pattern will include the folders containing the html files, but should exclude the html files themselves - is that the case?

Sorry! There was no issue after all, another Gulp task was the culprit. The code works as expected.

Thanks to gfloyd, that solution works.

Thank you, @ktstowell, your solution worked really well. I'm working with Gulp Zip. It was really cumbersome to exclude a few folders/files and keep everything else including the project tree as it is.

@stryju Thank you for your solution of using !{_tmp,_tmp/**} method. I was using !(.gitignore,.sftp-config.json) to exclude a few files, but that didn't work.

Here's my code:

var gulp             = require( 'gulp' ),
    zip              = require( 'gulp-zip' );

gulp.task( 'zip', function() {

  return gulp.src( [
    '!{.gitignore,sftp-config.json}',
    '!node_modules', '!node_modules/**',
    '!dist', '!dist/**',
    '!assets/bower_components', '!assets/bower_components/**',
    './**',
  ] )
    .pipe( zip('archive.zip') )
    .pipe( gulp.dest( 'dist' ) );

});

This works well for me:

gulp.src(['app/**', '!app/_tmp{,/**/*}'])

Just as a note, I used to use:

gulp.src([
  '!node_modules{,/**}',
  '!dist{,/**}'
])

But then converting it to:

gulp.src([
  '!node_modules',
  '!node_modules/**',
  '!dist',
  '!dist/**'
])

Shaved off at least _3 whole seconds_ from my task.
Just a heads up, you might want to test your task if you care about performance; it would appear the dir{**} notation is really slow.

I was calling a folder above and copying all it's content expect from the folder I was currently inside(called "deploy"). This worked for me - gulp.src(['../**/*','!../deploy','!../deploy/**']).

Read through this thread and tried a bunch of things but still directories are copying over. I want to exclude ALL of /src but src/images/sub-directory ends up getting copied albeit empty.

gulp.src([
    'dev/wordpress/**/*',
    'dev/wordpress/**/.*',
    '!dev/wordpress/wp-content/themes/lucidworks/src{,/**/*}',
  ])
    .pipe(gulp.dest(myDest));

I end up with:

src/images/sub-directory/(empty)
src/fonts/(empty)

Using gulp babel. Any ideas?

There is one line solution. It is great when glob need to be apply relative:

@import "../../!(web)/*/.scss";

It import:

  • ../../name/x.scss
  • ../../name/name/x.scss
  • ../../name/web/x.scss
  • ../../name/web/web/x.scss

Don't import:

  • ../../web/x.scss
  • ../../web/name/x.scss

So it basically work as one level directory exclude.
It can be even something like this:

  • ../../!(web)/!(web)/**/.scss

Important: It won't work if added AFTER "*".
Like this one: ../ ../ *
/ !(web) / *.scss (how to choose on what level directory exclude when multilevel are included?)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lgg picture lgg  路  3Comments

yapcheahshen picture yapcheahshen  路  5Comments

XaBerr picture XaBerr  路  3Comments

amio picture amio  路  3Comments

silverskyvicto picture silverskyvicto  路  3Comments