cli-engine
Version:
Generic CLI Framework
156 lines (125 loc) • 4.25 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _hooks = require('../hooks');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _manager = require('./manager');
var _yarn = require('./yarn');
var _yarn2 = _interopRequireDefault(_yarn);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class UserPluginPath extends _manager.PluginPath {
constructor({ config, type, path, tag, userPlugins }) {
super({ config, type, path, tag });
this.repairAttempted = false;
this.userPlugins = userPlugins;
}
async repair(err) {
if (err.code !== 'MODULE_NOT_FOUND') return false;
if (this.repairAttempted) return false;
this.cli.warn(err);
this.cli.action.start(`Repairing plugin ${this.path}`);
this.repairAttempted = true;
await this.userPlugins.installForce();
this.cli.action.stop();
return true;
}
}
class UserPlugins extends _manager.Manager {
constructor({ config, cache }) {
super({ config, cache });
this.yarn = new _yarn2.default(this.config, this.userPluginsDir);
this.hooks = new _hooks.Hooks({ config });
}
/**
* list user plugins
* @returns {PluginPath[]}
*/
async list() {
try {
const pjson = this.userPluginsPJSON;
return entries(pjson.dependencies || {}).filter(([name, tag]) => name !== 'semver').map(([name, tag]) => {
return new UserPluginPath({ config: this.config, type: 'user', path: this.userPluginPath(name), tag: tag, userPlugins: this });
});
} catch (err) {
this.cli.warn(err, 'error loading user plugins');
return [];
}
}
get userPluginsPJSON() {
try {
return _fsExtra2.default.readJSONSync(this.userPluginsPJSONPath);
} catch (err) {
return { dependencies: {} };
}
}
saveUserPluginsPJSON(pjson) {
_fsExtra2.default.writeJSONSync(_path2.default.join(this.userPluginsPJSONPath), pjson);
}
async setupUserPlugins() {
const pjson = _path2.default.join(this.userPluginsDir, 'package.json');
_fsExtra2.default.mkdirpSync(this.userPluginsDir);
if (!_fsExtra2.default.existsSync(pjson)) _fsExtra2.default.writeFileSync(pjson, JSON.stringify({ private: true }));
}
async installForce() {
if (_fsExtra2.default.existsSync(_path2.default.join(this.userPluginsDir, 'node_modules'))) {
await this.yarn.exec(['install', '--force']);
}
}
async handleNodeVersionChange() {
try {
await this.installForce();
} catch (err) {
this.cli.warn(err);
}
}
async install(name, tag = 'latest') {
await this.hooks.run('plugins:preinstall', { plugin: name, tag });
await this.setupUserPlugins();
this.addPackageToPJSON(name, tag);
try {
await this.yarn.exec();
let path = this.userPluginPath(name);
// let plugin = require(path)
// if (!plugin.commands) throw new Error(`${name} does not appear to be a ${this.config.bin} CLI plugin`)
return path;
} catch (err) {
this.removePackageFromPJSON(name);
this.cli.error(err);
throw new Error('unreachable');
}
}
async update() {
await this.setupUserPlugins();
await this.yarn.exec(['upgrade']);
}
async remove(name) {
await this.yarn.exec(['remove', name]);
}
addPackageToPJSON(name, version = '*') {
let pjson = this.userPluginsPJSON;
if (!pjson.dependencies) pjson.dependencies = {};
pjson.dependencies[name] = version;
this.saveUserPluginsPJSON(pjson);
}
removePackageFromPJSON(name) {
let pjson = this.userPluginsPJSON;
if (!pjson.dependencies) pjson.dependencies = {};
delete pjson.dependencies[name];
this.saveUserPluginsPJSON(pjson);
}
get userPluginsDir() {
return _path2.default.join(this.config.dataDir, 'plugins');
}
get userPluginsPJSONPath() {
return _path2.default.join(this.userPluginsDir, 'package.json');
}
userPluginPath(name) {
return _path2.default.join(this.userPluginsDir, 'node_modules', name);
}
}
exports.default = UserPlugins;
const entries = o => Object.keys(o).map(k => [k, o[k]]);