mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 07:48:55 +00:00
136 lines
2.5 KiB
JavaScript
136 lines
2.5 KiB
JavaScript
/**
|
|
* @file
|
|
* @copyright 2020 Aleksej Komarov
|
|
* @license MIT
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const glob = require('./glob');
|
|
|
|
class File {
|
|
constructor(path) {
|
|
this.path = path;
|
|
}
|
|
|
|
get stat() {
|
|
if (this._stat === undefined) {
|
|
this._stat = stat(this.path);
|
|
}
|
|
return this._stat;
|
|
}
|
|
|
|
exists() {
|
|
return this.stat !== null;
|
|
}
|
|
|
|
get mtime() {
|
|
return this.stat && this.stat.mtime;
|
|
}
|
|
|
|
touch() {
|
|
const time = new Date();
|
|
try {
|
|
fs.utimesSync(this.path, time, time);
|
|
}
|
|
catch (err) {
|
|
fs.closeSync(fs.openSync(this.path, 'w'));
|
|
}
|
|
}
|
|
}
|
|
|
|
class Glob {
|
|
constructor(path) {
|
|
this.path = path;
|
|
}
|
|
|
|
toFiles() {
|
|
const paths = glob.sync(this.path, {
|
|
strict: false,
|
|
silent: true,
|
|
});
|
|
return paths
|
|
.map(path => new File(path))
|
|
.filter(file => file.exists());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If true, source is newer than target.
|
|
* @param {File[]} sources
|
|
* @param {File[]} targets
|
|
*/
|
|
const compareFiles = (sources, targets) => {
|
|
let bestSource = null;
|
|
let bestTarget = null;
|
|
for (const file of sources) {
|
|
if (!bestSource || file.mtime > bestSource.mtime) {
|
|
bestSource = file;
|
|
}
|
|
}
|
|
for (const file of targets) {
|
|
if (!file.exists()) {
|
|
return `target '${file.path}' is missing`;
|
|
}
|
|
if (!bestTarget || file.mtime < bestTarget.mtime) {
|
|
bestTarget = file;
|
|
}
|
|
}
|
|
// Doesn't need rebuild if there is no source, but target exists.
|
|
if (!bestSource) {
|
|
if (bestTarget) {
|
|
return false;
|
|
}
|
|
return 'no known sources or targets';
|
|
}
|
|
// Always needs a rebuild if no targets were specified (e.g. due to GLOB).
|
|
if (!bestTarget) {
|
|
return 'no targets were specified';
|
|
}
|
|
// Needs rebuild if source is newer than target
|
|
if (bestSource.mtime > bestTarget.mtime) {
|
|
return `source '${bestSource.path}' is newer than target '${bestTarget.path}'`;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Returns file stats for the provided path, or null if file is
|
|
* not accessible.
|
|
*/
|
|
const stat = path => {
|
|
try {
|
|
return fs.statSync(path);
|
|
}
|
|
catch {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Resolves a glob pattern and returns files that are safe
|
|
* to call `stat` on.
|
|
*/
|
|
const resolveGlob = globPath => {
|
|
const unsafePaths = glob.sync(globPath, {
|
|
strict: false,
|
|
silent: true,
|
|
});
|
|
const safePaths = [];
|
|
for (let path of unsafePaths) {
|
|
try {
|
|
fs.statSync(path);
|
|
safePaths.push(path);
|
|
}
|
|
catch {}
|
|
}
|
|
return safePaths;
|
|
};
|
|
|
|
module.exports = {
|
|
File,
|
|
Glob,
|
|
compareFiles,
|
|
stat,
|
|
resolveGlob,
|
|
};
|