mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
97 lines
2.1 KiB
TypeScript
97 lines
2.1 KiB
TypeScript
import {Stats} from 'fs';
|
|
import {stat} from 'fs/promises';
|
|
import {glob} from 'glob';
|
|
import path from 'path';
|
|
|
|
interface JobContext {
|
|
name: string;
|
|
inputs: string[];
|
|
outputs: string[];
|
|
}
|
|
|
|
class JobBuilder {
|
|
#inputs: string[] = [];
|
|
#outputs: string[] = [];
|
|
#callback: (ctx: JobContext) => Promise<void>;
|
|
#name: string;
|
|
|
|
constructor(name: string, callback: (ctx: JobContext) => Promise<void>) {
|
|
this.#name = name;
|
|
this.#callback = callback;
|
|
}
|
|
|
|
inputs(inputs: string[]): JobBuilder {
|
|
this.#inputs = inputs.flatMap(value => {
|
|
value = path.resolve(__dirname, '..', '..', value);
|
|
const paths = glob.sync(value);
|
|
return paths.length ? paths : [value];
|
|
});
|
|
return this;
|
|
}
|
|
|
|
outputs(outputs: string[]): JobBuilder {
|
|
if (!this.#name) {
|
|
this.#name = outputs[0]!;
|
|
}
|
|
|
|
this.#outputs = outputs.map(value => {
|
|
return path.resolve(__dirname, '..', '..', value);
|
|
});
|
|
return this;
|
|
}
|
|
|
|
async build(): Promise<void> {
|
|
console.log(`Running job ${this.#name}...`);
|
|
|
|
let shouldRun = true;
|
|
|
|
const inputStats = await Promise.all(
|
|
this.#inputs.map(input => {
|
|
return stat(input);
|
|
})
|
|
);
|
|
let outputStats: Stats[];
|
|
try {
|
|
outputStats = await Promise.all(
|
|
this.#outputs.map(output => {
|
|
return stat(output);
|
|
})
|
|
);
|
|
|
|
if (
|
|
outputStats.reduce(reduceMaxTime, 0) >=
|
|
inputStats.reduce(reduceMinTime, Infinity)
|
|
) {
|
|
shouldRun = false;
|
|
}
|
|
} catch {}
|
|
|
|
if (shouldRun) {
|
|
this.#run();
|
|
}
|
|
}
|
|
|
|
#run(): Promise<void> {
|
|
return this.#callback({
|
|
name: this.#name,
|
|
inputs: this.#inputs,
|
|
outputs: this.#outputs,
|
|
});
|
|
}
|
|
}
|
|
|
|
export const job = (
|
|
name: string,
|
|
callback: (ctx: JobContext) => Promise<void>
|
|
): JobBuilder => {
|
|
return new JobBuilder(name, callback);
|
|
};
|
|
|
|
const reduceMaxTime = (time: number, stat: Stats) => {
|
|
return time < stat.mtimeMs ? stat.mtimeMs : time;
|
|
};
|
|
|
|
const reduceMinTime = (time: number, stat: Stats) => {
|
|
return time > stat.mtimeMs ? stat.mtimeMs : time;
|
|
};
|