turbo-gulp
Version:
Gulp tasks to boost high-quality projects.
190 lines (189 loc) • 7.42 kB
JavaScript
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;
}