/* 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); }); };