UNPKG

turbo-gulp

Version:

Gulp tasks to boost high-quality projects.

190 lines (189 loc) 7.42 kB
import { existsSync } from "fs"; import { Minimatch } from "minimatch"; import { posix as posixPath } from "path"; import { Readable as ReadableStream } from "stream"; import * as typescript from "typescript"; import Vinyl from "vinyl"; import { DEV_TSC_OPTIONS, mergeTscOptionsJson } from "../options/tsc"; import { OutModules } from "../options/typescript"; import { resolveProject } from "../project"; import { getBuildTypescriptTask, getBuildTypescriptWatchTask } from "../target-tasks/build-typescript"; import { getTsconfigJsonTask } from "../target-tasks/tsconfig-json"; import { generateTask as generateCleanTask } from "../task-generators/clean"; import * as copy from "../task-generators/copy"; import * as matcher from "../utils/matcher"; /** * Generate a copy task (and the corresponding watch task) for the copy operations described by `copyOptions` * * @param gulp Gulp instance to use for utility methods. * @param srcDir Base directory for source resolution. * @param targetDir Base directory for target (build) resolution. * @param copyOptions Simple copy operations to apply for this copy task. * @return A tuple with the task function and corresponding watch task function. */ export function getCopy(gulp, srcDir, targetDir, copyOptions) { const tasks = []; const watchTasks = []; for (const options of copyOptions) { const from = options.src === undefined ? srcDir : posixPath.join(srcDir, options.src); const files = options.files === undefined ? ["**/*"] : options.files; const to = options.dest === undefined ? targetDir : posixPath.join(targetDir, options.dest); const completeOptions = { from, files, to }; tasks.push(copy.generateTask(gulp, completeOptions)); watchTasks.push(() => copy.watch(gulp, completeOptions)); } const task = gulp.parallel(tasks); const watch = gulp.parallel(watchTasks); return [task, watch]; } /** * Resolve absolute paths and dependencies for the provided target. * * @param target Non-resolved target. * @return Resolved target. */ export function resolveTargetBase(target) { const project = resolveProject(target.project); const srcDir = typeof target.srcDir === "string" ? posixPath.join(project.absRoot, target.srcDir) : project.srcDir; const buildDir = typeof target.buildDir === "string" ? posixPath.join(project.absRoot, target.buildDir) : posixPath.join(project.absBuildDir, target.name); const scripts = []; if (target.scripts === undefined) { scripts.push(posixPath.join(srcDir, "**", "*.ts")); } else { for (const script of target.scripts) { scripts.push(matcher.asString(matcher.join(srcDir, new Minimatch(script)))); } } const defaultCustomTypingsDir = posixPath.join(srcDir, "custom-typings"); const customTypingsDir = target.customTypingsDir !== undefined ? (target.customTypingsDir !== null ? posixPath.join(project.absRoot, target.customTypingsDir) : null) : (existsSync(defaultCustomTypingsDir) ? defaultCustomTypingsDir : null); const tscOptions = mergeTscOptionsJson(DEV_TSC_OPTIONS, target.tscOptions); const outModules = target.outModules !== undefined ? target.outModules : OutModules.Js; const tsconfigJson = target.tsconfigJson !== undefined ? (target.tsconfigJson !== null ? posixPath.join(project.absRoot, target.tsconfigJson) : null) : posixPath.join(srcDir, "tsconfig.json"); const dependencies = { typescript }; if (target.dependencies !== undefined) { Object.assign(dependencies, target.dependencies); } return { project, name: target.name, srcDir, buildDir, scripts, customTypingsDir, tscOptions, outModules, tsconfigJson, dependencies, copy: target.copy, clean: target.clean, }; } /** * Adds a display name to the supplied task function and returns the task function. * * @param name The display name to set. * @param task The task function to name. * @return The input task, with its `displayName` property set to `name`. */ export function nameTask(name, task) { task.displayName = name; return task; } /** * Name a task function and register it to the provided gulp instance. */ export function addTask(gulp, displayName, task) { gulp.task(nameTask(displayName, task)); return task; } /** * Creates a Vinyl stream source from a Buffer. */ export function gulpBufferSrc(filename, data) { const src = new ReadableStream({ objectMode: true }); src._read = function () { this.push(new Vinyl({ path: filename, contents: data, })); this.push(null); }; return src; } /** * Generates gulp tasks available for every target (base tasks). * * @param gulp Gulp instance used to generate tasks manipulating files. * @param targetOptions Target configuration. */ export function generateBaseTasks(gulp, targetOptions) { const target = resolveTargetBase(targetOptions); const result = {}; // Typescript options const tsOptions = { tscOptions: target.tscOptions, tsconfigJson: target.tsconfigJson, customTypingsDir: target.customTypingsDir, packageJson: target.project.absPackageJson, buildDir: target.buildDir, srcDir: target.srcDir, scripts: target.scripts, outModules: target.outModules, }; const watchTasks = []; // build:scripts result.buildScripts = nameTask(`${target.name}:build:scripts`, getBuildTypescriptTask(gulp, tsOptions)); watchTasks.push(nameTask(`${target.name}:watch:scripts`, getBuildTypescriptWatchTask(gulp, tsOptions))); // build:copy if (target.copy !== undefined) { const [copyTask, copyWatchTask] = getCopy(gulp, target.srcDir, target.buildDir, target.copy); result.buildCopy = nameTask(`${target.name}:build:copy`, copyTask); watchTasks.push(nameTask(`${target.name}:watch:copy`, copyWatchTask)); } // build const buildTasks = [result.buildScripts]; if (result.buildCopy !== undefined) { buildTasks.push(result.buildCopy); } result.build = nameTask(`${target.name}:build`, gulp.parallel(buildTasks)); result.watch = nameTask(`${target.name}:watch`, gulp.series(result.build, gulp.parallel(watchTasks))); // clean if (target.clean !== undefined) { const cleanOptions = { base: target.project.absRoot, dirs: target.clean.dirs, files: target.clean.files, }; result.clean = nameTask(`${target.name}:clean`, generateCleanTask(gulp, cleanOptions)); } // tsconfig.json if (target.tsconfigJson !== null) { result.tsconfigJson = nameTask(`${target.name}:tsconfig.json`, getTsconfigJsonTask(tsOptions)); } return result; } /** * Generates and registers gulp tasks available for every target (base tasks). * * @param gulp Gulp instance where the tasks will be registered. * @param targetOptions Target configuration. */ export function registerBaseTasks(gulp, targetOptions) { const tasks = generateBaseTasks(gulp, targetOptions); for (const key in tasks) { const task = tasks[key]; if (task !== undefined) { gulp.task(task); } } return tasks; }