@gold.au/pancake
Version:
Pancake is an utility to make working with npm modules for the frontend sweet and seamlessly.
286 lines (237 loc) • 12 kB
JavaScript
/***************************************************************************************************************************************************************
*
* Returning ansi escape color codes
*
* @repo - https://github.com/designsystemau/pancake
* @author - Dominik Wilkowski
* @license - https://raw.githubusercontent.com/designsystemau/pancake/master/LICENSE (MIT)
*
**************************************************************************************************************************************************************/
; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Dependencies
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var Spawn = require('child_process');
var Path = require('path');
var TTY = require('tty');
var OS = require('os'); //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Module imports
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
var _require = require('./logging'),
Log = _require.Log,
Style = _require.Style; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check npm version
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Check that npm used is 3 and above
*
* @return {boolean} - Whether npm version is satisfied
*/
module.exports.CheckNPM = function () {
var npmVersion = Spawning.sync('npm', ['-v']);
if (npmVersion.error) {
Log.error("Pancake was unable to find an NPM version.");
Log.error(error);
Log.space();
process.exit(1);
} else {
npmVersion = parseInt(npmVersion.stdout.toString().replace('\n', '')); //normalize some oddities npm gives us
}
Log.verbose("NPM version ".concat(Style.yellow(npmVersion), " detected")); //npm 3 and higher is required as below will install dependencies inside each module folder
if (npmVersion < 3) {
return false;
} else {
return true;
}
}; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Finding CWD
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Find the current working directory by checking inside the current directory for a package.json and see if it is a pancake module.
* If it is then we go to the parent folder and run `npm prefix` there. Otherwise run `npm prefix` in the current working directory.
*
* @param {string} cwd - Path to current working directory
*
* @return {string} - The absolute path to the folder of your host package.json
*/
module.exports.Cwd = function () {
var cwd = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : process.cwd();
Log.verbose("Looking for cwd in ".concat(Style.yellow(cwd)));
var rootPath;
var pkgPath; //let’s find the package.json and check if it's a valid one
try {
var location = Path.normalize("".concat(cwd, "/package.json")); //on this level
var testingPkg = require(location);
if (testingPkg.pancake['pancake-module'] !== undefined) {
//this package.json has an pancake-module object
Log.verbose("Found valid pancake-module packages in ".concat(Style.yellow(cwd)));
rootPath = Path.normalize("".concat(cwd, "/../")); //so let’s go down one level and look for the next package.json file
pkgPath = Spawning.sync('npm', ['prefix'], {
cwd: rootPath
}); //this will find the nearest package.json
if (pkgPath.error) {
Log.error("Pancake was unable to find a folder with a package.json file from ".concat(Style.yellow(rootPath), "."));
Log.space();
process.exit(1);
} else {
pkgPath = Path.normalize(pkgPath.stdout.toString().replace('\n', '')); //normalize some oddities npm gives us
}
} else {
//not a valid pancake module
Log.verbose("Package.json not a pancake-module in ".concat(Style.yellow(location)));
pkgPath = Path.normalize("".concat(cwd, "/")); //we start looking from here on for the next package.json
}
} catch (error) {
//no package.json found in this folder
Log.verbose("No package.json found in ".concat(Style.yellow(cwd)));
rootPath = Path.normalize("".concat(cwd, "/")); //we start looking from here on for the next package.json
pkgPath = Spawning.sync('npm', ['prefix'], {
cwd: rootPath
}); //this will find the nearest package.json
if (pkgPath.error) {
Log.error("Pancake was unable to find a folder with a package.json file from ".concat(Style.yellow(rootPath), "."));
Log.space();
process.exit(1);
} else {
pkgPath = Path.normalize(pkgPath.stdout.toString().replace('\n', '')); //normalize some oddities npm gives us
}
}
Log.verbose("Cwd is ".concat(Style.yellow(pkgPath)));
return pkgPath;
}; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Get cli window size
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Get the size of the cli window
* A port from https://github.com/jonschlinkert/window-size
*
* @return {object} - An object with width and height
*/
module.exports.Size = function () {
var width;
var height;
if (TTY.isatty(1)) {
if (process.stdout.getWindowSize) {
width = process.stdout.getWindowSize(1)[0];
height = process.stdout.getWindowSize(1)[1];
} else if (TTY.getWindowSize) {
width = TTY.getWindowSize()[1];
height = TTY.getWindowSize()[0];
} else if (process.stdout.columns && process.stdout.rows) {
height = process.stdout.rows;
width = process.stdout.columns;
}
} else if (OS.release().startsWith('10')) {
var numberPattern = /\d+/g;
var cmd = 'wmic path Win32_VideoController get CurrentHorizontalResolution,CurrentVerticalResolution';
var code = Spawn.execSync(cmd).toString('utf8');
var res = code.match(numberPattern);
return {
height: ~~res[1],
width: ~~res[0]
};
} else {
return {
height: undefined,
width: undefined
};
}
return {
height: height,
width: width
};
}; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Spawning new processes cross os
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Spawning child processes in an abstraction so we can handle different OS
*
* @type {Object}
*/
var Spawning = {
isWin: /^win/.test(process.platform),
//sniffing the os, Can’t use os.platform() as we want to support node 5
/**
* Spawning async
*
* @param {string} command - The program we run
* @param {array} options - the flags and options we pass to it
* @param {object} param - Parameters we pass to child_process
*
* @return {Promise object} - The error code returned from child_process.spawn
*/
async: function async(command, options) {
var param = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Log.verbose("Spawning async ".concat(Style.yellow("".concat(command, " ").concat(_toConsumableArray(options).join(' '))), " with ").concat(Style.yellow(JSON.stringify(param))));
return new Promise(function (resolve, reject) {
var operation;
var error = ""; //gather errors
if (Spawning.isWin) {
operation = Spawn.spawn('cmd.exe', ['/s', '/c', command].concat(_toConsumableArray(options)), param);
} else {
operation = Spawn.spawn(command, _toConsumableArray(options), param);
}
if (operation.stderr) {
//if we even have an output
operation.stderr.on('data', function (error) {
error += error; //add to error object
});
}
operation.on('close', function (code) {
if (code !== 0) {
reject(error.toString()); //ignore warnings
} else {
resolve(code);
}
});
});
},
/**
* Spawning sync
*
* @param {string} command - The program we run
* @param {array} options - the flags and options we pass to it
* @param {object} param - Parameters we pass to child_process
*
* @return {object} - The object returned from child_process.spawnSync
*/
sync: function sync(command, options) {
var param = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Log.verbose("Spawning sync ".concat(Style.yellow("".concat(command, " ").concat(_toConsumableArray(options).join(' '))), " with ").concat(Style.yellow(JSON.stringify(param))));
if (Spawning.isWin) {
return Spawn.spawnSync('cmd.exe', ['/s', '/c', command].concat(_toConsumableArray(options)), param);
} else {
return Spawn.spawnSync(command, _toConsumableArray(options), param);
}
}
}; //--------------------------------------------------------------------------------------------------------------------------------------------------------------
// Exit handler
//--------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Handle exiting of program
*
* @param {null} exiting - null for bind
* @param {object} error - Object to distinguish between closing events
*/
module.exports.ExitHandler = function (exiting, error) {
if (error && error !== 1) {
try {
//try using our pretty output
Log.error(error);
} catch (error) {
//looks like it’s broken too so let’s just do the old school thing
console.error(error);
}
}
if (exiting.withoutSpace) {
process.exit(0); //exit now
}
Log.space(); //adding some space
process.exit(0); //now exit with a smile :)
};
module.exports.Spawning = Spawning;