import chalk from 'chalk'; import fs from 'fs-extra'; import path from 'path'; import { toRepoPath, findFiles } from '../utils'; import { Task } from './Task'; export type CopyFilesSettings = { from?: string; subDirectory?: string; filePattern: string | string[]; to: string; }; /** * A task which will copy files from `workingDirectory()/subDirectory/filePatterns` to the provided path. * * It's searching for file names which match `filePatterns` and then it copies them into `to/`. * So the `subDirectory` part won't be copied. * * If for this file structure: * * ``` * android/ * src/ * main.java * lib/ * lib.java * ``` * * you runs CopyFiles with: * ``` * { * from: 'android', * subDirectory: 'src|lib', * to: 'copied', * filePatterns: '*' * } * ``` * you gets: * ``` * android/ * src/ * main.java * lib/ * lib.java * lib/ * main.java * lib.java * ``` */ export class CopyFiles extends Task { private from?: string; private subDirectory?: string; private readonly filePattern: string[]; private readonly to: string; /** * Using `from` key, you can override the work directory. * @param settings */ constructor({ from, subDirectory, filePattern, to }: CopyFilesSettings) { super(); this.from = from; this.subDirectory = subDirectory; this.to = toRepoPath(to); if (typeof filePattern === 'string') { this.filePattern = [filePattern]; } else { this.filePattern = filePattern; } } protected overrideWorkingDirectory(): string { return this.from || ''; } async execute() { const workDirectory = this.getWorkingDirectory(); for (const pattern of this.filePattern) { const subPath = this.subDirectory ? path.join(workDirectory, this.subDirectory) : workDirectory; this.logSubStep( `📝 copy ${chalk.green(this.overrideWorkingDirectory())}/${chalk.green( this.subDirectory ? this.subDirectory + '/' : '' )}${chalk.yellow(pattern)} into ${chalk.magenta(this.to)}` ); const files = await findFiles(subPath, pattern); await Promise.all( files.map(async (file) => { const relativeFilePath = path.relative(subPath, file); const destinationFullPath = path.join(this.to, relativeFilePath); await fs.mkdirs(path.dirname(destinationFullPath)); return await fs.copy(file, destinationFullPath); }) ); } } }