UNPKG

copy-folder-util

Version:

Recursively copy files from one folder to another folder (CLI tool designed for use in npm package.json scripts)

85 lines (83 loc) 3.97 kB
//! copy-folder-util v1.1.5 ~~ https://github.com/center-key/copy-folder-util ~~ MIT License import chalk from 'chalk'; import fs from 'fs'; import log from 'fancy-log'; import path from 'path'; import slash from 'slash'; const extraneousFiles = ['.DS_Store', 'Thumbs.db', 'desktop.ini']; const extraneousFolders = ['.git', 'node_modules']; const copyFolder = { cp(sourceFolder, targetFolder, options) { const defaults = { basename: null, cd: null, fileExtensions: [], }; const settings = { ...defaults, ...options }; const startTime = Date.now(); const normalize = (folder) => !folder ? '' : slash(path.normalize(folder)).replace(/\/$/, ''); const startFolder = settings.cd ? normalize(settings.cd) + '/' : ''; const source = normalize(startFolder + sourceFolder); const target = normalize(startFolder + targetFolder); if (targetFolder) fs.mkdirSync(target, { recursive: true }); const errorMessage = !sourceFolder ? 'Must specify the source folder path.' : !targetFolder ? 'Must specify the target folder path.' : !fs.existsSync(source) ? 'Source folder does not exist: ' + source : !fs.existsSync(target) ? 'Target folder cannot be created: ' + target : !fs.statSync(source).isDirectory() ? 'Source is not a folder: ' + source : !fs.statSync(target).isDirectory() ? 'Target is not a folder: ' + target : null; if (errorMessage) throw new Error('[copy-folder-util] ' + errorMessage); const filterOff = { base: !settings.basename, ext: !Array.isArray(settings.fileExtensions) || !settings.fileExtensions.length, }; const files = []; const posixPath = (nativePath) => slash(nativePath.replace(/.*:/, '')); const relativePath = (fullPath, start) => fullPath.substring(fullPath.indexOf(start) + start.length + 1); const filter = (origin, dest) => { const isFile = fs.statSync(origin).isFile(); const name = path.basename(origin); const ext = path.extname(origin); const keepFolder = !isFile && !extraneousFolders.includes(name); const keepFile = isFile && (filterOff.base || name.replace(/[.].*/, '') === settings.basename) && (filterOff.ext || settings.fileExtensions.includes(ext)) && !extraneousFiles.includes(name); if (keepFile) files.push({ origin: relativePath(posixPath(origin), source), dest: relativePath(posixPath(dest), target), }); return keepFolder || keepFile; }; fs.cpSync(source, target, { filter: filter, recursive: true }); return { source: source, target: target, count: files.length, duration: Date.now() - startTime, files: files, }; }, reporter(results, options) { const defaults = { summaryOnly: false, }; const settings = { ...defaults, ...options }; const name = chalk.gray('copy-folder'); const source = chalk.blue.bold(results.source); const target = chalk.magenta(results.target); const arrow = { big: chalk.gray.bold(' ⟹ '), little: chalk.gray.bold('→') }; const infoColor = results.count ? chalk.white : chalk.red.bold; const info = infoColor(`(files: ${results.count}, ${results.duration}ms)`); log(name, source, arrow.big, target, info); const logFile = (file) => log(name, chalk.white(file.origin), arrow.little, chalk.green(file.dest)); if (!settings.summaryOnly) results.files.forEach(logFile); return results; }, }; export { copyFolder };