1 |
|
2 |
|
3 | const path = require('path')
|
4 | const fse = require('fs-extra')
|
5 | const junk = require('junk')
|
6 | const mm = require('micromatch')
|
7 | const log = require('./log')
|
8 |
|
9 | /**
|
10 | * Get a list of files which should not be copied.
|
11 | * @param {Array} routes - Array of route configurations.
|
12 | * @param {Array} customFiles - Array of user-defined globs.
|
13 | * @returns {Array} ignoredFiles
|
14 | */
|
15 | const getIgnoredFiles = function(routes, customFiles) {
|
16 |
|
17 | // Always ignore the following files
|
18 | const ignoredFiles = [
|
19 | '**/CVS',
|
20 | '**/.git',
|
21 | '**/.svn',
|
22 | '**/.hg',
|
23 | '**/.lock-wscript',
|
24 | '**/.wafpickle-N'
|
25 | ]
|
26 |
|
27 | // Extract the path out of the routes
|
28 | const ignoredRoutes = routes.map((route) => route.path)
|
29 |
|
30 | // Return all ignored files
|
31 | return [
|
32 | ...ignoredFiles,
|
33 | ...ignoredRoutes,
|
34 | ...customFiles
|
35 | ]
|
36 |
|
37 | }
|
38 |
|
39 | /**
|
40 | * Copy an entire directory with all its files and folders. Specified files will be ignored.
|
41 | * @public
|
42 | * @param {Array} routes - Array of route configurations.
|
43 | * @param {String} srcPath - Path to the source folder.
|
44 | * @param {String} distPath - Path to the destination folder.
|
45 | * @param {Object} opts - Additional optional options.
|
46 | * @param {Function} next - The callback that handles the response. Receives the following properties: err.
|
47 | */
|
48 | module.exports = function(routes, srcPath, distPath, opts, next) {
|
49 |
|
50 | const ignoredFiles = getIgnoredFiles(routes, opts.ignore)
|
51 |
|
52 | const filter = (filePath) => {
|
53 |
|
54 | // The filePath is absolute, but should be relative as micromatch will
|
55 | // match against the relative path of the routes. Matching against
|
56 | // an absolute path requires the use of path.join which causes issues on Windows:
|
57 | // https://github.com/micromatch/micromatch/issues/95
|
58 | filePath = path.relative(srcPath, filePath)
|
59 |
|
60 | const fileName = path.parse(filePath).base
|
61 |
|
62 | const isIgnored = mm.any(filePath, ignoredFiles)
|
63 | const isJunk = junk.is(fileName)
|
64 |
|
65 | // Copy file when it's not ignored or not junk
|
66 | const copy = isIgnored===false && isJunk===false
|
67 |
|
68 | if (opts.verbose===true) {
|
69 |
|
70 | if (copy===false) log(`{cyan:Skipping file: {grey:${ filePath }`)
|
71 | if (copy===true) log(`{cyan:Copying file: {grey:${ filePath }`)
|
72 |
|
73 | }
|
74 |
|
75 | // Return true to include, false to exclude
|
76 | return copy
|
77 |
|
78 | }
|
79 |
|
80 | fse.copy(srcPath, distPath, { filter }, next)
|
81 |
|
82 | } |
\ | No newline at end of file |