pandemics
Version:
Simplified academic writing.
146 lines (127 loc) • 3.66 kB
JavaScript
const fse = require('fs-extra');
const config = require('../config.js');
const gitSource = require('git-source');
const { spawnSync } = require('child_process');
const path = require('path');
const Instructions = require('./Instructions.js');
module.exports = class Recipe {
constructor (fingerprint, format) {
// try to get default repo if necessary
fingerprint = fingerprint || this.default (format || 'pdf');
// no repo found
this.isDefault = !fingerprint;
// look up repo and version
if (!this.isDefault) {
const [repoId, tag] = fingerprint.trim().split(/\s+/);
this.repo = gitSource(repoId);
this.tag = tag;
this.isDev = this.repo.resource === 'dev';
}
// clone if necessary
if (!this.isInstalled) {
this.install();
// otherwise checkout latest version
} else {
this.update();
}
// get instructions
this.loadInstructions (format)
}
get url () {
return this.isDefault ? null : this.repo.toString();
}
get path () {
if (!this.isDefault) {
return path.join(
this.repo.resource,
this.repo.pathname
);
}
}
get fullPath () {
if (!this.isDefault) {
return path.join(
config.RECIPES_PATH,
this.path
);
}
}
get isInstalled () {
return this.isDefault || fse.existsSync(this.fullPath);
}
loadInstructions (fmt) {
if (!this.isDefault && !this.isInstalled) {
throw new Error(`Cannot load instruction if the recipe is not installed.`);
}
this.instructions = new Instructions(this, fmt);
}
update () {
if (this.isDefault || this.isDev) return;
const ps = spawnSync(
`git reset --hard HEAD;
git clean -f -d;
git submodule foreach --recursive "git reset --hard; git clean -f -d;"
git fetch origin -t ${this.tag || 'master'} --recurse-submodules;
git checkout ${this.tag || 'master'};
git pull;
git checkout ${this.tag || 'master'};
git submodule sync --recursive;
git submodule update --init --force --recursive;`,
{
cwd: this.fullPath,
shell: true
}
);
}
install () {
if (this.isDefault || this.isDev) return;
// call git clone
const ps = spawnSync(
`git clone --recurse-submodules ${this.url} ${this.path}`,
{
cwd: config.RECIPES_PATH,
shell: true
}
);
// feedback
if (ps.status !== 0) {
throw new Error(`Could not install recipe: ${ps.stderr.toString()}`);
}
}
uninstall () {
if (this.isDefault || this.isDev) return;
// check if template already exists
if (!this.isInstalled) {
throw new Error('There is no recipe to uninstall.');
}
fse.removeSync(this.fullPath);
// TODO: remove empty parents
}
toString () {
let s = 'Recipe:';
s += `\n - isDefault: ${this.isDefault}`;
s += `\n - repo: ${this.repo}`;
s += `\n - tag: ${this.tag}`;
s += `\n - path: ${this.fullPath}`;
s += `\n - instructions:`;
s += `\n -format: ${this.instructions.format}`;
s += `\n -json: ${JSON.stringify(this.instructions._record)}`;
return s;
}
default (format) {
switch (format.split('.').pop()) {
case 'pdf':
return 'https://gitlab.com/pandemics/recipe-default-pdf';
break;
case 'docx':
return 'https://gitlab.com/pandemics/recipe-default-docx';
break;
case 'html':
return 'https://gitlab.com/pandemics/recipe-default-html';
break;
}
}
useLatex () {
return ['tex','pdf'].some(e=>this.instructions.format.endsWith(e))
}
};