bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
309 lines (237 loc) • 8.84 kB
JavaScript
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.onCapsuleInstalled = onCapsuleInstalled;
exports.beforeInstallingCapsules = beforeInstallingCapsules;
exports.default = void 0;
function _bluebird() {
const data = require("bluebird");
_bluebird = function () {
return data;
};
return data;
}
function _defineProperty2() {
const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
_defineProperty2 = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireWildcard(require("path"));
_path = function () {
return data;
};
return data;
}
function _events() {
const data = require("events");
_events = function () {
return data;
};
return data;
}
function _fsExtra() {
const data = _interopRequireDefault(require("fs-extra"));
_fsExtra = function () {
return data;
};
return data;
}
function _pMapSeries() {
const data = _interopRequireDefault(require("p-map-series"));
_pMapSeries = function () {
return data;
};
return data;
}
function _execa() {
const data = _interopRequireDefault(require("execa"));
_execa = function () {
return data;
};
return data;
}
function _child_process() {
const data = require("../../utils/child_process");
_child_process = function () {
return data;
};
return data;
}
function _createSymlinkOrCopy() {
const data = _interopRequireDefault(require("../../utils/fs/create-symlink-or-copy"));
_createSymlinkOrCopy = function () {
return data;
};
return data;
}
/* eslint-disable no-empty */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
// TODO:
// this is a hack in order to pass events from here to flows (and later install)
// we need to solve this hack by changing the dependency chain of the relevant extensions
// essentially flattening the structure so that we have less extensions to pass this event through
//
// at the time of writing, it's Flows => Workspace => Isolator => PackageManager
let emitter = null;
function onCapsuleInstalled(cb) {
// @ts-ignore - this is a hack
emitter.on('capsuleInstalled', componentName => cb(componentName));
}
function beforeInstallingCapsules(cb) {
// @ts-ignore - this is a hack
emitter.on('beforeInstallingCapsules', numCapsules => cb(numCapsules));
}
class PackageManager {
constructor(packageManagerName, logger) {
this.packageManagerName = packageManagerName;
this.logger = logger;
(0, _defineProperty2().default)(this, "emitter", new (_events().EventEmitter)());
// @ts-ignore - this is a hack
emitter = this.emitter;
}
get name() {
return this.packageManagerName;
}
checkIfFileExistsInCapsule(capsule, file) {
return (0, _bluebird().coroutine)(function* () {
const pathToFile = (0, _path().join)(capsule.wrkDir, file);
try {
yield capsule.fs.promises.access(pathToFile);
return true;
} catch (e) {}
return false;
})();
}
removeLockFilesInCapsule(capsule) {
return (0, _bluebird().coroutine)(function* () {
function safeUnlink(_x) {
return _safeUnlink.apply(this, arguments);
}
function _safeUnlink() {
_safeUnlink = (0, _bluebird().coroutine)(function* (toRemove) {
try {
yield capsule.fs.promises.unlink((0, _path().join)(capsule.wrkDir, toRemove));
} catch (e) {}
});
return _safeUnlink.apply(this, arguments);
}
yield safeUnlink('yarn.lock');
yield safeUnlink('package-lock.json');
})();
}
capsulesInstall(capsules, opts = {}) {
var _this = this;
return (0, _bluebird().coroutine)(function* () {
const packageManager = opts.packageManager || _this.packageManagerName;
const logPublisher = _this.logger.createLogPublisher('packageManager');
_this.emitter.emit('beforeInstallingCapsules', capsules.length);
if (packageManager === 'npm' || packageManager === 'yarn') {
// Don't run them in parallel (Promise.all), the package-manager doesn't handle it well.
yield (0, _pMapSeries().default)(capsules, /*#__PURE__*/function () {
var _ref = (0, _bluebird().coroutine)(function* (capsule) {
// TODO: remove this hack once harmony supports ownExtensionName
const componentId = capsule.component.id.toString();
const installProc = packageManager === 'npm' ? (0, _execa().default)('npm', ['install', '--no-package-lock'], {
cwd: capsule.wrkDir,
stdio: 'pipe'
}) : (0, _execa().default)('yarn', [], {
cwd: capsule.wrkDir,
stdio: 'pipe'
});
logPublisher.info(componentId, packageManager === 'npm' ? '$ npm install --no-package-lock' : '$ yarn'); // TODO: better
logPublisher.info(componentId, '');
installProc.stdout.on('data', d => logPublisher.info(componentId, d.toString()));
installProc.stderr.on('data', d => logPublisher.warn(componentId, d.toString()));
installProc.on('error', e => {
console.log('error:', e); // eslint-disable-line no-console
logPublisher.error(componentId, e);
});
yield installProc;
linkBitBinInCapsule(capsule);
_this.emitter.emit('capsuleInstalled', componentId);
});
return function (_x2) {
return _ref.apply(this, arguments);
};
}());
} else {
throw new Error(`unsupported package manager ${packageManager}`);
}
return null;
})();
}
runInstallInFolder(folder, opts = {}) {
var _this2 = this;
return (0, _bluebird().coroutine)(function* () {
// TODO: remove this hack once harmony supports ownExtensionName
const logPublisher = _this2.logger.createLogPublisher('packageManager');
const packageManager = opts.packageManager || _this2.packageManagerName;
if (packageManager === 'yarn') {
const child = (0, _execa().default)('yarn', [], {
cwd: folder,
stdio: 'pipe'
});
(0, _child_process().pipeOutput)(child);
yield child;
return null;
}
if (packageManager === 'npm') {
const child = (0, _execa().default)('npm', ['install'], {
cwd: folder,
stdio: 'pipe'
});
logPublisher.info(folder, '$ npm install');
logPublisher.info(folder, '');
yield new Promise((resolve, reject) => {
// @ts-ignore
child.stdout.on('data', d => logPublisher.info(folder, d.toString())); // @ts-ignore
child.stderr.on('data', d => logPublisher.warn(folder, d.toString()));
child.on('error', e => {
reject(e);
});
child.on('close', exitStatus => {
if (exitStatus) {
reject(new Error(`${folder}`));
} else {
resolve();
}
});
});
return null;
}
throw new Error(`unsupported package manager ${packageManager}`);
})();
}
}
exports.default = PackageManager;
function linkBitBinInCapsule(capsule) {
const bitBinPath = _path().default.join(capsule.wrkDir, './node_modules/bit-bin');
const getLocalBitBinPath = () => {
const pathOutsideNodeModules = _path().default.join(__dirname, '../..');
if (pathOutsideNodeModules.endsWith(`${_path().default.sep}dist`)) {
return pathOutsideNodeModules;
}
if (__dirname.includes('build-harmony')) {
// for bit-bin development, the cli extension is installed as a package in build-harmony directory
return _path().default.join(__dirname.split('build-harmony')[0], 'dist');
}
throw new Error('unable to link bit-bin to the capsule, the location of bit-bin is unknown');
};
const localBitBinPath = getLocalBitBinPath(); // if there are no deps, sometimes the node_modules folder is not created
// and we need it in order to perform the linking
try {
capsule.fs.mkdirSync('node_modules');
} catch (e) {} // fail silently - we only need to create it if it doesn't already exist
// we use fs directly here rather than the capsule.fs because there are some edge cases
// that the capusle fs does not deal with well (eg. identifying and deleting
// a symlink rather than the what the symlink links to)
_fsExtra().default.removeSync(bitBinPath);
(0, _createSymlinkOrCopy().default)(localBitBinPath, bitBinPath);
}
;