├── .gitignore ├── .jshintignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules 4 | build 5 | *.node 6 | components 7 | *.orig 8 | .idea 9 | -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "camelcase": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "forin": true, 7 | "immed": true, 8 | "latedef": true, 9 | "newcap": true, 10 | "noarg": true, 11 | "noempty": true, 12 | "nonew": true, 13 | "regexp": true, 14 | "strict": true, 15 | "trailing": true, 16 | "undef": true, 17 | "unused": true, 18 | "node": true 19 | } 20 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules 4 | build 5 | *.node 6 | components 7 | *.orig 8 | .idea 9 | test 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "10" 5 | - "12" 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 [Richardson & Sons, LLC](http://richardsonandsons.com/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gulp-rimraf ![status](https://secure.travis-ci.org/robrich/gulp-rimraf.png?branch=master) 2 | =========== 3 | 4 | Deprecated in favor of [https://github.com/gulpjs/gulp/blob/master/docs/recipes/delete-files-folder.md](https://github.com/gulpjs/gulp/blob/master/docs/recipes/delete-files-folder.md) 5 | 6 | [rimraf](https://github.com/isaacs/rimraf) plugin for [gulp](https://github.com/gulpjs/gulp) 7 | 8 | Usage 9 | ----- 10 | 11 | 1. Delete a folder: use [rimraf](https://github.com/isaacs/rimraf) directly *(you don't need gulp-rimraf!)*: 12 | 13 | ```javascript 14 | var rimraf = require('rimraf'); // rimraf directly 15 | gulp.task('task', function (cb) { 16 | rimraf('./folder', cb); 17 | }); 18 | ``` 19 | 20 | 2. Delete some files in a folder: use gulp-rimraf 21 | 22 | ```javascript 23 | var ignore = require('gulp-ignore'); 24 | var rimraf = require('gulp-rimraf'); 25 | 26 | gulp.task('task', function() { 27 | return gulp.src('./**/*.js', { read: false }) // much faster 28 | .pipe(ignore('node_modules/**')) 29 | .pipe(rimraf()); 30 | }); 31 | ``` 32 | Setting option `read` to false prevents gulp to read the contents of the files and makes this task much faster. 33 | 34 | Files and folders outside the current working directory can be removed with `force` option. 35 | 36 | ```javascript 37 | var rimraf = require('gulp-rimraf'); 38 | 39 | gulp.task('task', function() { 40 | return gulp.src('../temp/*.js', { read: false }) 41 | .pipe(rimraf({ force: true })); 42 | }); 43 | ``` 44 | 45 | LICENSE 46 | ------- 47 | 48 | (MIT License) 49 | 50 | Copyright (c) 2014 [Richardson & Sons, LLC](http://richardsonandsons.com/) 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining 53 | a copy of this software and associated documentation files (the 54 | "Software"), to deal in the Software without restriction, including 55 | without limitation the rights to use, copy, modify, merge, publish, 56 | distribute, sublicense, and/or sell copies of the Software, and to 57 | permit persons to whom the Software is furnished to do so, subject to 58 | the following conditions: 59 | 60 | The above copyright notice and this permission notice shall be 61 | included in all copies or substantial portions of the Software. 62 | 63 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 64 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 65 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 66 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 67 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 68 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 69 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 70 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var through = require('through2'); 4 | var rimraf = require('rimraf'); 5 | var path = require('path'); 6 | 7 | module.exports = function(options){ 8 | if (!options) { 9 | options = {}; 10 | } 11 | 12 | if (options.force && typeof options.force !== 'boolean') { 13 | options.force = false; 14 | } 15 | 16 | function del(file, encoding, cb){ 17 | //jshint validthis:true 18 | 19 | var cwd = file.cwd || process.cwd(); 20 | // For safety always resolve paths 21 | var filepath = path.resolve(cwd, file.path); 22 | var relativeFromCwd = path.relative(cwd, filepath); 23 | 24 | if (relativeFromCwd === '') { 25 | this.emit('error', new Error('Cannot delete the current working directory: ' + filepath)); 26 | this.push(file); 27 | return cb(); 28 | } 29 | 30 | if (!options.force && relativeFromCwd.substr(0, 2) === '..') { 31 | this.emit('error', new Error('Cannot delete files or folders outside the current working directory: ' + filepath)); 32 | this.push(file); 33 | return cb(); 34 | } 35 | 36 | if (options.verbose) { 37 | console.log('gulp-rimraf: removed '+filepath); 38 | } 39 | 40 | rimraf(filepath, function (err) { 41 | if (err) { 42 | this.emit('error', err); 43 | } 44 | this.push(file); 45 | cb(); 46 | }.bind(this)); 47 | } 48 | 49 | return through.obj(del); 50 | }; 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-rimraf", 3 | "description": "rimraf plugin for gulp", 4 | "version": "1.0.0", 5 | "homepage": "https://github.com/robrich/gulp-rimraf", 6 | "repository": "git://github.com/robrich/gulp-rimraf.git", 7 | "author": "Rob Richardson (http://robrich.org/)", 8 | "main": "./index.js", 9 | "keywords": [ 10 | "gulpplugin", 11 | "rimraf", 12 | "clean", 13 | "remove", 14 | "delete", 15 | "gulp-clean" 16 | ], 17 | "dependencies": { 18 | "rimraf": "^2.6.2", 19 | "through2": "^3.0.1" 20 | }, 21 | "devDependencies": { 22 | "jshint": "^2.9.5", 23 | "mocha": "^6.1.4", 24 | "should": "^13.2.0", 25 | "vinyl": "^2.2.0" 26 | }, 27 | "scripts": { 28 | "test": "mocha && jshint ." 29 | }, 30 | "license": "MIT" 31 | } 32 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false, beforeEach:false, afterEach:false */ 2 | 3 | 'use strict'; 4 | 5 | var rimraf = require('../'); 6 | 7 | var Vinyl = require('vinyl'); 8 | var fs = require('fs'); 9 | var path = require('path'); 10 | var should = require('should'); 11 | 12 | describe('gulp-rimraf', function() { 13 | describe('rimraf()', function() { 14 | var tempFileContent = 'A test generated this file and it is safe to delete'; 15 | var cwd = process.cwd(); 16 | var base = path.resolve('./test'); 17 | 18 | var realLog = console.log; 19 | 20 | var logContent = []; 21 | beforeEach(function () { 22 | console.log = function () { 23 | logContent.push(Array.prototype.join.call(arguments, ' ')); 24 | }; 25 | }); 26 | afterEach(function () { 27 | console.log = realLog; 28 | logContent = []; 29 | }); 30 | 31 | it('should pass file structure through', function(done) { 32 | // Arrange 33 | var tempFile = path.join(base, 'temp.txt'); 34 | 35 | var stream = rimraf(); 36 | var fakeFile = new Vinyl({ 37 | cwd: cwd, 38 | base: base, 39 | path: tempFile, 40 | contents: new Buffer(tempFileContent) 41 | }); 42 | 43 | // Assert 44 | stream.once('data', function(actualFile){ 45 | // Test that content passed through 46 | should.exist(actualFile); 47 | should.exist(actualFile.path); 48 | should.exist(actualFile.contents); 49 | actualFile.path.should.equal(tempFile); 50 | String(actualFile.contents).should.equal(tempFileContent); 51 | done(); 52 | }); 53 | 54 | // Act 55 | stream.write(fakeFile); 56 | stream.end(); 57 | }); 58 | 59 | it('should delete a file', function(done) { 60 | // Arrange 61 | var tempFile = path.join(base, 'temp.txt'); 62 | fs.writeFileSync(tempFile, tempFileContent); 63 | fs.existsSync(tempFile).should.equal(true); 64 | 65 | var stream = rimraf(); 66 | var fakeFile = new Vinyl({ 67 | cwd: cwd, 68 | base: base, 69 | path: tempFile, 70 | contents: new Buffer(tempFileContent) 71 | }); 72 | 73 | // Assert 74 | stream.once('data', function(/*file, enc, cb*/){ 75 | // Test that file is gone 76 | fs.existsSync(tempFile).should.equal(false); 77 | done(); 78 | }); 79 | 80 | // Act 81 | stream.write(fakeFile); 82 | stream.end(); 83 | }); 84 | 85 | it('should delete an empty folder', function(done) { 86 | // Arrange 87 | var tempDir = path.join(base, 'tempDir'); 88 | fs.mkdirSync(tempDir); 89 | fs.existsSync(tempDir).should.equal(true); 90 | 91 | var stream = rimraf(); 92 | var fakeFile = new Vinyl({ 93 | cwd: cwd, 94 | base: base, 95 | path: tempDir, 96 | contents: '' 97 | }); 98 | 99 | // Assert 100 | stream.once('data', function(/*file, enc, cb*/){ 101 | // Test that dir is gone 102 | fs.existsSync(tempDir).should.equal(false); 103 | done(); 104 | }); 105 | 106 | // Act 107 | stream.write(fakeFile); 108 | stream.end(); 109 | }); 110 | 111 | it('should delete a folder with files', function(done) { 112 | // Arrange 113 | var tempDir = path.join(base, 'tempDir'); 114 | fs.mkdirSync(tempDir); 115 | fs.existsSync(tempDir).should.equal(true); 116 | fs.writeFileSync(path.join(tempDir,'file1.txt'), tempFileContent); 117 | fs.writeFileSync(path.join(tempDir,'file2.txt'), tempFileContent); 118 | 119 | var stream = rimraf(); 120 | var fakeFile = new Vinyl({ 121 | cwd: cwd, 122 | base: base, 123 | path: tempDir, 124 | contents: '' 125 | }); 126 | 127 | // Assert 128 | stream.once('data', function(/*file, enc, cb*/){ 129 | // Test that dir is gone 130 | fs.existsSync(tempDir).should.equal(false); 131 | done(); 132 | }); 133 | 134 | // Act 135 | stream.write(fakeFile); 136 | stream.end(); 137 | }); 138 | 139 | it('should not error if target file does not exist', function(done) { 140 | // Arrange 141 | var tempFile = path.join(base, 'noexist.txt'); 142 | fs.existsSync(tempFile).should.equal(false); 143 | 144 | var stream = rimraf(); 145 | var fakeFile = new Vinyl({ 146 | cwd: cwd, 147 | base: base, 148 | path: tempFile, 149 | contents: new Buffer(tempFileContent) 150 | }); 151 | 152 | // Assert 153 | stream.once('data', function(/*actualFile*/){ 154 | // Test that file is gone 155 | fs.existsSync(tempFile).should.equal(false); 156 | done(); 157 | }); 158 | 159 | // Act 160 | stream.write(fakeFile); 161 | stream.end(); 162 | }); 163 | 164 | it('should not error if target dir does not exist', function(done) { 165 | // Arrange 166 | var tempDir = './noexistDir'; 167 | fs.existsSync(tempDir).should.equal(false); 168 | 169 | var stream = rimraf(); 170 | var fakeFile = new Vinyl({ 171 | cwd: cwd, 172 | base: base, 173 | path: tempDir, 174 | contents: '' 175 | }); 176 | 177 | // Assert 178 | stream.once('data', function(/*actualFile*/){ 179 | // Test that dir is gone 180 | fs.existsSync(tempDir).should.equal(false); 181 | done(); 182 | }); 183 | 184 | // Act 185 | stream.write(fakeFile); 186 | stream.end(); 187 | }); 188 | 189 | it('cannot remove the current working directory', function (done) { 190 | // Arrange 191 | var stream = rimraf(); 192 | 193 | // Assert 194 | stream.once('error', function () { 195 | // Test that cwd is not removed 196 | fs.existsSync(cwd).should.equal(true); 197 | done(); 198 | }); 199 | 200 | // Act 201 | stream.write(new Vinyl({ 202 | cwd: cwd, 203 | base: cwd, 204 | path: cwd 205 | })); 206 | 207 | stream.end(); 208 | }); 209 | 210 | it('cannot delete a folder outside the current working directory without force', function (done) { 211 | // Arrange 212 | var stream = rimraf(); 213 | var tempFolder = path.resolve(cwd, '../gulp-rimrafTemp/'); 214 | 215 | if (!fs.existsSync(tempFolder)) { 216 | fs.mkdirSync(tempFolder); 217 | } 218 | 219 | // Assert 220 | stream.once('error', function () { 221 | var exists = fs.existsSync(tempFolder); 222 | exists.should.equal(true); 223 | if (exists) { 224 | fs.unlink(tempFolder, function () { 225 | done(); 226 | }); 227 | } else { 228 | done(); 229 | } 230 | }); 231 | 232 | // Act 233 | stream.write(new Vinyl({ 234 | cwd: cwd, 235 | base: cwd, 236 | path: tempFolder 237 | })); 238 | 239 | stream.end(); 240 | }); 241 | 242 | it('cannot delete a file outside the current working directory without force', function (done) { 243 | // Arrange 244 | var stream = rimraf(); 245 | var tempFile = path.resolve(cwd, '../temp.txt'); 246 | 247 | if (!fs.existsSync(tempFile)) { 248 | fs.writeFileSync(tempFile, tempFileContent); 249 | } 250 | 251 | // Assert 252 | stream.once('error', function () { 253 | var exists = fs.existsSync(tempFile); 254 | exists.should.equal(true); 255 | if (exists) { 256 | fs.unlink(tempFile, function () { 257 | done(); 258 | }); 259 | } else { 260 | done(); 261 | } 262 | }); 263 | 264 | // Act 265 | stream.write(new Vinyl({ 266 | cwd: cwd, 267 | base: cwd, 268 | path: tempFile 269 | })); 270 | 271 | stream.end(); 272 | }); 273 | 274 | it('can delete a folder outside the current working directory with force', function (done) { 275 | // Arrange 276 | var stream = rimraf({ force: true }); 277 | var tempFolder = path.resolve(cwd, '../gulp-rimrafTemp/'); 278 | 279 | if (!fs.existsSync(tempFolder)) { 280 | fs.mkdirSync(tempFolder); 281 | } 282 | 283 | // Assert 284 | stream.once('data', function () { 285 | fs.existsSync(tempFolder).should.equal(false); 286 | done(); 287 | }); 288 | 289 | // Act 290 | stream.write(new Vinyl({ 291 | cwd: cwd, 292 | base: cwd, 293 | path: tempFolder 294 | })); 295 | 296 | stream.end(); 297 | }); 298 | 299 | it('can delete a file outside the current working directory with force', function (done) { 300 | // Arrange 301 | var stream = rimraf({ force: true }); 302 | var tempFile = path.resolve(cwd, '../temp.txt'); 303 | 304 | if (!fs.existsSync(tempFile)) { 305 | fs.writeFileSync(tempFile, tempFileContent); 306 | } 307 | 308 | // Assert 309 | stream.once('data', function () { 310 | fs.existsSync(tempFile).should.equal(false); 311 | done(); 312 | }); 313 | 314 | // Act 315 | stream.write(new Vinyl({ 316 | cwd: cwd, 317 | base: cwd, 318 | path: tempFile 319 | })); 320 | 321 | stream.end(); 322 | }); 323 | 324 | it('supports resolved file.path', function (done) { 325 | // Arrange 326 | var stream = rimraf(); 327 | var resolvedTempFile = path.resolve(cwd, './tempResolved.txt'); 328 | 329 | if (!fs.existsSync(resolvedTempFile)) { 330 | fs.writeFileSync(resolvedTempFile, tempFileContent); 331 | } 332 | 333 | // Assert 334 | stream.once('data', function () { 335 | fs.existsSync(resolvedTempFile).should.equal(false); 336 | done(); 337 | }); 338 | 339 | // Act 340 | stream.write(new Vinyl({ 341 | cwd: cwd, 342 | base: cwd, 343 | path: resolvedTempFile 344 | })); 345 | 346 | stream.end(); 347 | }); 348 | 349 | it('supports unresolved file.path', function (done) { 350 | // Arrange 351 | var stream = rimraf(); 352 | var unresolvedTempFile = './tempUnresolved.txt'; 353 | 354 | if (!fs.existsSync(unresolvedTempFile)) { 355 | fs.writeFileSync(unresolvedTempFile, tempFileContent); 356 | } 357 | 358 | // Assert 359 | stream.once('data', function () { 360 | fs.existsSync(unresolvedTempFile).should.equal(false); 361 | done(); 362 | }); 363 | 364 | // Act 365 | stream.write(new Vinyl({ 366 | cwd: cwd, 367 | base: base, 368 | path: unresolvedTempFile 369 | })); 370 | 371 | stream.end(); 372 | }); 373 | 374 | it('should not log when not directed to', function(done) { 375 | // Arrange 376 | var tempFile = path.join(base, 'temp.txt'); 377 | fs.writeFileSync(tempFile, tempFileContent); 378 | fs.existsSync(tempFile).should.equal(true); 379 | 380 | var stream = rimraf(); 381 | var fakeFile = new Vinyl({ 382 | cwd: cwd, 383 | base: base, 384 | path: tempFile, 385 | contents: new Buffer(tempFileContent) 386 | }); 387 | 388 | // Assert 389 | stream.once('data', function(/*file, enc, cb*/){ 390 | // Test that file is gone 391 | fs.existsSync(tempFile).should.equal(false); 392 | logContent.length.should.equal(0); 393 | done(); 394 | }); 395 | 396 | // Act 397 | stream.write(fakeFile); 398 | stream.end(); 399 | }); 400 | 401 | it('should log when directed to', function(done) { 402 | // Arrange 403 | var tempFile = path.join(base, 'temp.txt'); 404 | fs.writeFileSync(tempFile, tempFileContent); 405 | fs.existsSync(tempFile).should.equal(true); 406 | 407 | var stream = rimraf({ 408 | verbose: true 409 | }); 410 | var fakeFile = new Vinyl({ 411 | cwd: cwd, 412 | base: base, 413 | path: tempFile, 414 | contents: new Buffer(tempFileContent) 415 | }); 416 | 417 | // Assert 418 | stream.once('data', function(/*file, enc, cb*/){ 419 | // Test that file is gone 420 | fs.existsSync(tempFile).should.equal(false); 421 | logContent.length.should.equal(1); 422 | logContent[0].indexOf(tempFile).should.be.above(-1); 423 | done(); 424 | }); 425 | 426 | // Act 427 | stream.write(fakeFile); 428 | stream.end(); 429 | }); 430 | }); 431 | }); 432 | --------------------------------------------------------------------------------