From b1a0e14ee2b7c4e39c3b83591adf273df7a59417 Mon Sep 17 00:00:00 2001 From: muxator Date: Wed, 22 Aug 2018 00:38:13 +0200 Subject: [PATCH] AbsolutePaths: written findEtherpadRoot() This is just a function (with an ugly side effect for caching purposes) that heuristically tries to compute the Etherpad installation path when running under Unix and win32 (they have different file system layouts). This path can be used by Etherpad as a base for all the relative paths, in order to be deterministic and not depending on cwd. --- src/node/utils/AbsolutePaths.js | 65 +++++++++++++++++++++++++++++++++ src/package.json | 1 + 2 files changed, 66 insertions(+) diff --git a/src/node/utils/AbsolutePaths.js b/src/node/utils/AbsolutePaths.js index 2736599b6..3a7e60f0d 100644 --- a/src/node/utils/AbsolutePaths.js +++ b/src/node/utils/AbsolutePaths.js @@ -19,10 +19,17 @@ */ var log4js = require('log4js'); +var path = require('path'); var _ = require('underscore'); var absPathLogger = log4js.getLogger('AbsolutePaths'); +/* + * findEtherpadRoot() computes its value only on first invocation. + * Subsequent invocations are served from this variable. + */ +var etherpadRoot = null; + /** * If stringArray's last elements are exactly equal to lastDesiredElements, * returns a copy in which those last elements are popped, or false otherwise. @@ -49,3 +56,61 @@ var popIfEndsWith = function(stringArray, lastDesiredElements) { absPathLogger.debug(`${stringArray.join(path.sep)} does not end with "${lastDesiredElements.join(path.sep)}"`); return false; }; + +/** + * Heuristically computes the directory in which Etherpad is installed. + * + * All the relative paths have to be interpreted against this absolute base + * path. Since the Unix and Windows install have a different layout on disk, + * they are treated as two special cases. + * + * The path is computed only on first invocation. Subsequent invocations return + * a cached value. + * + * The cached value is stored in AbsolutePaths.etherpadRoot via a side effect. + * + * @return {string} The identified absolute base path. If such path cannot be + * identified, prints a log and exits the application. + */ +exports.findEtherpadRoot = function() { + if (etherpadRoot !== null) { + return etherpadRoot; + } + + const findRoot = require('find-root'); + const foundRoot = findRoot(__dirname); + + var directoriesToStrip; + if (process.platform === 'win32') { + /* + * Given the structure of our Windows package, foundRoot's value + * will be the following on win32: + * + * \node_modules\ep_etherpad-lite + */ + directoriesToStrip = ['node_modules', 'ep_etherpad-lite']; + } else { + /* + * On Unix platforms, foundRoot's value will be: + * + * \src + */ + directoriesToStrip = ['src']; + } + + const maybeEtherpadRoot = popIfEndsWith(foundRoot.split(path.sep), directoriesToStrip); + if (maybeEtherpadRoot === false) { + absPathLogger.error(`Could not identity Etherpad base path in this ${process.platform} installation in "${foundRoot}"`); + process.exit(1); + } + + // SIDE EFFECT on this module-level variable + etherpadRoot = maybeEtherpadRoot.join(path.sep); + + if (path.isAbsolute(etherpadRoot)) { + return etherpadRoot; + } + + absPathLogger.error(`To run, Etherpad has to identify an absolute base path. This is not: "${etherpadRoot}"`); + process.exit(1); +}; diff --git a/src/package.json b/src/package.json index b6df2acb3..bbb069201 100644 --- a/src/package.json +++ b/src/package.json @@ -38,6 +38,7 @@ "etherpad-yajsml": "0.0.2", "express": "4.16.3", "express-session": "1.15.6", + "find-root": "1.1.0", "formidable": "1.2.1", "graceful-fs": "4.1.3", "jsonminify": "0.4.1",