diff --git a/README.md b/README.md index 9effdf53..410ee9a1 100644 --- a/README.md +++ b/README.md @@ -79,11 +79,10 @@ module.exports = { | [`from`](#from) | `{String}` | `undefined` | Glob or path from where we сopy files. | | [`to`](#to) | `{String}` | `compiler.options.output` | Output path. | | [`context`](#context) | `{String}` | `options.context \|\| compiler.options.context` | A path that determines how to interpret the `from` path. | -| [`globOptions`](#globoptions) | `{Object}` | `undefined` | [Options][glob-options] passed to the glob pattern matching library | +| [`globOptions`](#globoptions) | `{Object}` | `undefined` | [Options][glob-options] passed to the glob pattern matching library, including `ignore` option | | [`toType`](#totype) | `{String}` | `undefined` | Determinate what is `to` option - directory, file or template. | | [`test`](#test) | `{String\|RegExp}` | `undefined` | Pattern for extracting elements to be used in `to` templates. | | [`force`](#force) | `{Boolean}` | `false` | Overwrites files already in `compilation.assets` (usually added by other plugins/loaders). | -| [`ignore`](#ignore) | `{Array}` | `[]` | Globs to ignore files. | | [`flatten`](#flatten) | `{Boolean}` | `false` | Removes all directory references and only copies file names. | | [`transform`](#transform) | `{Function}` | `undefined` | Allows to modify the file contents. | | [`cacheTransform`](#cacheTransform) | `{Boolean\|Object}` | `false` | Enable `transform` caching. You can use `{ cache: { key: 'my-cache-key' } }` to invalidate the cache. | @@ -95,7 +94,8 @@ Type: `String` Default: `undefined` Glob or path from where we сopy files. -Globs accept [micromatch options](https://github.com/micromatch/micromatch). +Globs accept [fast-glob pattern-syntax](https://github.com/mrmlnc/fast-glob#pattern-syntax). +Glob can only be a `string`. > ⚠️ Don't use directly `\\` in `from` (i.e `path\to\file.ext`) option because on UNIX the backslash is a valid character inside a path component, i.e., it's not a separator. > On Windows, the forward slash and the backward slash are both separators. @@ -126,21 +126,62 @@ module.exports = { If you define `from` as file path or folder path on `Windows`, you can use windows path segment (`\\`) -``` -... -from: path.resolve('__dirname', 'file.txt'), -... +```js +module.exports = { + plugins: [ + new CopyPlugin({ + patterns: [ + { + from: path.resolve('__dirname', 'file.txt'), + }, + ], + }), + ], +}; ``` But you should always use forward-slashes in `glob` expressions See [fast-glob manual](https://github.com/mrmlnc/fast-glob#how-to-write-patterns-on-windows). +```js +const FIXTURES_DIR_NORMALIZED = path + .resolve(__dirname, 'fixtures') + .replace(/\\/g, '/'); + +module.exports = { + plugins: [ + new CopyPlugin({ + patterns: [ + { + from: path.posix.join(FIXTURES_DIR_NORMALIZED, 'file.txt'), + }, + ], + }), + ], +}; ``` -... -const FIXTURES_DIR_NORMALIZED = path.resolve(__dirname, 'fixtures').replace(/\\/g, '/'); -from: path.posix.join(FIXTURES_DIR_NORMALIZED, 'file.txt'), -... +##### `For exclude files` + +To exclude files from the selection, you should use [globOptions.ignore option](https://github.com/mrmlnc/fast-glob#ignore) + +**webpack.config.js** + +```js +module.exports = { + plugins: [ + new CopyPlugin({ + patterns: [ + { + from: '**/*', + globOptions: { + ignore: ['**/file.*', '**/ignored-directory/**'], + }, + }, + ], + }), + ], +}; ``` #### `to` @@ -367,51 +408,6 @@ module.exports = { }; ``` -#### `ignore` - -Type: `Array` -Default: `[]` - -Globs to ignore files. - -**webpack.config.js** - -```js -module.exports = { - plugins: [ - new CopyPlugin({ - patterns: [ - { - from: 'src/**/*', - to: 'dest/', - ignore: ['*.js'], - }, - ], - }), - ], -}; -``` - -> ⚠️ Note that only relative path should be provided to ignore option, an example to ignore `src/assets/subfolder/ignorefile.js` : - -**webpack.config.js** - -```js -module.exports = { - plugins: [ - new CopyPlugin({ - patterns: [ - { - from: 'src/assets', - to: 'dest/', - ignore: ['subfolder/ignorefile.js'], - }, - ], - }), - ], -}; -``` - #### `flatten` Type: `Boolean` @@ -566,12 +562,6 @@ module.exports = { }; ``` -### Options - -| Name | Type | Default | Description | -| :-----------------: | :-------: | :-----: | :------------------------------------------- | -| [`ignore`](#ignore) | `{Array}` | `[]` | Array of globs to ignore (applied to `from`) | - #### `ignore` Array of globs to ignore (applied to `from`). diff --git a/package.json b/package.json index e7a78d24..b7c1a462 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "glob-parent": "^5.1.1", "globby": "^11.0.0", "loader-utils": "^2.0.0", - "minimatch": "^3.0.4", "normalize-path": "^3.0.0", "p-limit": "^2.3.0", "schema-utils": "^2.6.6", diff --git a/src/index.js b/src/index.js index 7c6a868b..1dadcf2c 100644 --- a/src/index.js +++ b/src/index.js @@ -33,7 +33,6 @@ class CopyPlugin { compilation, inputFileSystem: compiler.inputFileSystem, output: compiler.options.output.path, - ignore: this.options.ignore || [], concurrency: this.options.concurrency, }; diff --git a/src/options.json b/src/options.json index 9b5f6ea0..8eb8d993 100644 --- a/src/options.json +++ b/src/options.json @@ -29,19 +29,6 @@ "force": { "type": "boolean" }, - "ignore": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object" - } - ] - } - }, "flatten": { "type": "boolean" }, @@ -89,11 +76,7 @@ "options": { "type": "object", "additionalProperties": false, - "properties": { - "ignore": { - "type": "array" - } - } + "properties": {} } } } diff --git a/src/preProcessPattern.js b/src/preProcessPattern.js index 5561eee7..7748bae2 100644 --- a/src/preProcessPattern.js +++ b/src/preProcessPattern.js @@ -29,8 +29,6 @@ export default async function preProcessPattern(globalRef, pattern) { pattern.context = path.normalize(pattern.context); pattern.to = path.normalize(pattern.to); - pattern.ignore = globalRef.ignore.concat(pattern.ignore || []); - logger.debug(`processing from: '${pattern.from}' to: '${pattern.to}'`); switch (true) { diff --git a/src/processPattern.js b/src/processPattern.js index bcab016a..3359bc1b 100644 --- a/src/processPattern.js +++ b/src/processPattern.js @@ -2,9 +2,7 @@ import path from 'path'; import globby from 'globby'; import pLimit from 'p-limit'; -import minimatch from 'minimatch'; -import isObject from './utils/isObject'; import createPatternGlob from './utils/createPatternGlob'; /* eslint-disable no-param-reassign */ @@ -56,47 +54,6 @@ export default async function processPattern(globalRef, pattern) { logger.debug(`found ${from}`); - // Check the ignore list - let il = pattern.ignore.length; - - // eslint-disable-next-line no-plusplus - while (il--) { - const ignoreGlob = pattern.ignore[il]; - - let globParams = { - dot: true, - matchBase: true, - }; - - let glob; - - if (typeof ignoreGlob === 'string') { - glob = ignoreGlob; - } else if (isObject(ignoreGlob)) { - glob = ignoreGlob.glob || ''; - - const ignoreGlobParams = Object.assign({}, ignoreGlob); - delete ignoreGlobParams.glob; - - // Overwrite minimatch defaults - globParams = Object.assign(globParams, ignoreGlobParams); - } else { - glob = ''; - } - - logger.debug(`testing ${glob} against ${file.relativeFrom}`); - - if (minimatch(file.relativeFrom, glob, globParams)) { - logger.log( - `ignoring '${file.relativeFrom}', because it matches the ignore glob '${glob}'` - ); - - return Promise.resolve(); - } - - logger.debug(`${glob} doesn't match ${file.relativeFrom}`); - } - // Change the to path to be relative for webpack if (pattern.toType === 'dir') { file.webpackTo = path.join(pattern.to, file.relativeFrom); diff --git a/src/utils/createPatternGlob.js b/src/utils/createPatternGlob.js index 74035691..b35bb432 100644 --- a/src/utils/createPatternGlob.js +++ b/src/utils/createPatternGlob.js @@ -38,9 +38,11 @@ function createPatternGlob(pattern, globalRef) { '**/*' ); pattern.absoluteFrom = path.join(pattern.absoluteFrom, '**/*'); - pattern.globOptions = { - dot: true, - }; + + if (typeof pattern.globOptions.dot === 'undefined') { + pattern.globOptions.dot = true; + } + break; case 'file': @@ -50,9 +52,11 @@ function createPatternGlob(pattern, globalRef) { pattern.context = path.dirname(pattern.absoluteFrom); pattern.glob = getAbsoluteContext(pattern.absoluteFrom); - pattern.globOptions = { - dot: true, - }; + + if (typeof pattern.globOptions.dot === 'undefined') { + pattern.globOptions.dot = true; + } + break; default: @@ -67,7 +71,6 @@ function createPatternGlob(pattern, globalRef) { compilation.contextDependencies.add(contextDependencies); pattern.fromType = 'glob'; - pattern.globOptions = pattern.globOptions || {}; pattern.glob = path.isAbsolute(pattern.fromOrigin) ? pattern.fromOrigin : path.posix.join( diff --git a/src/utils/isObject.js b/src/utils/isObject.js deleted file mode 100644 index 2f60ad8e..00000000 --- a/src/utils/isObject.js +++ /dev/null @@ -1,2 +0,0 @@ -export default (val) => - Object.prototype.toString.call(val) === '[object Object]'; diff --git a/test/__snapshots__/CopyPlugin.test.js.snap b/test/__snapshots__/CopyPlugin.test.js.snap index 71946ebc..c9a8de60 100644 --- a/test/__snapshots__/CopyPlugin.test.js.snap +++ b/test/__snapshots__/CopyPlugin.test.js.snap @@ -10,14 +10,6 @@ Object { "add ./fixtures/file.txt as fileDependencies", "begin globbing './fixtures/file.txt' with a context of './fixtures'", "found ./fixtures/file.txt", - "testing watch/**/* against file.txt", - "watch/**/* doesn't match file.txt", - "testing directory-ln against file.txt", - "directory-ln doesn't match file.txt", - "testing file-ln.txt against file.txt", - "file-ln.txt doesn't match file.txt", - "testing symlink/**/* against file.txt", - "symlink/**/* doesn't match file.txt", "determined that './fixtures/file.txt' should write to 'file.txt'", "getting stats for './fixtures/file.txt' to write to assets", "reading './fixtures/file.txt' to write to assets", diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index 336e5ad5..4bfa80b9 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -1,21 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`validate options should throw an error on the "options" option with "{"ignore":true}" value 1`] = ` -"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - - options.options.ignore should be an array: - [any, ...]" -`; - exports[`validate options should throw an error on the "options" option with "{"unknown":true}" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.options has an unknown property 'unknown'. These properties are valid: - object { ignore? }" + object {}" `; exports[`validate options should throw an error on the "patterns" option with "" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns should be an array: - [non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" + [non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" `; exports[`validate options should throw an error on the "patterns" option with "[""]" value 1`] = ` @@ -43,42 +37,10 @@ exports[`validate options should throw an error on the "patterns" option with "[ - options.patterns[0].force should be a boolean." `; -exports[`validate options should throw an error on the "patterns" option with "[{"from":"test.txt","to":"dir","context":"context","ignore":["test.txt",true]}]" value 1`] = ` -"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - - options.patterns[0] should be one of these: - non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … } - Details: - * options.patterns[0].ignore[1] should be one of these: - string | object { … } - Details: - * options.patterns[0].ignore[1] should be a string. - * options.patterns[0].ignore[1] should be an object: - object { … }" -`; - -exports[`validate options should throw an error on the "patterns" option with "[{"from":"test.txt","to":"dir","context":"context","ignore":[true]}]" value 1`] = ` -"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - - options.patterns[0] should be one of these: - non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … } - Details: - * options.patterns[0].ignore[0] should be one of these: - string | object { … } - Details: - * options.patterns[0].ignore[0] should be a string. - * options.patterns[0].ignore[0] should be an object: - object { … }" -`; - -exports[`validate options should throw an error on the "patterns" option with "[{"from":"test.txt","to":"dir","context":"context","ignore":true}]" value 1`] = ` -"Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - - options.patterns[0].ignore should be an array: - [string | object { … }, ...]" -`; - exports[`validate options should throw an error on the "patterns" option with "[{"from":"test.txt","to":"dir","context":"context","test":true}]" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns[0] should be one of these: - non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … } + non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … } Details: * options.patterns[0].test should be one of these: string | RegExp @@ -106,7 +68,7 @@ exports[`validate options should throw an error on the "patterns" option with "[ exports[`validate options should throw an error on the "patterns" option with "[{"from":"test.txt","to":"dir","context":"context"}]" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns[0] should be one of these: - non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … } + non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … } Details: * options.patterns[0].cacheTransform should be one of these: boolean | object { … } @@ -145,19 +107,19 @@ exports[`validate options should throw an error on the "patterns" option with "[ exports[`validate options should throw an error on the "patterns" option with "{}" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns should be an array: - [non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" + [non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" `; exports[`validate options should throw an error on the "patterns" option with "true" value 1`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns should be an array: - [non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" + [non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" `; exports[`validate options should throw an error on the "patterns" option with "true" value 2`] = ` "Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema. - options.patterns should be an array: - [non-empty string | object { from, to?, context?, toType?, test?, force?, ignore?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" + [non-empty string | object { from, to?, context?, toType?, test?, force?, flatten?, transform?, cacheTransform?, transformPath?, … }, ...] (should not have fewer than 1 item)" `; exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = ` diff --git a/test/from-option.test.js b/test/from-option.test.js index 5ea0ace0..46740f6b 100644 --- a/test/from-option.test.js +++ b/test/from-option.test.js @@ -67,6 +67,14 @@ describe('from option', () => { it('should move a file (symbolic link)', (done) => { runEmit({ symlink: true, + expectedWarnings: + process.platform === 'win32' + ? [ + new Error( + `unable to locate 'symlink${path.sep}file-ln.txt' at '${FIXTURES_DIR}${path.sep}symlink${path.sep}file-ln.txt'` + ), + ] + : [], expectedAssetKeys: process.platform === 'win32' ? [] : ['file-ln.txt'], patterns: [ { @@ -198,6 +206,14 @@ describe('from option', () => { runEmit({ // Windows doesn't support symbolic link symlink: true, + expectedWarnings: + process.platform === 'win32' + ? [ + new Error( + `unable to locate 'symlink${path.sep}directory-ln' at '${FIXTURES_DIR}${path.sep}symlink${path.sep}directory-ln'` + ), + ] + : [], expectedAssetKeys: process.platform === 'win32' ? [] @@ -455,6 +471,14 @@ describe('from option', () => { runEmit({ // Windows doesn't support symbolic link symlink: true, + expectedWarnings: + process.platform === 'win32' + ? [ + new Error( + `unable to locate 'symlink\\**\\*.txt' at '${FIXTURES_DIR}${path.sep}symlink\\**\\*.txt'` + ), + ] + : [], expectedAssetKeys: process.platform === 'win32' ? [] diff --git a/test/globOptions-option.test.js b/test/globOptions-option.test.js index 2198b262..020163bd 100644 --- a/test/globOptions-option.test.js +++ b/test/globOptions-option.test.js @@ -1,5 +1,9 @@ +import path from 'path'; + import { runEmit } from './helpers/run'; +const FIXTURES_DIR = path.join(__dirname, 'fixtures'); + describe('from option', () => { it('should move files exclude dot files', (done) => { runEmit({ @@ -33,3 +37,223 @@ describe('from option', () => { .catch(done); }); }); + +describe('globOptions ignore option', () => { + it('should ignore files when "from" is a file', (done) => { + runEmit({ + expectedWarnings: [ + new Error( + `unable to locate 'file.txt' at '${FIXTURES_DIR}${path.sep}file.txt'` + ), + ], + patterns: [ + { + from: 'file.txt', + globOptions: { + ignore: ['**/file.*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should files when "from" is a directory', (done) => { + runEmit({ + expectedAssetKeys: [ + '.dottedfile', + 'directoryfile.txt', + 'nested/deep-nested/deepnested.txt', + ], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['**/nestedfile.*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should files in nested directory when "from" is a directory', (done) => { + runEmit({ + expectedAssetKeys: ['.dottedfile', 'directoryfile.txt'], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['**/nested/**'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should files when from is a glob', (done) => { + runEmit({ + expectedAssetKeys: [ + 'directory/directoryfile.txt', + 'directory/nested/deep-nested/deepnested.txt', + ], + patterns: [ + { + from: 'directory/**/*', + globOptions: { + ignore: ['**/nestedfile.*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should files in nested directory when from is a glob', (done) => { + runEmit({ + expectedAssetKeys: ['directory/directoryfile.txt'], + patterns: [ + { + from: 'directory/**/*', + globOptions: { + ignore: ['**/nested/**'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files with a certain extension', (done) => { + runEmit({ + expectedAssetKeys: ['.dottedfile'], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['**/*.txt'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files with multiple ignore patterns', (done) => { + runEmit({ + expectedAssetKeys: ['directory/nested/nestedfile.txt'], + patterns: [ + { + from: 'directory/**/*', + globOptions: { + ignore: ['**/directoryfile.*', '**/deep-nested/**'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files with flatten true', (done) => { + runEmit({ + expectedAssetKeys: ['img/.dottedfile', 'img/nestedfile.txt'], + patterns: [ + { + from: 'directory/', + to: 'img/', + flatten: true, + globOptions: { + ignore: ['**/directoryfile.*', '**/deep-nested/**'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files except those with dots', (done) => { + runEmit({ + expectedAssetKeys: ['.dottedfile'], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['!(**/.*)'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files that start with a dot', (done) => { + runEmit({ + expectedAssetKeys: [ + 'directoryfile.txt', + 'nested/deep-nested/deepnested.txt', + 'nested/nestedfile.txt', + ], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['**/.*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignores all files even if they start with a dot', (done) => { + runEmit({ + expectedWarnings: [ + new Error( + `unable to locate 'directory' at '${FIXTURES_DIR}${path.sep}directory${path.sep}**${path.sep}*'` + ), + ], + patterns: [ + { + from: 'directory', + globOptions: { + ignore: ['**/*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); + + it('should ignore files when "from" is a file (global ignore)', (done) => { + runEmit({ + expectedWarnings: [ + new Error( + `unable to locate 'file.txt' at '${FIXTURES_DIR}${path.sep}file.txt'` + ), + ], + patterns: [ + { + ignore: ['file.*'], + from: 'file.txt', + globOptions: { + ignore: ['**/file.*'], + }, + }, + ], + }) + .then(done) + .catch(done); + }); +}); diff --git a/test/helpers/run.js b/test/helpers/run.js index 66d59870..0cb41ca3 100644 --- a/test/helpers/run.js +++ b/test/helpers/run.js @@ -10,6 +10,17 @@ import removeIllegalCharacterForWindows from './removeIllegalCharacterForWindows import { compile, getCompiler, readAssets } from './'; +/* eslint-disable no-param-reassign */ + +const isWin = process.platform === 'win32'; + +const ignore = [ + '**/symlink/**/*', + '**/file-ln.txt', + '**/directory-ln', + '**/watch/**/*', +]; + function run(opts) { return new Promise((resolve, reject) => { if (Array.isArray(opts.patterns)) { @@ -18,32 +29,21 @@ function run(opts) { // eslint-disable-next-line no-param-reassign pattern.context = removeIllegalCharacterForWindows(pattern.context); } + + if (typeof pattern !== 'string') { + if (!opts.symlink || isWin) { + pattern.globOptions = pattern.globOptions || {}; + pattern.globOptions.ignore = [ + ...ignore, + ...(pattern.globOptions.ignore || []), + ]; + } + } }); } const compiler = opts.compiler || getCompiler(); - const isWin = process.platform === 'win32'; - - if (!opts.symlink || isWin) { - if (!opts.options) { - // eslint-disable-next-line no-param-reassign - opts.options = {}; - } - - if (!opts.options.ignore) { - // eslint-disable-next-line no-param-reassign - opts.options.ignore = []; - } - - opts.options.ignore.push( - 'symlink/**/*', - 'file-ln.txt', - 'directory-ln', - 'watch/**/*' - ); - } - new CopyPlugin({ patterns: opts.patterns, options: opts.options }).apply( compiler ); diff --git a/test/ignore-option.test.js b/test/ignore-option.test.js deleted file mode 100644 index f65d2cb9..00000000 --- a/test/ignore-option.test.js +++ /dev/null @@ -1,186 +0,0 @@ -import { runEmit } from './helpers/run'; - -describe('ignore option', () => { - it('should ignore files when "from" is a file', (done) => { - runEmit({ - expectedAssetKeys: [], - patterns: [ - { - ignore: ['file.*'], - from: 'file.txt', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should files when "from" is a directory', (done) => { - runEmit({ - expectedAssetKeys: [ - '.dottedfile', - 'directoryfile.txt', - 'nested/deep-nested/deepnested.txt', - ], - patterns: [ - { - ignore: ['*/nestedfile.*'], - from: 'directory', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should files in nested directory when "from" is a directory', (done) => { - runEmit({ - expectedAssetKeys: ['.dottedfile', 'directoryfile.txt'], - patterns: [ - { - ignore: ['**/nested/**'], - from: 'directory', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should files when from is a glob', (done) => { - runEmit({ - expectedAssetKeys: [ - 'directory/directoryfile.txt', - 'directory/nested/deep-nested/deepnested.txt', - ], - patterns: [ - { - ignore: ['*nestedfile.*'], - from: 'directory/**/*', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should files in nested directory when from is a glob', (done) => { - runEmit({ - expectedAssetKeys: ['directory/directoryfile.txt'], - patterns: [ - { - ignore: ['*/nested/**'], - from: 'directory/**/*', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignore files with a certain extension', (done) => { - runEmit({ - expectedAssetKeys: ['.dottedfile'], - patterns: [ - { - ignore: ['*.txt'], - from: 'directory', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignore files with multiple ignore patterns', (done) => { - runEmit({ - expectedAssetKeys: ['directory/nested/nestedfile.txt'], - patterns: [ - { - ignore: ['directoryfile.*', '**/deep-nested/**'], - from: 'directory/**/*', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignore files except those with dots', (done) => { - runEmit({ - expectedAssetKeys: ['.dottedfile'], - options: { - ignore: [ - { - dot: false, - glob: '**/*', - }, - ], - }, - patterns: [ - { - from: 'directory', - ignore: [ - { - dot: false, - glob: '**/*', - }, - ], - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignore files that start with a dot', (done) => { - runEmit({ - expectedAssetKeys: [ - 'directoryfile.txt', - 'nested/deep-nested/deepnested.txt', - 'nested/nestedfile.txt', - ], - patterns: [ - { - ignore: ['.dottedfile'], - from: 'directory', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignores all files even if they start with a dot', (done) => { - runEmit({ - expectedAssetKeys: [], - options: { - ignore: ['**/*'], - }, - patterns: [ - { - from: 'directory', - }, - ], - }) - .then(done) - .catch(done); - }); - - it('should ignore files when "from" is a file (global ignore)', (done) => { - runEmit({ - expectedAssetKeys: [], - options: { - ignore: ['file.*'], - }, - patterns: [ - { - ignore: ['file.*'], - from: 'file.txt', - }, - ], - }) - .then(done) - .catch(done); - }); -}); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index cf779cc2..bd87b481 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -55,14 +55,6 @@ describe('validate options', () => { toType: 'file', test: /test/, force: true, - ignore: [ - 'ignore-1', - 'ignore-2', - { - dot: false, - glob: '**/*', - }, - ], flatten: true, transform: () => {}, cacheTransform: true, @@ -166,30 +158,6 @@ describe('validate options', () => { force: 'true', }, ], - [ - { - from: 'test.txt', - to: 'dir', - context: 'context', - ignore: true, - }, - ], - [ - { - from: 'test.txt', - to: 'dir', - context: 'context', - ignore: [true], - }, - ], - [ - { - from: 'test.txt', - to: 'dir', - context: 'context', - ignore: ['test.txt', true], - }, - ], [ { from: 'test.txt', @@ -235,8 +203,8 @@ describe('validate options', () => { ], }, options: { - success: [{ ignore: ['test'] }], - failure: [{ unknown: true }, { ignore: true }], + success: [{}], + failure: [{ unknown: true }], }, unknown: { success: [],