UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

199 lines (165 loc) 7.66 kB
Object.defineProperty(exports, '__esModule', { value: true }); /* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var canFindFlow = _asyncToGenerator(function* (flowPath) { return (yield (0, (_commonsNodeWhich2 || _commonsNodeWhich()).default)(flowPath)) != null; } // `string | null` forces the presence of an explicit argument (`?string` allows undefined which // means the argument can be left off altogether. ); function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, 'next'); var callThrow = step.bind(null, 'throw'); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _lruCache2; function _lruCache() { return _lruCache2 = _interopRequireDefault(require('lru-cache')); } var _eventKit2; function _eventKit() { return _eventKit2 = require('event-kit'); } var _commonsNodeNuclideUri2; function _commonsNodeNuclideUri() { return _commonsNodeNuclideUri2 = _interopRequireDefault(require('../../commons-node/nuclideUri')); } var _commonsNodeWhich2; function _commonsNodeWhich() { return _commonsNodeWhich2 = _interopRequireDefault(require('../../commons-node/which')); } var _commonsNodeFsPromise2; function _commonsNodeFsPromise() { return _commonsNodeFsPromise2 = _interopRequireDefault(require('../../commons-node/fsPromise')); } // All the information needed to execute Flow in a given root. The path to the Flow binary we want // to use may vary per root -- for now, only if we are using the version of Flow from `flow-bin`. // The options also vary, right now only because they set the cwd to the current Flow root. var FlowExecInfoContainer = (function () { function FlowExecInfoContainer() { _classCallCheck(this, FlowExecInfoContainer); this._flowConfigDirCache = (0, (_lruCache2 || _lruCache()).default)({ max: 10, maxAge: 1000 * 30 }); // 30 seconds this._flowExecInfoCache = (0, (_lruCache2 || _lruCache()).default)({ max: 10, maxAge: 1000 * 30 }); // 30 seconds this._disposables = new (_eventKit2 || _eventKit()).CompositeDisposable(); this._observeSettings(); } _createClass(FlowExecInfoContainer, [{ key: 'dispose', value: function dispose() { this._disposables.dispose(); this._flowConfigDirCache.reset(); this._flowExecInfoCache.reset(); } // Returns null iff Flow cannot be found. }, { key: 'getFlowExecInfo', value: _asyncToGenerator(function* (root) { if (!this._flowExecInfoCache.has(root)) { var info = yield this._computeFlowExecInfo(root); this._flowExecInfoCache.set(root, info); } return this._flowExecInfoCache.get(root); }) }, { key: '_computeFlowExecInfo', value: _asyncToGenerator(function* (root) { var flowPath = yield this._getPathToFlow(root); if (flowPath == null) { return null; } return { pathToFlow: flowPath, execOptions: getFlowExecOptions(root) }; }) // Return the path we should use to execute Flow for the given root, or null if Flow cannot be // found. }, { key: '_getPathToFlow', value: _asyncToGenerator(function* (root) { var flowBinPath = yield this._getFlowBinPath(root); if (flowBinPath != null && (yield canFindFlow(flowBinPath))) { return flowBinPath; } // Pull this into a local on the off chance that the setting changes while we are doing the // check. var systemFlowPath = this._pathToFlow; if (yield canFindFlow(systemFlowPath)) { return systemFlowPath; } return null; }) }, { key: '_getFlowBinPath', value: _asyncToGenerator(function* (root) { if (root == null) { return null; } if (!this._canUseFlowBin) { return null; } return (_commonsNodeNuclideUri2 || _commonsNodeNuclideUri()).default.join(root, 'node_modules/.bin/flow'); }) }, { key: 'findFlowConfigDir', value: _asyncToGenerator(function* (localFile) { if (!this._flowConfigDirCache.has(localFile)) { var flowConfigDir = yield (_commonsNodeFsPromise2 || _commonsNodeFsPromise()).default.findNearestFile('.flowconfig', (_commonsNodeNuclideUri2 || _commonsNodeNuclideUri()).default.dirname(localFile)); this._flowConfigDirCache.set(localFile, flowConfigDir); } return this._flowConfigDirCache.get(localFile); }) }, { key: '_observeSettings', value: function _observeSettings() { var _this = this; if (global.atom == null) { this._pathToFlow = 'flow'; this._canUseFlowBin = false; } else { // $UPFixMe: This should use nuclide-features-config // Does not currently do so because this is an npm module that may run on the server. this._disposables.add(atom.config.observe('nuclide.nuclide-flow.pathToFlow', function (path) { _this._pathToFlow = path; _this._flowExecInfoCache.reset(); }), atom.config.observe('nuclide.nuclide-flow.canUseFlowBin', function (canUseFlowBin) { _this._canUseFlowBin = canUseFlowBin; _this._flowExecInfoCache.reset(); })); } } }]); return FlowExecInfoContainer; })(); exports.FlowExecInfoContainer = FlowExecInfoContainer; function getFlowExecOptions(root) { return { cwd: root, env: _extends({ // Allows backtrace to be printed: // http://caml.inria.fr/pub/docs/manual-ocaml/runtime.html#sec279 OCAMLRUNPARAM: 'b' }, process.env) }; } // Map from file path to the closest ancestor directory containing a .flowconfig file (the file's // Flow root) // Map from Flow root directory (or null for "no root" e.g. files outside of a Flow root, or // unsaved files. Useful for outline view) to FlowExecInfo. A null value means that the Flow // binary cannot be found for that root. It is possible for Flow to be available in some roots but // not others because we will support root-specific installations of flow-bin. // Put this after so that if the user already has something set for OCAMLRUNPARAM we use // that instead. They probably know what they're doing.