glov-build
Version:
GLOV.js Build System
96 lines (84 loc) • 2.61 kB
JavaScript
exports.createTaskState = createTaskState;
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const {
asyncLoader,
asyncSaver,
forwardSlashes,
deleteFileWithRmdir,
writeFileWithMkdir,
} = require('./util.js');
const MODE_SINGLE_FILE = 'single';
// TODO: Add a mode that saves each job as a single .json file, compare performance on a big build
function loadAll(ts, next) {
if (ts.mode === MODE_SINGLE_FILE) {
let disk_path = path.join(ts.dir, 'state.json');
fs.readFile(disk_path, 'utf8', function (err, value) {
ts.job_states = {}; // If error of any kind, reset to empty state
if (err) {
// Probably file doesn't exist, reset to blank state
return next();
}
try {
ts.job_states = JSON.parse(value);
} catch (e) {
// Possibly previous build interrupted while writing state
ts.gb.warn(`Error parsing JSON in ${disk_path} (resetting to blank state): ${e}`);
return next();
}
ts.gb.silly(` Task "${ts.name}": loaded existing job state`);
next();
});
} else {
assert(!'TODO');
}
}
function saveTaskState(ts, next) {
let data = JSON.stringify(ts.job_states, undefined, 2); // TODO: optional formatting when not testing
let disk_path = forwardSlashes(path.join(ts.dir, 'state.json'));
if (data === '{}') {
ts.gb.debug(` Pruning ${disk_path}...`);
deleteFileWithRmdir(disk_path, next);
} else {
ts.gb.silly(` Writing ${disk_path}...`);
writeFileWithMkdir(ts.gb, disk_path, data, next);
}
}
const loader = asyncLoader(loadAll);
const taskSaver = asyncSaver(saveTaskState);
function TaskState(opts) {
assert(opts.dir);
this.mode = MODE_SINGLE_FILE;
this.dir = opts.dir;
this.name = opts.name;
this.gb = opts.gb;
// this.job_states = {};
}
TaskState.prototype.loadAll = function (next) {
loader(this, next);
};
TaskState.prototype.getAllJobStates = function () {
assert(this.job_states); // already called loadAll()
return this.job_states;
};
TaskState.prototype.getJobState = function (job_name) {
assert(this.job_states); // already called loadAll()
return this.job_states[job_name];
};
TaskState.prototype.setJobState = function (job_name, state, next) {
assert(this.job_states); // already called loadAll()
if (!state) {
delete this.job_states[job_name];
} else {
this.job_states[job_name] = state;
}
if (this.mode === MODE_SINGLE_FILE) {
taskSaver(this, next);
} else {
assert(!'TODO');
}
};
function createTaskState(opts) {
return new TaskState(opts);
}