@sap/generator-cap-project
Version:
Creates a new SAP Cloud Application Programming Model project.
76 lines (75 loc) • 3.32 kB
JavaScript
import assert from 'assert';
import fs from 'fs';
import path from 'path';
import { globbySync, isDynamicPattern } from 'globby';
import multimatch from 'multimatch';
import normalize from 'normalize-path';
import { getCommonPath, globify, render } from '../util.js';
function applyProcessingFunc(process, contents, filename, destination) {
const output = process(contents, filename, destination);
return Buffer.isBuffer(output) ? output : Buffer.from(output);
}
export function copy(from, to, options, context, tplSettings) {
to = path.resolve(to);
options = options || {};
let files = [];
if (options.noGlob) {
const fromFiles = Array.isArray(from) ? from : [from];
files = fromFiles.filter((filepath) => this.store.existsInMemory(filepath) || fs.existsSync(filepath));
}
else {
const fromGlob = globify(from);
const globOptions = { ...options.globOptions, nodir: true };
const diskFiles = globbySync(fromGlob, globOptions).map((file) => path.resolve(file));
const storeFiles = [];
this.store.each((file) => {
// The store may have a glob path and when we try to copy it will fail because not real file
if (!diskFiles.includes(file.path) &&
!isDynamicPattern(normalize(file.path)) &&
multimatch([file.path], fromGlob).length !== 0) {
storeFiles.push(file.path);
}
});
files = diskFiles.concat(storeFiles);
}
let generateDestination = () => to;
if (Array.isArray(from) || !this.exists(from) || (isDynamicPattern(normalize(from)) && !options.noGlob)) {
assert(!this.exists(to) || fs.statSync(to).isDirectory(), 'When copying multiple files, provide a directory as destination');
const processDestinationPath = options.processDestinationPath || ((path) => path);
const root = options.fromBasePath || getCommonPath(from);
generateDestination = (filepath) => {
const toFile = path.relative(root, filepath);
return processDestinationPath(path.join(to, toFile));
};
}
// Sanity checks: Makes sure we copy at least one file.
assert(options.ignoreNoMatch || files.length > 0, 'Trying to copy from a source that does not exist: ' + from);
files.forEach((file) => {
let toFile = generateDestination(file);
if (context) {
toFile = render(toFile, context, { ...tplSettings, cache: false });
}
this._copySingle(file, toFile, options);
});
}
export function _copySingle(from, to, options = {}) {
assert(this.exists(from), 'Trying to copy from a source that does not exist: ' + from);
const file = this.store.get(from);
let { contents } = file;
if (!contents) {
throw new Error(`Cannot copy empty file ${from}`);
}
if (options.process) {
contents = applyProcessingFunc(options.process, contents, file.path, to);
}
if (options.append) {
if (!this.store.existsInMemory) {
throw new Error('Current mem-fs is not compatible with append');
}
if (this.store.existsInMemory(to)) {
this.append(to, contents, { create: true, ...options });
return;
}
}
this.write(to, contents, file.stat);
}