pitaya-launcher/src/util/system.js

186 lines
4.2 KiB
JavaScript

/* jshint node:true */
var fs = require('fs');
var cp = require('child_process');
var glob = require('glob');
var ini = require('ini');
var Cache = require('./cache');
var request = require('request');
var HTTP_REGEX = /^https?:\/\//i;
/**
* Load a JSON file (http or local)
*
* @param filePath The path of the json file
* @return Promise
*/
exports.loadJSON = function(jsonUrl) {
if( HTTP_REGEX.test(jsonUrl) ) {
return exports.fetchRemoteJSON(jsonUrl);
} else {
return exports.loadLocalJSON(jsonUrl);
}
};
/**
* Load a remote JSON file via http
*
* @param filePath The path of the json file
* @return Promise
*/
exports.fetchRemoteJSON = function(fileUrl) {
return new Promise(function(resolve, reject) {
request(fileUrl, { followRedirect: true, json: true }, function (err, res, body) {
if(err) return reject(err);
return resolve(body);
});
});
};
/**
* Load a local JSON file
*
* @param filePath The path of the json file
* @return Promise
*/
exports.loadLocalJSON = function(filePath) {
return new Promise(function(resolve, reject) {
fs.readFile(filePath, 'utf8', function(err, fileContent) {
if(err) return reject(err);
try {
var json = JSON.parse(fileContent);
return resolve(json);
} catch(err) {
return reject(err);
}
});
});
};
exports.saveJSON = function(filePath, obj) {
var jsonStr = JSON.stringify(obj, null, 2);
return new Promise(function(resolve, reject) {
fs.writeFile(filePath, jsonStr, function(err) {
if(err) return reject(err);
return resolve();
});
});
};
/**
* Load a INI file
*
* @param filePath The path of the json file
* @return Promise
*/
exports.loadINIFile = function(filePath) {
return new Promise(function(resolve, reject) {
fs.readFile(filePath, 'utf8', function(err, content) {
if(err) return reject(err);
try {
var decoded = ini.decode(content);
return resolve(decoded);
} catch(err) {
return reject(err);
}
});
});
};
exports.clearFreeDesktopFlags = function(exec) {
return exec.replace(/%[uUdDfFnNickvm]/g, '');
};
exports.runApp = function(execPath, opts) {
opts = opts || {};
return new Promise(function(resolve, reject) {
try {
if(opts.clearFreeDesktopFlags) {
execPath = exports.clearFreeDesktopFlags(execPath);
}
var isDev = process.env.NODE_ENV === 'development';
var child = cp.spawn(execPath, {
detached: true,
shell: true,
stdio: [
'ignore',
isDev ? process.stdout : 'ignore',
isDev ? process.stderr : 'ignore'
]
});
// Detach the child process
child.unref();
} catch(err) {
return reject(err);
}
// Execute the rest after all I/O operations in this tick
let immediateId = setImmediate(() => {
// We do not want to be notified of child events after launch
child.removeAllListeners();
try {
// Check if the child process is still alive, should throw otherwise
child.kill(0);
} catch(err) {
return reject(err);
}
return resolve(child);
});
// If the child process exit with an exit code != 0, reject the promise
child.once('close', code => {
if(code === 0) return;
clearImmediate(immediateId);
child.removeAllListeners();
return reject(`Program exited with a exit code "${code}"`);
});
// If an error occurs during the process launch, reject the promise
child.once('error', err => {
clearImmediate(immediateId);
child.removeAllListeners();
return reject(err);
});
});
};
var _searchCache = new Cache();
exports.findFiles = function(pattern, opts) {
return new Promise(function(resolve, reject) {
var cachedResult = _searchCache.get([pattern, opts]);
if( cachedResult !== undefined) {
return resolve(cachedResult);
}
glob(pattern, opts, function(err, files) {
if(err) return reject(err);
_searchCache.set([pattern, opts], files);
return resolve(files);
});
});
};
exports.exists = function(filePath) {
return new Promise(function(resolve) {
fs.exists(filePath, resolve);
});
};