UNPKG

2.72 kBJavaScriptView Raw
1'use strict';
2
3var assert = require('assert');
4var fs = require('fs');
5var path = require('path');
6var globby = require('globby');
7var multimatch = require('multimatch');
8var ejs = require('ejs');
9var util = require('../util');
10var normalize = require('normalize-path');
11
12function applyProcessingFunc(process, contents, filename) {
13 var output = process(contents, filename);
14 return output instanceof Buffer ? output : Buffer.from(output);
15}
16
17exports.copy = function (from, to, options, context, tplSettings) {
18 to = path.resolve(to);
19 options = options || {};
20 var fromGlob = util.globify(from);
21
22 var globOptions = {...options.globOptions, nodir: true};
23 var diskFiles = globby.sync(fromGlob, globOptions).map(file => path.resolve(file));
24 var storeFiles = [];
25 this.store.each(file => {
26 // The store may have a glob path and when we try to copy it will fail because not real file
27 if (!globby.hasMagic(normalize(file.path)) && multimatch([file.path], fromGlob).length !== 0 && !diskFiles.includes(file.path)) {
28 storeFiles.push(file.path);
29 }
30 });
31 var files = diskFiles.concat(storeFiles);
32
33 var generateDestination = () => to;
34 if (Array.isArray(from) || !this.exists(from) || globby.hasMagic(normalize(from))) {
35 assert(
36 !this.exists(to) || fs.statSync(to).isDirectory(),
37 'When copying multiple files, provide a directory as destination'
38 );
39
40 const processDestinationPath = options.processDestinationPath || (path => path);
41 var root = util.getCommonPath(from);
42 generateDestination = filepath => {
43 var toFile = path.relative(root, filepath);
44 return processDestinationPath(path.join(to, toFile));
45 };
46 }
47
48 // Sanity checks: Makes sure we copy at least one file.
49 assert(options.ignoreNoMatch || files.length > 0, 'Trying to copy from a source that does not exist: ' + from);
50
51 files.forEach(file => {
52 var toFile = generateDestination(file);
53 if (context) {
54 toFile = ejs.render(toFile, context, tplSettings);
55 }
56
57 this._copySingle(file, toFile, options, context, tplSettings);
58 });
59};
60
61exports._copySingle = function (from, to, options = {}) {
62 assert(this.exists(from), 'Trying to copy from a source that does not exist: ' + from);
63
64 var file = this.store.get(from);
65
66 var contents = file.contents;
67 if (options.process) {
68 contents = applyProcessingFunc(options.process, file.contents, file.path);
69 }
70
71 if (options.append) {
72 if (!this.store.existsInMemory) {
73 throw new Error('Current mem-fs is not compatible with append');
74 }
75
76 if (this.store.existsInMemory(to)) {
77 this.append(to, contents, {create: true, ...options});
78 return;
79 }
80 }
81
82 this.write(to, contents, file.stat);
83};