Skip to content

Commit c294c7d

Browse files
committed
Allow cleaning of folders outside of webpack dir (but still within root dir)
1 parent 0e88ae6 commit c294c7d

File tree

4 files changed

+73
-95
lines changed

4 files changed

+73
-95
lines changed

index.js

Lines changed: 27 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,9 @@ function Plugin(paths, options) {
5353
Plugin.prototype.apply = function (compiler) {
5454
var _this = this;
5555
var results = [];
56-
var insideFailCheck;
57-
var pathSplit;
5856
var workingDir;
5957
var projectRootDir;
6058
var webpackDir;
61-
var projectDirSplit;
6259

6360
// exit if no paths passed in
6461
if (_this.paths === void 0) {
@@ -84,17 +81,6 @@ Plugin.prototype.apply = function (compiler) {
8481
webpackDir = upperCaseWindowsRoot(webpackDir);
8582
}
8683

87-
// This is not perfect.
88-
projectDirSplit = projectRootDir.split(path.sep);
89-
if ((projectRootDir !== workingDir.slice(0, projectRootDir.length)) &&
90-
(projectRootDir.indexOf(workingDir) === -1)) {
91-
_this.options.verbose &&
92-
console.warn('clean-webpack-plugin: ' + _this.options.root +
93-
' project root is outside of project. Skipping all...');
94-
results.push({ path: projectRootDir, output: 'project root is outside of project' });
95-
return results;
96-
}
97-
9884
// preform an rm -rf on each path
9985
_this.paths.forEach(function (rimrafPath) {
10086
rimrafPath = path.resolve(_this.options.root, rimrafPath);
@@ -103,59 +89,42 @@ Plugin.prototype.apply = function (compiler) {
10389
rimrafPath = upperCaseWindowsRoot(rimrafPath);
10490
}
10591

106-
pathSplit = rimrafPath.split(path.sep);
107-
projectDirSplit.forEach((function (singleDir, index) {
108-
if (singleDir === '') {
109-
return;
110-
}
111-
112-
if (pathSplit[index] !== singleDir) {
113-
insideFailCheck = true;
114-
}
115-
}));
92+
// disallow deletion any directories outside of root path.
93+
if (rimrafPath.indexOf(projectRootDir) < 0) {
94+
console.warn('clean-webpack-plugin: ' + rimrafPath + ' is outside of the project root. Skipping...');
95+
results.push({ path: rimrafPath, output: 'must be inside the project root' });
96+
return;
97+
}
11698

117-
if (insideFailCheck) {
99+
if (rimrafPath === projectRootDir) {
118100
_this.options.verbose &&
119101
console.warn(
120-
'clean-webpack-plugin: ' + rimrafPath + ' must be inside the project root. Skipping...');
121-
results.push({ path: rimrafPath, output: 'must be inside the project root' });
102+
'clean-webpack-plugin: ' + rimrafPath + ' is equal to project root. Skipping...');
103+
results.push({ path: rimrafPath, output: 'is equal to project root' });
122104
return;
123105
}
124106

125-
// disallow deletion of project path and any directories outside of project path.
126-
if (rimrafPath.indexOf(projectRootDir) === 0) {
127-
if (rimrafPath === projectRootDir) {
128-
_this.options.verbose &&
129-
console.warn(
130-
'clean-webpack-plugin: ' + rimrafPath + ' is equal to project root. Skipping...');
131-
results.push({ path: rimrafPath, output: 'is equal to project root' });
132-
return;
133-
}
134-
135-
if (rimrafPath === webpackDir) {
136-
_this.options.verbose &&
137-
console.warn('clean-webpack-plugin: ' + rimrafPath + ' would delete webpack. Skipping...');
138-
results.push({ path: rimrafPath, output: 'would delete webpack' });
139-
return;
140-
}
141-
142-
// If path is completely outside of the project. Should not be able to happen. Including as an extra fail-safe.
143-
if (projectRootDir.indexOf(rimrafPath) !== -1 || rimrafPath === __dirname ||
144-
rimrafPath === process.cwd()) {
145-
_this.options.verbose &&
146-
console.warn('clean-webpack-plugin: ' + rimrafPath + ' is unsafe to delete. Skipping...');
147-
results.push({ path: rimrafPath, output: 'is unsafe to delete' });
148-
return;
149-
}
150-
151-
if (_this.options.dry !== true) {
152-
rimraf.sync(rimrafPath);
153-
}
107+
if (rimrafPath === webpackDir) {
108+
_this.options.verbose &&
109+
console.warn('clean-webpack-plugin: ' + rimrafPath + ' would delete webpack. Skipping...');
110+
results.push({ path: rimrafPath, output: 'would delete webpack' });
111+
return;
112+
}
154113

114+
if (rimrafPath === __dirname || rimrafPath === process.cwd()) {
155115
_this.options.verbose &&
156-
console.warn('clean-webpack-plugin: ' + rimrafPath + ' has been removed.');
157-
results.push({ path: rimrafPath, output: 'removed' });
116+
console.log('clean-webpack-plugin: ' + rimrafPath + ' is working directory. Skipping...');
117+
results.push({ path: rimrafPath, output: 'is working directory' });
118+
return;
158119
}
120+
121+
if (_this.options.dry !== true) {
122+
rimraf.sync(rimrafPath);
123+
}
124+
125+
_this.options.verbose &&
126+
console.warn('clean-webpack-plugin: ' + rimrafPath + ' has been removed.');
127+
results.push({ path: rimrafPath, output: 'removed' });
159128
});
160129

161130
return results;

test/index_spec.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,29 @@ var tests = require('./tests');
88
describe('clean-webpack-plugin', function () {
99
describe('native os', function () {
1010
this.CleanWebpackPlugin = CleanWebpackPlugin;
11-
this.projectDir = path.resolve(process.cwd());
12-
this.tempRootDir = path.resolve(process.cwd(), './test/_temp');
13-
this.outsideProjectDir = path.resolve('/test/dir');
11+
1412
this.filesystemRoot = path.resolve('/');
15-
this.dirOne = path.resolve(this.tempRootDir, '_one');
16-
this.dirTwo = path.resolve(this.tempRootDir, '_two');
13+
14+
// where project root is under the cwd
15+
this.projectDir = path.resolve(process.cwd());
16+
this.projectRoot = path.resolve(process.cwd(), 'test/project_root');
17+
this.dirOne = path.resolve(this.projectRoot, '_one');
18+
this.dirTwo = path.resolve(this.projectRoot, '_two');
19+
20+
// where root is outside the cwd
21+
this.outsideProjectRoot = path.resolve(process.cwd(), 'test/outside_root');
22+
this.dirThree = path.resolve(this.outsideProjectRoot, 'three');
23+
1724
var _this = this;
1825
var cleanWebpackPlugin;
1926

2027
before(function () {
21-
tests.createDir(_this.tempRootDir);
28+
tests.createDir(_this.projectRoot);
29+
tests.createDir(_this.outsideProjectRoot);
2230
});
2331

2432
after(function () {
25-
cleanWebpackPlugin = new CleanWebpackPlugin(_this.tempRootDir, { root: _this.projectDir });
33+
cleanWebpackPlugin = new CleanWebpackPlugin([_this.projectRoot, _this.outsideProjectRoot], { root: _this.projectDir });
2634
cleanWebpackPlugin.apply();
2735
});
2836

test/tests.js

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ var run = function (setup) {
3030
describe('shared', function () {
3131
var CleanWebpackPlugin = _this.CleanWebpackPlugin;
3232
var projectDir = _this.projectDir;
33-
var tempRootDir = _this.tempRootDir;
34-
var outsideProjectDir = _this.outsideProjectDir;
33+
var projectRoot = _this.projectRoot;
34+
var outsideProjectRoot = _this.outsideProjectRoot;
3535
var filesystemRoot = _this.filesystemRoot;
3636
var dirOne = _this.dirOne;
3737
var dirTwo = _this.dirTwo;
38+
var dirThree = _this.dirThree;
3839
var platform = _this.platform || os.platform();
3940
var cleanWebpackPlugin;
4041
var result;
@@ -47,37 +48,36 @@ var run = function (setup) {
4748
});
4849

4950
it('project root must be an absolute path', function () {
50-
cleanWebpackPlugin = new CleanWebpackPlugin([tempRootDir], { root: '../' });
51+
cleanWebpackPlugin = new CleanWebpackPlugin([projectRoot], { root: '../' });
5152
result = cleanWebpackPlugin.apply();
5253

5354
expect(result[0].output).to.equal('project root must be an absolute path');
5455
});
5556

56-
it('project root is outside of project', function () {
57+
it('project root is outside of cwd', function () {
5758
cleanWebpackPlugin =
58-
new CleanWebpackPlugin([tempRootDir], { root: outsideProjectDir });
59+
new CleanWebpackPlugin([dirThree], { root: outsideProjectRoot });
5960
result = cleanWebpackPlugin.apply();
6061

61-
expect(result[0].output).to.equal('project root is outside of project');
62+
expect(result[0].output).to.equal('removed');
6263
});
6364

6465
it('must be inside the project root - bad path', function () {
65-
cleanWebpackPlugin = new CleanWebpackPlugin(['/fake/path'], { root: tempRootDir });
66+
cleanWebpackPlugin = new CleanWebpackPlugin([dirThree], { root: projectRoot });
6667
result = cleanWebpackPlugin.apply();
6768

6869
expect(result[0].output).to.equal('must be inside the project root');
6970
});
7071

71-
it('must be inside the project root - bad root', function () {
72-
var fakeRootDir = tempRootDir.slice(0, -2);
73-
cleanWebpackPlugin = new CleanWebpackPlugin([tempRootDir], { root: fakeRootDir });
72+
it('must be inside the project root - good path', function () {
73+
cleanWebpackPlugin = new CleanWebpackPlugin([dirThree], { root: outsideProjectRoot });
7474
result = cleanWebpackPlugin.apply();
7575

76-
expect(result[0].output).to.equal('must be inside the project root');
76+
expect(result[0].output).to.equal('removed');
7777
});
7878

7979
it('is equal to project root', function () {
80-
cleanWebpackPlugin = new CleanWebpackPlugin([tempRootDir], { root: tempRootDir });
80+
cleanWebpackPlugin = new CleanWebpackPlugin([projectRoot], { root: projectRoot });
8181
result = cleanWebpackPlugin.apply();
8282

8383
expect(result[0].output).to.equal('is equal to project root');
@@ -93,31 +93,31 @@ var run = function (setup) {
9393

9494
it('remove direct', function () {
9595
createDir(dirOne);
96-
cleanWebpackPlugin = new CleanWebpackPlugin(['_one'], { root: tempRootDir });
96+
cleanWebpackPlugin = new CleanWebpackPlugin(['_one'], { root: projectRoot });
9797
result = cleanWebpackPlugin.apply();
9898

9999
expect(result[0].output).to.equal('removed');
100100
});
101101

102102
it('remove direct', function () {
103103
createDir(dirOne);
104-
cleanWebpackPlugin = new CleanWebpackPlugin(['_one'], { root: tempRootDir });
104+
cleanWebpackPlugin = new CleanWebpackPlugin(['_one'], { root: projectRoot });
105105
result = cleanWebpackPlugin.apply();
106106

107107
expect(result[0].output).to.equal('removed');
108108
});
109109

110110
it('remove relative', function () {
111111
createDir(dirOne);
112-
cleanWebpackPlugin = new CleanWebpackPlugin(['./_one'], { root: tempRootDir });
112+
cleanWebpackPlugin = new CleanWebpackPlugin(['./_one'], { root: projectRoot });
113113
result = cleanWebpackPlugin.apply();
114114

115115
expect(result[0].output).to.equal('removed');
116116
});
117117

118118
it('remove absolute', function () {
119119
createDir(dirOne);
120-
cleanWebpackPlugin = new CleanWebpackPlugin([dirOne], { root: tempRootDir });
120+
cleanWebpackPlugin = new CleanWebpackPlugin([dirOne], { root: projectRoot });
121121
result = cleanWebpackPlugin.apply();
122122

123123
expect(result[0].output).to.equal('removed');
@@ -126,7 +126,7 @@ var run = function (setup) {
126126
it('remove multiple', function () {
127127
createDir(dirOne);
128128
createDir(dirTwo);
129-
cleanWebpackPlugin = new CleanWebpackPlugin([dirOne, dirTwo], { root: tempRootDir });
129+
cleanWebpackPlugin = new CleanWebpackPlugin([dirOne, dirTwo], { root: projectRoot });
130130
result = cleanWebpackPlugin.apply();
131131

132132
expect(result[0].output).to.equal('removed');
@@ -135,38 +135,38 @@ var run = function (setup) {
135135

136136
it('remove string', function () {
137137
createDir(dirOne);
138-
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: tempRootDir });
138+
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: projectRoot });
139139
result = cleanWebpackPlugin.apply();
140140

141141
expect(result[0].output).to.equal('removed');
142142
});
143143

144144
it('context backwards compatibility ', function () {
145145
createDir(dirOne);
146-
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, tempRootDir);
146+
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, projectRoot);
147147
result = cleanWebpackPlugin.apply();
148148

149149
expect(result[0].output).to.equal('removed');
150150
});
151151

152152
it('options = { dry: true }', function () {
153153
createDir(dirOne);
154-
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: tempRootDir, dry: true });
154+
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: projectRoot, dry: true });
155155
result = cleanWebpackPlugin.apply();
156156

157157
fs.statSync(dirOne);
158158
expect(result[0].output).to.equal('removed');
159159
});
160160

161161
it('successful delete = { dry: true }', function () {
162-
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: tempRootDir, dry: true });
162+
cleanWebpackPlugin = new CleanWebpackPlugin(dirOne, { root: projectRoot, dry: true });
163163
result = cleanWebpackPlugin.apply();
164164

165165
expect(result[0].output).to.equal('removed');
166166
});
167167

168168
it('filesystem root', function () {
169-
cleanWebpackPlugin = new CleanWebpackPlugin([tempRootDir],
169+
cleanWebpackPlugin = new CleanWebpackPlugin([projectRoot],
170170
{ root: filesystemRoot, dry: true });
171171

172172
result = cleanWebpackPlugin.apply();
@@ -176,20 +176,20 @@ var run = function (setup) {
176176
if (platform === 'win32') {
177177
describe('windows only tests', function () {
178178
it('mixed case drive letters', function () {
179-
var lowerCaseTempRootDir = switchCaseRoot(tempRootDir, 'toLowerCase');
179+
var lowerCaseProjectRoot = switchCaseRoot(projectRoot, 'toLowerCase');
180180
var upperCaseRimrafPath = switchCaseRoot(dirOne, 'toUpperCase');
181181
cleanWebpackPlugin = new CleanWebpackPlugin([upperCaseRimrafPath],
182-
{ root: lowerCaseTempRootDir });
182+
{ root: lowerCaseProjectRoot });
183183

184184
result = cleanWebpackPlugin.apply();
185185
expect(result[0].output).to.equal('removed');
186186
});
187187

188188
it('mixed case file paths', function () {
189-
var upperCaseTempRootDir = switchCaseRoot(tempRootDir, 'toUpperCase');
189+
var upperCaseprojectRoot = switchCaseRoot(projectRoot, 'toUpperCase');
190190
var lowerCaseRimrafPath = switchCaseRoot(dirOne, 'toLowerCase');
191191
cleanWebpackPlugin = new CleanWebpackPlugin([lowerCaseRimrafPath],
192-
{ root: upperCaseTempRootDir });
192+
{ root: upperCaseprojectRoot });
193193

194194
result = cleanWebpackPlugin.apply();
195195
expect(result[0].output).to.equal('removed');

test/windows_spec.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ function convertToWin32Path(dir) {
2424
describe('windows emulation', function () {
2525
this.processCwdWin32 = convertToWin32Path(process.cwd());
2626
this.projectDir = convertToWin32Path(process.cwd());
27-
this.tempRootDir = convertToWin32Path(path.resolve(process.cwd(), './test/_temp'));
28-
this.outsideProjectDir = convertToWin32Path(path.resolve('/test/dir'));
27+
this.projectRoot = convertToWin32Path(path.resolve(process.cwd(), './test/_temp'));
28+
this.outsideProjectRoot = convertToWin32Path(path.resolve('/test/dir'));
2929
this.filesystemRoot = convertToWin32Path(path.resolve(('/')));
30-
this.dirOne = path.win32.resolve(this.tempRootDir + path.win32.sep + '_one');
31-
this.dirTwo = path.win32.resolve(this.tempRootDir + path.win32.sep + '_two');
30+
this.dirOne = path.win32.resolve(this.projectRoot + path.win32.sep + '_one');
31+
this.dirTwo = path.win32.resolve(this.projectRoot + path.win32.sep + '_two');
32+
this.dirThree = path.win32.resolve(this.outsideProjectRoot + path.win32.sep + '_three');
3233
this.CleanWebpackPlugin = CleanWebpackPlugin;
3334
this.platform = 'win32';
3435
var _this = this;

0 commit comments

Comments
 (0)