copy-webpack-plugin
Advanced tools
Comparing version 0.3.3 to 1.0.0
105
index.js
var _ = require('lodash'); | ||
var Promise = require('bluebird'); | ||
var path = require('path'); | ||
var fs = Promise.promisifyAll(require('fs')); | ||
var globAsync = Promise.promisify(require('glob')); | ||
var fs = Promise.promisifyAll(require('fs-extra')); | ||
var dir = Promise.promisifyAll(require('node-dir')); | ||
var minimatch = require('minimatch'); | ||
function toLooksLikeDirectory(pattern) { | ||
var filename = pattern.to; | ||
if ((path.extname(filename) === '' || // doesn't have an extension | ||
_.last(filename) === path.sep || // ends in a path separator | ||
_.last(filename) === '/' || // ends in a slash (kept for compatibility) | ||
pattern.toType === 'dir') && // is explicitly a dir | ||
pattern.toType !== 'file') { // is not explicitly a file | ||
return true; | ||
} | ||
} | ||
@@ -15,7 +26,7 @@ function apply(patterns, opts, compiler) { | ||
var lastGlobalUpdate = 0; | ||
if (!opts) { | ||
opts = {}; | ||
} | ||
var ignoreList = opts.ignore; | ||
@@ -28,8 +39,23 @@ | ||
var relDest = pattern.to || ''; | ||
// Determine if this is an absolute to | ||
var absDest; | ||
if (path.isAbsolute(relDest)) { | ||
absDest = relDest; | ||
} | ||
var forceWrite = !!pattern.force; | ||
return fs.statAsync(absSrc) | ||
.catch(function(err) { | ||
return null; | ||
}) | ||
.then(function(stat) { | ||
if (stat.isDirectory()) { | ||
if (stat && stat.isDirectory()) { | ||
contextDependencies.push(absSrc); | ||
if (absDest && toLooksLikeDirectory(pattern)) { | ||
return fs.copyAsync(absSrc, absDest); | ||
} | ||
return writeDirectoryToAssets({ | ||
@@ -44,23 +70,46 @@ compilation: compilation, | ||
} else { | ||
// Skip if it matches any of our ignore list | ||
if (shouldIgnore(relSrc, ignoreList)) { | ||
return; | ||
} | ||
fileDependencies.push(absSrc); | ||
if ((path.extname(relDest) === '' || // doesn't have an extension | ||
_.last(relDest) === path.sep || // ends in a path separator | ||
_.last(relDest) === '/' || // ends in a slash (kept for compatibility) | ||
pattern.toType === 'dir') && // is explicitly a dir | ||
pattern.toType !== 'file') { // is not explicitly a file | ||
relDest = path.join(relDest, path.basename(relSrc)); | ||
} else { | ||
relDest = relDest || path.basename(relSrc); | ||
} | ||
return writeFileToAssets({ | ||
compilation: compilation, | ||
absFileSrc: absSrc, | ||
relFileDest: relDest, | ||
forceWrite: forceWrite, | ||
lastGlobalUpdate: lastGlobalUpdate | ||
return globAsync(relSrc, {cwd: baseDir}) | ||
.each(function(relFileSrc) { | ||
// Skip if it matches any of our ignore list | ||
if (shouldIgnore(relFileSrc, ignoreList)) { | ||
return; | ||
} | ||
var absFileSrc = path.resolve(baseDir, relFileSrc); | ||
var relFileDest = pattern.to || ''; | ||
var relFileDirname = path.dirname(relFileSrc); | ||
fileDependencies.push(absFileSrc); | ||
// If it's an absolute destination, write directly | ||
if (absDest) { | ||
var dest = absDest; | ||
if (toLooksLikeDirectory(pattern)) { | ||
dest = path.join(absDest, path.basename(absFileSrc)); | ||
} | ||
return fs.copyAsync(absFileSrc, dest); | ||
} | ||
if (!stat && relFileDirname !== baseDir) { | ||
if (path.isAbsolute(relFileSrc)) { | ||
// If the file is in a subdirectory (from globbing), we should correctly map the dest folder | ||
relFileDest = path.join(path.relative(baseDir, relFileDirname), path.basename(relFileSrc)); | ||
} else { | ||
relFileDest = relFileSrc; | ||
} | ||
} else if (toLooksLikeDirectory(pattern)) { | ||
relFileDest = path.join(relFileDest, path.basename(relFileSrc)); | ||
} else { | ||
relFileDest = relFileDest || path.basename(relFileSrc); | ||
} | ||
return writeFileToAssets({ | ||
compilation: compilation, | ||
absFileSrc: absFileSrc, | ||
relFileDest: relFileDest, | ||
forceWrite: forceWrite, | ||
lastGlobalUpdate: lastGlobalUpdate | ||
}); | ||
}); | ||
@@ -108,2 +157,3 @@ } | ||
} | ||
return fs.statAsync(absFileSrc) | ||
@@ -136,3 +186,3 @@ .then(function(stat) { | ||
var relFileDest = path.join(relDirDest, relFileSrc); | ||
// Skip if it matches any of our ignore list | ||
@@ -161,3 +211,4 @@ if (shouldIgnore(relFileSrc, ignoreList)) { | ||
return minimatch(pathName, glob, { | ||
matchBase: true | ||
matchBase: true, | ||
dot: true | ||
}); | ||
@@ -164,0 +215,0 @@ }); |
{ | ||
"name": "copy-webpack-plugin", | ||
"version": "0.3.3", | ||
"version": "1.0.0", | ||
"description": "Copy files and directories in webpack", | ||
@@ -22,2 +22,4 @@ "main": "index.js", | ||
"bluebird": "^2.10.2", | ||
"fs-extra": "^0.26.4", | ||
"glob": "^6.0.4", | ||
"lodash": "^3.10.1", | ||
@@ -24,0 +26,0 @@ "minimatch": "^3.0.0", |
@@ -25,6 +25,6 @@ ## Copy Webpack Plugin | ||
- can be a file or directory | ||
- can be a glob | ||
* `to` | ||
- is optional | ||
- is relative to the build root (webpack defaults to `dist`) | ||
- defaults to `'/'` | ||
- if not absolute, it's relative to the build root | ||
- must be a directory if `from` is a directory | ||
@@ -58,16 +58,19 @@ * `toType` | ||
// {output}/file.txt | ||
{ from: 'path/to/file.txt' }, | ||
{ from: 'from/file.txt' }, | ||
// {output}/path/to/build/file.txt | ||
{ from: 'path/to/file.txt', to: 'path/to/build/file.txt' }, | ||
// {output}/to/file.txt | ||
{ from: 'from/file.txt', to: 'to/file.txt' }, | ||
// {output}/path/to/build/directory/file.txt | ||
{ from: 'path/to/file.txt', to: 'path/to/build/directory' }, | ||
// {output}/to/directory/file.txt | ||
{ from: 'from/file.txt', to: 'to/directory' }, | ||
// Copy directory contents to {output}/ | ||
{ from: 'path/to/directory' }, | ||
{ from: 'from/directory' }, | ||
// Copy directory contents to {output}/path/to/build/directory/ | ||
{ from: 'path/to/directory', to: 'path/to/build/directory' }, | ||
// Copy directory contents to {output}/to/directory/ | ||
{ from: 'from/directory', to: 'to/directory' }, | ||
// Copy glob results to /absolute/path/ | ||
{ from: 'from/directory/**/*', to: '/absolute/path' }, | ||
// {output}/file/without/extension | ||
@@ -74,0 +77,0 @@ { |
@@ -0,1 +1,2 @@ | ||
/* globals describe, it, afterEach, __dirname */ | ||
var expect = require('chai').expect; | ||
@@ -6,6 +7,7 @@ var CopyWebpackPlugin = require('../index'); | ||
var Promise = require('bluebird'); | ||
var fs = Promise.promisifyAll(require('fs')); | ||
var fs = Promise.promisifyAll(require('fs-extra')); | ||
var HELPER_DIR = path.join(__dirname, 'helpers'); | ||
var TEMP_DIR = path.join(__dirname, 'tempdir'); | ||
@@ -30,2 +32,7 @@ function MockCompiler() { | ||
describe('apply function', function() { | ||
afterEach(function() { | ||
// Make sure the temp directory is removed | ||
fs.removeSync(TEMP_DIR); | ||
}); | ||
@@ -79,2 +86,12 @@ // Ideally we pass in patterns and confirm the resulting assets | ||
} | ||
if (opts.expectedFilesWritten) { | ||
_.each(opts.expectedFilesWritten, function(file) { | ||
var stat = fs.statSync(file); | ||
expect(stat).to.exist; | ||
if (stat) { | ||
fs.unlinkSync(file); | ||
} | ||
}); | ||
} | ||
}); | ||
@@ -137,2 +154,4 @@ } | ||
// Use then and catch explicitly, so errors | ||
// aren't seen as unhandled exceptions | ||
describe('error handling', function() { | ||
@@ -182,3 +201,39 @@ it('doesn\'t throw an error if no patterns are passed', function(done) { | ||
}); | ||
it('can use a glob to move a file to the root directory', function(done) { | ||
runEmit({ | ||
patterns: [{ from: '*.txt' }], | ||
expectedAssetKeys: ['file.txt'] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('can use a glob to move multiple files to the root directory', function(done) { | ||
runEmit({ | ||
patterns: [{ from: '**/*.txt' }], | ||
expectedAssetKeys: ['file.txt', 'directory/directoryfile.txt', 'directory/nested/nestedfile.txt'] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('can use a glob with a full path to move a file to the root directory', function(done) { | ||
runEmit({ | ||
patterns: [{ from: path.join(HELPER_DIR, '*.txt') }], | ||
expectedAssetKeys: ['file.txt'] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('can use a glob with a full path to move multiple files to the root directory', function(done) { | ||
runEmit({ | ||
patterns: [{ from: path.join(HELPER_DIR, '**/*.txt') }], | ||
expectedAssetKeys: ['file.txt', 'directory/directoryfile.txt', 'directory/nested/nestedfile.txt'] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('can move a file to a new directory without a forward slash', function(done) { | ||
@@ -192,2 +247,29 @@ runEmit({ | ||
}); | ||
it('can move a file to a new directory using an absolute to', function(done) { | ||
runEmit({ | ||
patterns: [{ | ||
from: 'file.txt', | ||
to: TEMP_DIR | ||
}], | ||
expectedAssetKeys: [], | ||
expectedFilesWritten: [path.join(TEMP_DIR, 'file.txt')] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('can move a file to a new file using an absolute to', function(done) { | ||
var absolutePath = path.resolve(TEMP_DIR, 'newfile.txt'); | ||
runEmit({ | ||
patterns: [{ | ||
from: 'file.txt', | ||
to: absolutePath | ||
}], | ||
expectedAssetKeys: [], | ||
expectedFilesWritten: [absolutePath] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
@@ -352,2 +434,15 @@ it('can move a file to a new directory with a forward slash', function(done) { | ||
}); | ||
it('can move a directory\'s contents to a new directory using an absolute to', function(done) { | ||
runEmit({ | ||
patterns: [{ from: 'directory', to: TEMP_DIR }], | ||
expectedAssetKeys: [], | ||
expectedFilesWritten: [ | ||
path.join(TEMP_DIR, 'directoryfile.txt'), | ||
path.join(TEMP_DIR, 'nested/nestedfile.txt') | ||
] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
@@ -428,3 +523,3 @@ it('can move a nested directory\'s contents to the root directory', function(done) { | ||
}); | ||
describe('options', function() { | ||
@@ -448,2 +543,3 @@ describe('ignore', function() { | ||
}); | ||
it('ignores files when from is a directory', function(done) { | ||
@@ -462,2 +558,3 @@ runEmit({ | ||
}); | ||
it('ignores files with a certain extension', function(done) { | ||
@@ -476,4 +573,36 @@ runEmit({ | ||
}); | ||
it('ignores files that start with a dot', function(done) { | ||
runEmit({ | ||
patterns: [{ from: '.' }], | ||
options: { | ||
ignore: [ | ||
'.dotted_file' | ||
] | ||
}, | ||
expectedAssetKeys: [ | ||
'file.txt', | ||
'directory/directoryfile.txt', | ||
'directory/nested/nestedfile.txt' | ||
] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
it('ignores all files', function(done) { | ||
runEmit({ | ||
patterns: [{ from: '.' }], | ||
options: { | ||
ignore: [ | ||
'**/*' | ||
] | ||
}, | ||
expectedAssetKeys: [] | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
28766
11
735
0
105
6
+ Addedfs-extra@^0.26.4
+ Addedglob@^6.0.4
+ Addedfs-extra@0.26.7(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@6.0.47.2.3(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedjsonfile@2.4.0(transitive)
+ Addedklaw@1.3.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedwrappy@1.0.2(transitive)