Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import {unique} from 'lodash';
- import * as path from 'path';
- /*
- * Grunt copy task that's faster by eliminating unnecessary or redundant fs calls.
- *
- * Things it does *not* do:
- * - set or copy file mode / permissions
- * - "process"ing files
- * - "process"ing files as raw buffers
- * - recursively copying directories
- * - tally created files and directories identically to grunt-contrib-copy
- * - verbose logging identical to grunt-contrib-copy
- * - catch case where src is directory and dest is a pre-existing file (silently succeeds instead)
- */
- grunt.registerMultiTask('copy', function() {
- const {target, data, files} = this;
- const destFiles = [];
- files.forEach(fileMapping => {
- const {src: srcArray, dest} = fileMapping;
- if(srcArray.length !== 1) throw new Error('Only supports one-to-one file mappings.');
- destFiles.push(dest);
- });
- const dirs = unique(destFiles.map(f => path.dirname(f)));
- addAllParentDirs(dirs);
- // Ensure that parent directories are always created before children
- dirs.sort();
- let createdDirectories = 0;
- dirs.forEach(dir => {
- if(mkDir(dir)) createdDirectories++;
- });
- let copiedFiles = 0;
- files.forEach(({src: [src], dest}) => {
- switch(copyFile(src, dest, true)) {
- case 1:
- copiedFiles++;
- break;
- case 2:
- createdDirectories++;
- break;
- }
- });
- console.log(`Created ${ createdDirectories } directories, copied ${ copiedFiles } files`);
- });
- /**
- * Given an array of paths, recursively adds paths to all containing directories.
- * For example, for path '/foo/bar/baz', adds '/foo/bar' and '/foo'.
- */
- function addAllParentDirs(dirs) {
- for(let i = 0; i < dirs.length; i++) {
- const dir = dirs[i];
- const dirOfDir = path.dirname(dir);
- if(dirOfDir !== '.' && dirs.indexOf(dirOfDir) === -1) dirs.push(dirOfDir);
- }
- }
- /**
- * Copies src to dest. If src is a directory, then creates target directory.
- * Returns 0 if nothing was done, 1 if file was created, 2 if directory was created.
- */
- function copyFile(src, dest, createDir = false) {
- let content;
- try {
- content = fs.readFileSync(src);
- } catch(e) {
- // If we tried to read a directory, that's ok. Just skip it.
- if(e.code === 'EISDIR') {
- if(createDir && mkDir(dest)) return 2;
- return 0;
- }
- throw e;
- }
- fs.writeFileSync(dest, content);
- return 1;
- }
- /**
- * Create directory at given path if a file or directory does not already exist at that path.
- * Does not indicate if a file existed at that path even though that might be unexpected.
- * Returns true if directory was created, false otherwise.
- */
- function mkDir(dir) {
- try {
- fs.mkdirSync(dir);
- } catch(e) {
- // If the directory already exists, that's ok.
- if(e.code !== 'EEXIST') throw e;
- return false;
- }
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement