| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*
- * decaffeinate suggestions:
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
- * DS205: Consider reworking code to avoid use of IIFEs
- * DS207: Consider shorter variations of null checks
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- const coffee = require("coffee-script");
- const fs = require("fs");
- const {
- spawn
- } = require("child_process");
- const {
- exec
- } = require("child_process");
- const rimraf = require("rimraf");
- const Path = require("path");
- const semver = require("semver");
- const knox = require("knox");
- const crypto = require("crypto");
- const async = require("async");
- const settings = require("settings-sharelatex");
- const _ = require("underscore");
- const SERVICES = require("./config/services");
- module.exports = function(grunt) {
- let Helpers;
- let service;
- grunt.loadNpmTasks('grunt-bunyan');
- grunt.loadNpmTasks('grunt-execute');
- grunt.loadNpmTasks('grunt-available-tasks');
- grunt.loadNpmTasks('grunt-concurrent');
- grunt.loadNpmTasks("grunt-contrib-coffee");
- grunt.loadNpmTasks("grunt-shell");
- grunt.task.loadTasks("./tasks");
- const execute = {};
- for (service of Array.from(SERVICES)) {
- execute[service.name] =
- {src: `${service.name}/app.js`};
- }
- grunt.initConfig({
- execute,
- concurrent: {
- all: {
- tasks: (((() => {
- const result = [];
- for (service of Array.from(SERVICES)) { result.push(`run:${service.name}`);
- }
- return result;
- })())),
- options: {
- limit: SERVICES.length,
- logConcurrentOutput: true
- availabletasks: {
- tasks: {
- options: {
- filter: 'exclude',
- tasks: [
- 'concurrent',
- 'execute',
- 'bunyan',
- 'availabletasks'
- ],
- groups: {
- "Run tasks": [
- "run",
- "run:all",
- "default"
- ].concat(((() => {
- const result1 = [];
- for (service of Array.from(SERVICES)) { result1.push(`run:${service.name}`);
- }
- return result1;
- })())),
- "Misc": [
- "help"
- ],
- "Install tasks": ((() => {
- const result2 = [];
- for (service of Array.from(SERVICES)) { result2.push(`install:${service.name}`);
- }
- return result2;
- })()).concat(["install:all", "install"]),
- "Update tasks": ((() => {
- const result3 = [];
- for (service of Array.from(SERVICES)) { result3.push(`update:${service.name}`);
- }
- return result3;
- })()).concat(["update:all", "update"]),
- "Checks": ["check", "check:redis", "check:latexmk", "check:s3", "check:make", "check:mongo"]
- }
- }
- }
- }});
- for (service of Array.from(SERVICES)) {
- ((service => grunt.registerTask(`install:${service.name}`, `Download and set up the ${service.name} service`, function() {
- const done = this.async();
- return Helpers.installService(service, done);
- })))(service);
- }
- grunt.registerTask('install:all', "Download and set up all ShareLaTeX services",
- [].concat(
- ((() => {
- const result4 = [];
- for (service of Array.from(SERVICES)) { result4.push(`install:${service.name}`);
- }
- return result4;
- })())
- ).concat(['postinstall'])
- );
- grunt.registerTask('install', 'install:all');
- grunt.registerTask('postinstall', 'Explain postinstall steps', function() {
- return Helpers.postinstallMessage(this.async());
- });
- grunt.registerTask('update:all', "Checkout and update all ShareLaTeX services",
- ["check:make"].concat(
- ((() => {
- const result5 = [];
- for (service of Array.from(SERVICES)) { result5.push(`update:${service.name}`);
- }
- return result5;
- })())
- )
- );
- grunt.registerTask('update', 'update:all');
- grunt.registerTask('run', "Run all of the sharelatex processes", ['concurrent:all']);
- grunt.registerTask('run:all', 'run');
- grunt.registerTask('help', 'Display this help list', 'availabletasks');
- grunt.registerTask('default', 'run');
- grunt.registerTask("check:redis", "Check that redis is installed and running", function() {
- return Helpers.checkRedisConnect(this.async());
- });
- grunt.registerTask("check:mongo", "Check that mongo is installed", function() {
- return Helpers.checkMongoConnect(this.async());
- });
- grunt.registerTask("check", "Check that you have the required dependencies installed", ["check:redis", "check:mongo", "check:make"]);
- grunt.registerTask("check:make", "Check that make is installed", function() {
- return Helpers.checkMake(this.async());
- });
- return Helpers = {
- installService(service, callback) {
- if (callback == null) { callback = function(error) {}; }
- console.log(`Installing ${service.name}`);
- return Helpers.cloneGitRepo(service, function(error) {
- if (error != null) {
- return callback(error);
- } else {
- return callback();
- }
- });
- },
- cloneGitRepo(service, callback) {
- if (callback == null) { callback = function(error) {}; }
- const repo_src = service.repo;
- const dir = service.name;
- if (!fs.existsSync(dir)) {
- const proc = spawn("git", [
- "clone",
- repo_src,
- dir
- ], {stdio: "inherit"});
- return proc.on("close", () => Helpers.checkoutVersion(service, callback));
- } else {
- console.log(`${dir} already installed, skipping.`);
- return callback();
- }
- },
- checkoutVersion(service, callback) {
- if (callback == null) { callback = function(error) {}; }
- const dir = service.name;
- grunt.log.write(`checking out ${service.name} ${service.version}`);
- const proc = spawn("git", ["checkout", service.version], {stdio: "inherit", cwd: dir});
- return proc.on("close", () => callback());
- },
- postinstallMessage(callback) {
- if (callback == null) { callback = function(error) {}; }
- grunt.log.write(`\
- Services cloned:
- ${(() => {
- const result6 = [];
- for (service of Array.from(SERVICES)) { result6.push(service.name);
- }
- return result6;
- })()}
- To install services run:
- $ source bin/install-services
- This will install the required node versions and run \`npm install\` for each service.
- See https://github.com/sharelatex/sharelatex/pull/549 for more info.\
- `
- );
- return callback();
- },
- checkMake(callback) {
- if (callback == null) { callback = function(error) {}; }
- grunt.log.write("Checking make is installed... ");
- return exec("make --version", function(error, stdout, stderr) {
- if ((error != null) && error.message.match("not found")) {
- grunt.log.error("FAIL.");
- grunt.log.errorlns(`\
- Either make is not installed or is not in your path.
- On Ubuntu you can install make with:
- sudo apt-get install build-essential
- \
- `
- );
- return callback(error);
- } else if (error != null) {
- return callback(error);
- } else {
- grunt.log.write("OK.");
- return callback();
- }
- });
- },
- checkMongoConnect(callback) {
- if (callback == null) { callback = function(error) {}; }
- grunt.log.write("Checking can connect to mongo");
- const mongojs = require("mongojs");
- const db = mongojs(settings.mongo.url, ["tags"]);
- db.runCommand({ ping: 1 }, function(err, res) {
- if (!err && res.ok) {
- grunt.log.write("OK.");
- }
- return callback();
- });
- return db.on('error', function(err){
- err = "Can not connect to mongodb";
- grunt.log.error("FAIL.");
- grunt.log.errorlns(`\
- !!!!!!!!!!!!!! MONGO ERROR !!!!!!!!!!!!!!
- ShareLaTeX can not talk to the mongodb instance
- Check the mongodb instance is running and accessible on env var SHARELATEX_MONGO_URL
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\
- `
- );
- throw new Error("Can not connect to Mongodb");
- return callback(err);
- });
- },
- checkRedisConnect(callback) {
- if (callback == null) { callback = function(error) {}; }
- grunt.log.write("Checking can connect to redis\n");
- const rclient = require("redis").createClient(settings.redis.web);
- rclient.ping(function(err, res) {
- if ((err == null)) {
- grunt.log.write("OK.");
- } else {
- throw new Error("Can not connect to redis");
- }
- return callback();
- });
- const errorHandler = _.once(function(err){
- err = "Can not connect to redis";
- grunt.log.error("FAIL.");
- grunt.log.errorlns(`\
- !!!!!!!!!!!!!! REDIS ERROR !!!!!!!!!!!!!!
- ShareLaTeX can not talk to the redis instance
- Check the redis instance is running and accessible on env var SHARELATEX_REDIS_HOST
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\
- `
- );
- throw new Error("Can not connect to redis");
- return callback(err);
- });
- return rclient.on('error', errorHandler);
- }
- };
- };
- function __guard__(value, transform) {
- return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;
- }
|