From 179e3396d964121dd345001f0e5835ca3c35f977 Mon Sep 17 00:00:00 2001 From: loveky Date: Wed, 23 May 2018 23:12:03 +0800 Subject: [PATCH 1/7] fix #231 allow brackets in path --- src/utils/escape.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/escape.js b/src/utils/escape.js index 447f376b..ee9bbc1c 100644 --- a/src/utils/escape.js +++ b/src/utils/escape.js @@ -8,7 +8,8 @@ export default function escape(context, from) { // Handles special characters in paths const absoluteContext = path.resolve(context) .replace(/\\/, '/') - .replace(/[\*|\?|\!|\(|\)|\[|\]|\{|\}]/g, (substring) => `\\${substring}`); + .replace(/[\*|\?|\!|\(|\)|\{|\}]/g, (substring) => `\\${substring}`) + .replace(/[\[\]]/g, substring => (substring === '[' ? '[[]' : '[]]')); if (!from) { return absoluteContext; From 9b842b00fedf1b8271d314652ce6179286b8360d Mon Sep 17 00:00:00 2001 From: loveky Date: Thu, 24 May 2018 10:43:13 +0800 Subject: [PATCH 2/7] only need take care of [ --- src/utils/escape.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/escape.js b/src/utils/escape.js index ee9bbc1c..1501281b 100644 --- a/src/utils/escape.js +++ b/src/utils/escape.js @@ -9,7 +9,7 @@ export default function escape(context, from) { const absoluteContext = path.resolve(context) .replace(/\\/, '/') .replace(/[\*|\?|\!|\(|\)|\{|\}]/g, (substring) => `\\${substring}`) - .replace(/[\[\]]/g, substring => (substring === '[' ? '[[]' : '[]]')); + .replace(/\[/g, '[[]'); if (!from) { return absoluteContext; From 8c4405ce352a88842054974c3e1647f6f0597b69 Mon Sep 17 00:00:00 2001 From: loveky Date: Sat, 26 May 2018 21:40:07 +0800 Subject: [PATCH 3/7] use character sets to escape special character to avoid issue on Windows --- src/utils/escape.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/escape.js b/src/utils/escape.js index 1501281b..df292266 100644 --- a/src/utils/escape.js +++ b/src/utils/escape.js @@ -8,8 +8,7 @@ export default function escape(context, from) { // Handles special characters in paths const absoluteContext = path.resolve(context) .replace(/\\/, '/') - .replace(/[\*|\?|\!|\(|\)|\{|\}]/g, (substring) => `\\${substring}`) - .replace(/\[/g, '[[]'); + .replace(/[\*|\?|\!|\(|\)|\[|\{|\}]/g, (substring) => `[${substring}]`); if (!from) { return absoluteContext; From a065c7fef2e3e27405008ef0f26fcc7fd597cac6 Mon Sep 17 00:00:00 2001 From: loveky Date: Sun, 27 May 2018 21:04:55 +0800 Subject: [PATCH 4/7] [fix 220] create special directory/file through scripts --- package-lock.json | 2 +- package.json | 9 +++++---- scripts/createSpecialDirectory.js | 19 +++++++++++++++++++ scripts/removeIllegalCharacterForWindows.js | 5 +++++ .../[special?directory]/(special-*file).txt | 1 - .../[special?directory]/directoryfile.txt | 1 - .../[special?directory]/nested/nestedfile.txt | 0 tests/index.js | 17 +++++++++++++---- 8 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 scripts/createSpecialDirectory.js create mode 100644 scripts/removeIllegalCharacterForWindows.js delete mode 100644 tests/helpers/[special?directory]/(special-*file).txt delete mode 100644 tests/helpers/[special?directory]/directoryfile.txt delete mode 100644 tests/helpers/[special?directory]/nested/nestedfile.txt diff --git a/package-lock.json b/package-lock.json index b71bb516..fd0bb23a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3900,7 +3900,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" diff --git a/package.json b/package.json index 4cfc23a5..26b542df 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "pretest": "npm run lint && npm run build && npm run build:tests", "test": "mocha compiled_tests/", "build": "babel src/ --out-dir dist/", - "build:tests": "babel tests/ --out-dir compiled_tests/ && ncp tests/helpers compiled_tests/helpers" + "build:tests": "babel tests/ --out-dir compiled_tests/ && ncp tests/helpers compiled_tests/helpers && node scripts/createSpecialDirectory.js" }, "dependencies": { "globby": "^7.1.1", @@ -34,12 +34,13 @@ "babel-cli": "^6.8.0", "babel-preset-es2015": "^6.6.0", "chai": "^3.4.0", - "eslint": "^2.9.0", "enhanced-resolve": "^3.4.1", + "eslint": "^2.9.0", + "is-gzip": "^2.0.0", + "mkdirp": "^0.5.1", "mocha": "^2.4.5", "ncp": "^2.0.0", - "standard-version": "^4.2.0", - "is-gzip": "^2.0.0" + "standard-version": "^4.2.0" }, "homepage": "https://github.com/webpack-contrib/copy-webpack-plugin", "bugs": "https://github.com/webpack-contrib/copy-webpack-plugin/issues", diff --git a/scripts/createSpecialDirectory.js b/scripts/createSpecialDirectory.js new file mode 100644 index 00000000..bd3762a6 --- /dev/null +++ b/scripts/createSpecialDirectory.js @@ -0,0 +1,19 @@ +const mkdirp = require('mkdirp'); +const path = require('path'); +const fs = require('fs'); +const removeIllegalCharacterForWindows = require('./removeIllegalCharacterForWindows'); + +const baseDir = 'compiled_tests/helpers'; + +const specialFiles = { + '[special?directory]/nested/nestedfile.txt': '', + '[special?directory]/(special-*file).txt': 'special', + '[special?directory]/directoryfile.txt': 'new' +}; + +Object.keys(specialFiles).forEach(function (originFile) { + const file = removeIllegalCharacterForWindows(originFile); + const dir = path.dirname(file); + mkdirp.sync(path.join(baseDir, dir)); + fs.writeFileSync(path.join(baseDir, file), specialFiles[originFile]); +}); \ No newline at end of file diff --git a/scripts/removeIllegalCharacterForWindows.js b/scripts/removeIllegalCharacterForWindows.js new file mode 100644 index 00000000..14da191d --- /dev/null +++ b/scripts/removeIllegalCharacterForWindows.js @@ -0,0 +1,5 @@ +const path = require('path'); + +module.exports = function (string) { + return path.sep === '/' ? string : string.replace(/[*?"<>|]/g, ''); +}; diff --git a/tests/helpers/[special?directory]/(special-*file).txt b/tests/helpers/[special?directory]/(special-*file).txt deleted file mode 100644 index 065d0200..00000000 --- a/tests/helpers/[special?directory]/(special-*file).txt +++ /dev/null @@ -1 +0,0 @@ -special \ No newline at end of file diff --git a/tests/helpers/[special?directory]/directoryfile.txt b/tests/helpers/[special?directory]/directoryfile.txt deleted file mode 100644 index 3e5126c4..00000000 --- a/tests/helpers/[special?directory]/directoryfile.txt +++ /dev/null @@ -1 +0,0 @@ -new \ No newline at end of file diff --git a/tests/helpers/[special?directory]/nested/nestedfile.txt b/tests/helpers/[special?directory]/nested/nestedfile.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/index.js b/tests/index.js index fefd44ec..30a66ce4 100644 --- a/tests/index.js +++ b/tests/index.js @@ -15,6 +15,8 @@ import cacache from 'cacache'; import isGzip from 'is-gzip'; import zlib from 'zlib'; +import removeIllegalCharacterForWindows from '../scripts/removeIllegalCharacterForWindows'; + const BUILD_DIR = path.join(__dirname, 'build'); const HELPER_DIR = path.join(__dirname, 'helpers'); const TEMP_DIR = path.join(__dirname, 'tempdir'); @@ -58,6 +60,13 @@ describe('apply function', () => { // Ideally we pass in patterns and confirm the resulting assets const run = (opts) => { return new Promise((resolve, reject) => { + if (Array.isArray(opts.patterns)) { + opts.patterns.forEach(function (pattern) { + if (pattern.context) { + pattern.context = removeIllegalCharacterForWindows(pattern.context); + } + }); + } const plugin = CopyWebpackPlugin(opts.patterns, opts.options); // Get a mock compiler to pass to plugin.apply @@ -109,7 +118,7 @@ describe('apply function', () => { return run(opts) .then((compilation) => { if (opts.expectedAssetKeys && opts.expectedAssetKeys.length > 0) { - expect(compilation.assets).to.have.all.keys(opts.expectedAssetKeys); + expect(compilation.assets).to.have.all.keys(opts.expectedAssetKeys.map(removeIllegalCharacterForWindows)); } else { expect(compilation.assets).to.deep.equal({}); } @@ -451,7 +460,7 @@ describe('apply function', () => { ], patterns: [{ from: '*/*.*', - test: /([^\/]+)\/([^\/]+)\.\w+$/, + test: `([^\\${path.sep}]+)\\${path.sep}([^\\${path.sep}]+)\\.\\w+$`, to: '[1]-[2].[ext]' }] }) @@ -984,7 +993,7 @@ describe('apply function', () => { 'nested/nestedfile.txt' ], patterns: [{ - from: '[special?directory]' + from: (path.sep === '/' ? '[special?directory]' : '[specialdirectory]') }] }) .then(done) @@ -1390,7 +1399,7 @@ describe('apply function', () => { 'noextension' ], options: { - ignore: ['directory/**/*', '\\[special\\?directory\\]/**/*'] + ignore: ['directory/**/*', (path.sep === '/' ? '\\[special\\?directory\\]/**/*' : '[[]specialdirectory]/**/*')] }, patterns: [{ from: '.' From d9e9d32fd654197a078376d8c37184d668dad3c0 Mon Sep 17 00:00:00 2001 From: loveky Date: Sun, 27 May 2018 21:10:53 +0800 Subject: [PATCH 5/7] rm helpers directory on every test --- package-lock.json | 4 ++-- package.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd0bb23a..198fe596 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4722,8 +4722,8 @@ }, "rimraf": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "resolved": "http://registry.npm.taobao.org/rimraf/download/rimraf-2.6.2.tgz", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "requires": { "glob": "7.1.2" } diff --git a/package.json b/package.json index 26b542df..a6ed4948 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "pretest": "npm run lint && npm run build && npm run build:tests", "test": "mocha compiled_tests/", "build": "babel src/ --out-dir dist/", - "build:tests": "babel tests/ --out-dir compiled_tests/ && ncp tests/helpers compiled_tests/helpers && node scripts/createSpecialDirectory.js" + "build:tests": "babel tests/ --out-dir compiled_tests/ && rimraf compiled_tests/helpers && ncp tests/helpers compiled_tests/helpers && node scripts/createSpecialDirectory.js" }, "dependencies": { "globby": "^7.1.1", @@ -40,6 +40,7 @@ "mkdirp": "^0.5.1", "mocha": "^2.4.5", "ncp": "^2.0.0", + "rimraf": "^2.6.2", "standard-version": "^4.2.0" }, "homepage": "https://github.com/webpack-contrib/copy-webpack-plugin", From 0ffc4f768c795316bb835e5ba779551396a1a8fb Mon Sep 17 00:00:00 2001 From: loveky Date: Mon, 28 May 2018 20:11:16 +0800 Subject: [PATCH 6/7] add new line to the end of scripts --- scripts/createSpecialDirectory.js | 3 ++- scripts/removeIllegalCharacterForWindows.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/createSpecialDirectory.js b/scripts/createSpecialDirectory.js index bd3762a6..86a97a47 100644 --- a/scripts/createSpecialDirectory.js +++ b/scripts/createSpecialDirectory.js @@ -16,4 +16,5 @@ Object.keys(specialFiles).forEach(function (originFile) { const dir = path.dirname(file); mkdirp.sync(path.join(baseDir, dir)); fs.writeFileSync(path.join(baseDir, file), specialFiles[originFile]); -}); \ No newline at end of file +}); + diff --git a/scripts/removeIllegalCharacterForWindows.js b/scripts/removeIllegalCharacterForWindows.js index 14da191d..e5d6d856 100644 --- a/scripts/removeIllegalCharacterForWindows.js +++ b/scripts/removeIllegalCharacterForWindows.js @@ -3,3 +3,4 @@ const path = require('path'); module.exports = function (string) { return path.sep === '/' ? string : string.replace(/[*?"<>|]/g, ''); }; + From e19b4ee9d44c0bafc19ef70130f60bfa70d6f93b Mon Sep 17 00:00:00 2001 From: loveky Date: Fri, 1 Jun 2018 08:46:13 +0800 Subject: [PATCH 7/7] update code, add tests --- scripts/createSpecialDirectory.js | 2 +- scripts/removeIllegalCharacterForWindows.js | 6 ---- src/utils/escape.js | 3 +- tests/helpers/[!]/hello.txt | 0 tests/index.js | 35 +++++++++++++++++-- .../utils/removeIllegalCharacterForWindows.js | 4 +++ 6 files changed, 39 insertions(+), 11 deletions(-) delete mode 100644 scripts/removeIllegalCharacterForWindows.js create mode 100644 tests/helpers/[!]/hello.txt create mode 100644 tests/utils/removeIllegalCharacterForWindows.js diff --git a/scripts/createSpecialDirectory.js b/scripts/createSpecialDirectory.js index 86a97a47..831f336e 100644 --- a/scripts/createSpecialDirectory.js +++ b/scripts/createSpecialDirectory.js @@ -1,7 +1,7 @@ const mkdirp = require('mkdirp'); const path = require('path'); const fs = require('fs'); -const removeIllegalCharacterForWindows = require('./removeIllegalCharacterForWindows'); +const removeIllegalCharacterForWindows = require('../tests/utils/removeIllegalCharacterForWindows'); const baseDir = 'compiled_tests/helpers'; diff --git a/scripts/removeIllegalCharacterForWindows.js b/scripts/removeIllegalCharacterForWindows.js deleted file mode 100644 index e5d6d856..00000000 --- a/scripts/removeIllegalCharacterForWindows.js +++ /dev/null @@ -1,6 +0,0 @@ -const path = require('path'); - -module.exports = function (string) { - return path.sep === '/' ? string : string.replace(/[*?"<>|]/g, ''); -}; - diff --git a/src/utils/escape.js b/src/utils/escape.js index df292266..07ef750f 100644 --- a/src/utils/escape.js +++ b/src/utils/escape.js @@ -7,8 +7,7 @@ export default function escape(context, from) { // Ensure context is escaped before globbing // Handles special characters in paths const absoluteContext = path.resolve(context) - .replace(/\\/, '/') - .replace(/[\*|\?|\!|\(|\)|\[|\{|\}]/g, (substring) => `[${substring}]`); + .replace(/[\*|\?|\!|\(|\)|\[|\]|\{|\}]/g, (substring) => `[${substring}]`); if (!from) { return absoluteContext; diff --git a/tests/helpers/[!]/hello.txt b/tests/helpers/[!]/hello.txt new file mode 100644 index 00000000..e69de29b diff --git a/tests/index.js b/tests/index.js index 30a66ce4..bcb8497e 100644 --- a/tests/index.js +++ b/tests/index.js @@ -15,7 +15,7 @@ import cacache from 'cacache'; import isGzip from 'is-gzip'; import zlib from 'zlib'; -import removeIllegalCharacterForWindows from '../scripts/removeIllegalCharacterForWindows'; +import removeIllegalCharacterForWindows from './utils/removeIllegalCharacterForWindows'; const BUILD_DIR = path.join(__dirname, 'build'); const HELPER_DIR = path.join(__dirname, 'helpers'); @@ -277,6 +277,7 @@ describe('apply function', () => { it('can use a glob to move multiple files to the root directory', (done) => { runEmit({ expectedAssetKeys: [ + '[!]/hello.txt', 'binextension.bin', 'file.txt', 'file.txt.gz', @@ -298,6 +299,7 @@ describe('apply function', () => { it('can use a glob to move multiple files to a non-root directory', (done) => { runEmit({ expectedAssetKeys: [ + 'nested/[!]/hello.txt', 'nested/binextension.bin', 'nested/file.txt', 'nested/file.txt.gz', @@ -414,6 +416,7 @@ describe('apply function', () => { it('can use a glob with a full path to move multiple files to the root directory', (done) => { runEmit({ expectedAssetKeys: [ + '[!]/hello.txt', 'file.txt', 'directory/directoryfile.txt', 'directory/nested/nestedfile.txt', @@ -432,6 +435,7 @@ describe('apply function', () => { it('can use a glob to move multiple files to a non-root directory with name, hash and ext', (done) => { runEmit({ expectedAssetKeys: [ + 'nested/[!]/hello-d41d8c.txt', 'nested/binextension-d41d8c.bin', 'nested/file-22af64.txt', 'nested/file.txt-5b311c.gz', @@ -454,6 +458,7 @@ describe('apply function', () => { it('can flatten or normalize glob matches', (done) => { runEmit({ expectedAssetKeys: [ + '[!]-hello.txt', '[special?directory]-(special-*file).txt', '[special?directory]-directoryfile.txt', 'directory-directoryfile.txt' @@ -896,6 +901,7 @@ describe('apply function', () => { it('ignores files in pattern', (done) => { runEmit({ expectedAssetKeys: [ + '[!]/hello.txt', 'binextension.bin', 'directory/directoryfile.txt', 'directory/nested/nestedfile.txt', @@ -1333,6 +1339,7 @@ describe('apply function', () => { it('ignores files that start with a dot', (done) => { runEmit({ expectedAssetKeys: [ + '[!]/hello.txt', 'binextension.bin', 'file.txt', 'file.txt.gz', @@ -1393,13 +1400,14 @@ describe('apply function', () => { it('ignores nested directory', (done) => { runEmit({ expectedAssetKeys: [ + '[!]/hello.txt', 'binextension.bin', 'file.txt', 'file.txt.gz', 'noextension' ], options: { - ignore: ['directory/**/*', (path.sep === '/' ? '\\[special\\?directory\\]/**/*' : '[[]specialdirectory]/**/*')] + ignore: ['directory/**/*', `[[]special${process.platform === 'win32' ? '' : '[?]'}directory]/**/*`] }, patterns: [{ from: '.' @@ -1410,6 +1418,29 @@ describe('apply function', () => { .catch(done); }); + if (path.sep === '/') { + it('ignores nested directory(can use "\\" to escape if path.sep is "/")', (done) => { + runEmit({ + expectedAssetKeys: [ + '[!]/hello.txt', + 'binextension.bin', + 'file.txt', + 'file.txt.gz', + 'noextension' + ], + options: { + ignore: ['directory/**/*', '\\[special\\?directory\\]/**/*'] + }, + patterns: [{ + from: '.' + }] + + }) + .then(done) + .catch(done); + }); + } + it('ignores nested directory (glob)', (done) => { runEmit({ expectedAssetKeys: [ diff --git a/tests/utils/removeIllegalCharacterForWindows.js b/tests/utils/removeIllegalCharacterForWindows.js new file mode 100644 index 00000000..0754abbf --- /dev/null +++ b/tests/utils/removeIllegalCharacterForWindows.js @@ -0,0 +1,4 @@ +module.exports = function (string) { + return process.platform !== 'win32' ? string : string.replace(/[*?"<>|]/g, ''); +}; +