UNPKG

bulk-decaffeinate

Version:

Run decaffeinate and related operations on a whole codebase, or just part of one.

1,853 lines (1,521 loc) 129 kB
import 'babel-polyfill'; import commander from 'commander'; import { exists, readFile, readdir, stat, unlink, writeFile } from 'mz/fs'; import { basename, dirname, extname, join, relative, resolve } from 'path'; import git from 'simple-git/promise'; import executable from 'executable'; import { exec } from 'mz/child_process'; import moment from 'moment'; import readline from 'mz/readline'; import requireUncached from 'require-uncached'; import { spawn } from 'child_process'; import { copy, move, readFile as readFile$1, unlink as unlink$1, writeFile as writeFile$1 } from 'fs-promise'; import zlib from 'zlib'; import opn from 'opn'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var jsx = function () { var REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7; return function createRawReactElement(type, props, key, children) { var defaultProps = type && type.defaultProps; var childrenLength = arguments.length - 3; if (!props && childrenLength !== 0) { props = {}; } if (props && defaultProps) { for (var propName in defaultProps) { if (props[propName] === void 0) { props[propName] = defaultProps[propName]; } } } else if (!props) { props = defaultProps || {}; } if (childrenLength === 1) { props.children = children; } else if (childrenLength > 1) { var childArray = Array(childrenLength); for (var i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 3]; } props.children = childArray; } return { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key === undefined ? null : '' + key, ref: null, props: props, _owner: null }; }; }(); var asyncIterator = function (iterable) { if (typeof Symbol === "function") { if (Symbol.asyncIterator) { var method = iterable[Symbol.asyncIterator]; if (method != null) return method.call(iterable); } if (Symbol.iterator) { return iterable[Symbol.iterator](); } } throw new TypeError("Object is not async iterable"); }; var asyncGenerator = function () { function AwaitValue(value) { this.value = value; } function AsyncGenerator(gen) { var front, back; function send(key, arg) { return new Promise(function (resolve$$1, reject) { var request = { key: key, arg: arg, resolve: resolve$$1, reject: reject, next: null }; if (back) { back = back.next = request; } else { front = back = request; resume(key, arg); } }); } function resume(key, arg) { try { var result = gen[key](arg); var value = result.value; if (value instanceof AwaitValue) { Promise.resolve(value.value).then(function (arg) { resume("next", arg); }, function (arg) { resume("throw", arg); }); } else { settle(result.done ? "return" : "normal", result.value); } } catch (err) { settle("throw", err); } } function settle(type, value) { switch (type) { case "return": front.resolve({ value: value, done: true }); break; case "throw": front.reject(value); break; default: front.resolve({ value: value, done: false }); break; } front = front.next; if (front) { resume(front.key, front.arg); } else { back = null; } } this._invoke = send; if (typeof gen.return !== "function") { this.return = undefined; } } if (typeof Symbol === "function" && Symbol.asyncIterator) { AsyncGenerator.prototype[Symbol.asyncIterator] = function () { return this; }; } AsyncGenerator.prototype.next = function (arg) { return this._invoke("next", arg); }; AsyncGenerator.prototype.throw = function (arg) { return this._invoke("throw", arg); }; AsyncGenerator.prototype.return = function (arg) { return this._invoke("return", arg); }; return { wrap: function (fn) { return function () { return new AsyncGenerator(fn.apply(this, arguments)); }; }, await: function (value) { return new AwaitValue(value); } }; }(); var asyncGeneratorDelegate = function (inner, awaitWrap) { var iter = {}, waiting = false; function pump(key, value) { waiting = true; value = new Promise(function (resolve$$1) { resolve$$1(inner[key](value)); }); return { done: false, value: awaitWrap(value) }; } if (typeof Symbol === "function" && Symbol.iterator) { iter[Symbol.iterator] = function () { return this; }; } iter.next = function (value) { if (waiting) { waiting = false; return value; } return pump("next", value); }; if (typeof inner.throw === "function") { iter.throw = function (value) { if (waiting) { waiting = false; throw value; } return pump("throw", value); }; } if (typeof inner.return === "function") { iter.return = function (value) { return pump("return", value); }; } return iter; }; var asyncToGenerator = function (fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve$$1, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve$$1(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; 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 defineEnumerableProperties = function (obj, descs) { for (var key in descs) { var desc = descs[key]; desc.configurable = desc.enumerable = true; if ("value" in desc) desc.writable = true; Object.defineProperty(obj, key, desc); } return obj; }; var defaults = function (obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }; var defineProperty = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; 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 get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var _instanceof = function (left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return right[Symbol.hasInstance](left); } else { return left instanceof right; } }; var interopRequireDefault = function (obj) { return obj && obj.__esModule ? obj : { default: obj }; }; var interopRequireWildcard = function (obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }; var newArrowCheck = function (innerThis, boundThis) { if (innerThis !== boundThis) { throw new TypeError("Cannot instantiate an arrow function"); } }; var objectDestructuringEmpty = function (obj) { if (obj == null) throw new TypeError("Cannot destructure undefined"); }; var objectWithoutProperties = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; var selfGlobal = typeof global === "undefined" ? self : global; var set = function set(object, property, value, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent !== null) { set(parent, property, value, receiver); } } else if ("value" in desc && desc.writable) { desc.value = value; } else { var setter = desc.set; if (setter !== undefined) { setter.call(receiver, value); } } return value; }; var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var slicedToArrayLoose = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; var taggedTemplateLiteral = function (strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }; var taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; }; var temporalRef = function (val, name, undef) { if (val === undef) { throw new ReferenceError(name + " is not defined - temporal dead zone"); } else { return val; } }; var temporalUndefined = {}; var toArray = function (arr) { return Array.isArray(arr) ? arr : Array.from(arr); }; var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; var babelHelpers$1 = Object.freeze({ jsx: jsx, asyncIterator: asyncIterator, asyncGenerator: asyncGenerator, asyncGeneratorDelegate: asyncGeneratorDelegate, asyncToGenerator: asyncToGenerator, classCallCheck: classCallCheck, createClass: createClass, defineEnumerableProperties: defineEnumerableProperties, defaults: defaults, defineProperty: defineProperty, get: get, inherits: inherits, interopRequireDefault: interopRequireDefault, interopRequireWildcard: interopRequireWildcard, newArrowCheck: newArrowCheck, objectDestructuringEmpty: objectDestructuringEmpty, objectWithoutProperties: objectWithoutProperties, possibleConstructorReturn: possibleConstructorReturn, selfGlobal: selfGlobal, set: set, slicedToArray: slicedToArray, slicedToArrayLoose: slicedToArrayLoose, taggedTemplateLiteral: taggedTemplateLiteral, taggedTemplateLiteralLoose: taggedTemplateLiteralLoose, temporalRef: temporalRef, temporalUndefined: temporalUndefined, toArray: toArray, toConsumableArray: toConsumableArray, typeof: _typeof, extends: _extends, instanceof: _instanceof }); var PREFIX = 'bulk-decaffeinate CLIError: '; /** * Exception class for a nice-looking error. * * Apparently async/await propagation doesn't preserve the exception, so to work * around this, we put a special prefix at the start of CLI errors and format * the error without a stack trace if the message starts with that prefix. */ var CLIError = function (_Error) { inherits(CLIError, _Error); function CLIError(message) { classCallCheck(this, CLIError); return possibleConstructorReturn(this, (CLIError.__proto__ || Object.getPrototypeOf(CLIError)).call(this, PREFIX + message)); } createClass(CLIError, null, [{ key: 'formatError', value: function formatError(e) { if (!e) { return e; } if (e.message.startsWith(PREFIX)) { return e.message.substring(PREFIX.length); } else { return e; } } }]); return CLIError; }(Error); /** * Read a list of files from a file and return it. Verify that all files * actually exist. */ var getFilesFromPathFile$1 = (function getFilesFromPathFile(filePath) { var fileContents, lines, resultLines, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line; return regeneratorRuntime.async(function getFilesFromPathFile$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(readFile(filePath)); case 2: fileContents = _context.sent; lines = fileContents.toString().split('\n'); resultLines = []; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 8; _iterator = lines[Symbol.iterator](); case 10: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context.next = 23; break; } line = _step.value; line = line.trim(); if (!(line.length === 0 || line.startsWith('#'))) { _context.next = 15; break; } return _context.abrupt('continue', 20); case 15: _context.next = 17; return regeneratorRuntime.awrap(exists(line)); case 17: if (_context.sent) { _context.next = 19; break; } throw new CLIError('The file "' + line + '" did not exist.'); case 19: resultLines.push(line); case 20: _iteratorNormalCompletion = true; _context.next = 10; break; case 23: _context.next = 29; break; case 25: _context.prev = 25; _context.t0 = _context['catch'](8); _didIteratorError = true; _iteratorError = _context.t0; case 29: _context.prev = 29; _context.prev = 30; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 32: _context.prev = 32; if (!_didIteratorError) { _context.next = 35; break; } throw _iteratorError; case 35: return _context.finish(32); case 36: return _context.finish(29); case 37: return _context.abrupt('return', resultLines); case 38: case 'end': return _context.stop(); } } }, null, this, [[8, 25, 29, 37], [30,, 32, 36]]); }); /** * Recursively discover any matching files in the current directory, ignoring * things like node_modules and .git. */ var getFilesUnderPath$1 = (function getFilesUnderPath(dirPath, asyncPathPredicate) { var resultFiles, children, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, child, childPath, subdirCoffeeFiles; return regeneratorRuntime.async(function getFilesUnderPath$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: resultFiles = []; _context.next = 3; return regeneratorRuntime.awrap(readdir(dirPath)); case 3: children = _context.sent; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 7; _iterator = children[Symbol.iterator](); case 9: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context.next = 30; break; } child = _step.value; if (!['node_modules', '.git'].includes(child)) { _context.next = 13; break; } return _context.abrupt('continue', 27); case 13: childPath = resolve(join(dirPath, child)); _context.next = 16; return regeneratorRuntime.awrap(stat(childPath)); case 16: if (!_context.sent.isDirectory()) { _context.next = 23; break; } _context.next = 19; return regeneratorRuntime.awrap(getFilesUnderPath(childPath, asyncPathPredicate)); case 19: subdirCoffeeFiles = _context.sent; resultFiles.push.apply(resultFiles, toConsumableArray(subdirCoffeeFiles)); _context.next = 27; break; case 23: _context.next = 25; return regeneratorRuntime.awrap(asyncPathPredicate(childPath)); case 25: if (!_context.sent) { _context.next = 27; break; } resultFiles.push(childPath); case 27: _iteratorNormalCompletion = true; _context.next = 9; break; case 30: _context.next = 36; break; case 32: _context.prev = 32; _context.t0 = _context['catch'](7); _didIteratorError = true; _iteratorError = _context.t0; case 36: _context.prev = 36; _context.prev = 37; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 39: _context.prev = 39; if (!_didIteratorError) { _context.next = 42; break; } throw _iteratorError; case 42: return _context.finish(39); case 43: return _context.finish(36); case 44: return _context.abrupt('return', resultFiles); case 45: case 'end': return _context.stop(); } } }, null, this, [[7, 32, 36, 44], [37,, 39, 43]]); }); var getTrackedFiles$1 = (function getTrackedFiles() { var stdout; return regeneratorRuntime.async(function getTrackedFiles$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(git().raw(['ls-files'])); case 2: stdout = _context.sent; return _context.abrupt('return', new Set(stdout.split('\n').map(function (s) { return s.trim(); }).map(function (s) { return resolve(s); }))); case 4: case 'end': return _context.stop(); } } }, null, this); }); var COFFEE_FILE_RECOGNIZER = { extensions: ['.coffee', '.litcoffee', '.coffee.md'], shebangSuffix: 'coffee' }; var JS_FILE_RECOGNIZER = { extensions: ['.js'], shebangSuffix: 'node' }; function extensionFor(path$$1) { if (path$$1.endsWith('.coffee.md')) { return '.coffee.md'; } return extname(path$$1); } function basePathFor(path$$1) { var extension = extensionFor(path$$1); return join(dirname(path$$1), basename(path$$1, extension)); } function shouldConvertFile(path$$1, recognizer, trackedFiles) { return regeneratorRuntime.async(function shouldConvertFile$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.t0 = !hasRecognizedExtension(path$$1, recognizer); if (!_context.t0) { _context.next = 5; break; } _context.next = 4; return regeneratorRuntime.awrap(isExecutableScript(path$$1, recognizer)); case 4: _context.t0 = !_context.sent; case 5: if (!_context.t0) { _context.next = 7; break; } return _context.abrupt('return', false); case 7: if (trackedFiles.has(path$$1)) { _context.next = 10; break; } console.log('Warning: Skipping ' + path$$1 + ' because the file is not tracked in the git repo.'); return _context.abrupt('return', false); case 10: return _context.abrupt('return', true); case 11: case 'end': return _context.stop(); } } }, null, this); } function hasRecognizedExtension(path$$1, recognizer) { return recognizer.extensions.some(function (ext) { return path$$1.endsWith(ext) && !path$$1.endsWith('.original' + ext); }); } function isExecutableScript(path$$1, recognizer) { var contents, firstLine; return regeneratorRuntime.async(function isExecutableScript$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.t0 = isExtensionless(path$$1); if (!_context2.t0) { _context2.next = 5; break; } _context2.next = 4; return regeneratorRuntime.awrap(executable(path$$1)); case 4: _context2.t0 = _context2.sent; case 5: if (!_context2.t0) { _context2.next = 12; break; } _context2.next = 8; return regeneratorRuntime.awrap(readFile(path$$1)); case 8: contents = _context2.sent; firstLine = contents.toString().split('\n')[0]; if (!(firstLine.startsWith('#!') && firstLine.includes(recognizer.shebangSuffix))) { _context2.next = 12; break; } return _context2.abrupt('return', true); case 12: return _context2.abrupt('return', false); case 13: case 'end': return _context2.stop(); } } }, null, this); } function isExtensionless(path$$1) { return extensionFor(path$$1) === ''; } function backupPathFor(path$$1) { var extension = extensionFor(path$$1); var basePath = basePathFor(path$$1); return basePath + '.original' + extension; } /** * The resulting path where we should send the given input file. Note that when * the input file is an extensionless script, we prefer to keep it extensionless * (and decaffeinate handles the shebang line). */ function jsPathFor(path$$1, config) { if (config.customNames[path$$1]) { return config.customNames[path$$1]; } if (isExtensionless(path$$1)) { return path$$1; } else { return basePathFor(path$$1) + '.' + config.outputFileExtension; } } /** * The file generated by decaffeinate for the input file with this name. */ function decaffeinateOutPathFor(path$$1) { return basePathFor(path$$1) + '.js'; } function isLiterate(path$$1) { return path$$1.endsWith('.litcoffee') || path$$1.endsWith('.coffee.md'); } /** * Get the files that we should process based on the config. "recognizer" should * be an object describing the files to auto-recognize, e.g. * COFFEE_FILE_RECOGNIZER. */ var getFilesToProcess$1 = (function getFilesToProcess(config, recognizer) { var filesToProcess; return regeneratorRuntime.async(function getFilesToProcess$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(resolveFilesToProcess(config, recognizer)); case 2: filesToProcess = _context.sent; filesToProcess = resolveFileFilter(filesToProcess, config); _context.next = 6; return regeneratorRuntime.awrap(validateFilesToProcess(filesToProcess, config)); case 6: return _context.abrupt('return', filesToProcess); case 7: case 'end': return _context.stop(); } } }, null, this); }); function resolveFilesToProcess(config, recognizer) { var _this = this; var filesToProcess, pathFile, searchDirectory, trackedFiles, files, _files, _files2, _files3, _trackedFiles; return regeneratorRuntime.async(function resolveFilesToProcess$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: filesToProcess = config.filesToProcess, pathFile = config.pathFile, searchDirectory = config.searchDirectory; if (!(!filesToProcess && !pathFile && !searchDirectory)) { _context4.next = 8; break; } _context4.next = 4; return regeneratorRuntime.awrap(getTrackedFiles$1()); case 4: trackedFiles = _context4.sent; _context4.next = 7; return regeneratorRuntime.awrap(getFilesUnderPath$1('.', function _callee(path$$1) { return regeneratorRuntime.async(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return regeneratorRuntime.awrap(shouldConvertFile(path$$1, recognizer, trackedFiles)); case 2: return _context2.abrupt('return', _context2.sent); case 3: case 'end': return _context2.stop(); } } }, null, _this); })); case 7: return _context4.abrupt('return', _context4.sent); case 8: files = []; if (filesToProcess) { (_files = files).push.apply(_files, toConsumableArray(filesToProcess)); } if (!pathFile) { _context4.next = 19; break; } _context4.t0 = (_files2 = files).push; _context4.t1 = _files2; _context4.t2 = babelHelpers$1; _context4.next = 16; return regeneratorRuntime.awrap(getFilesFromPathFile$1(pathFile)); case 16: _context4.t3 = _context4.sent; _context4.t4 = _context4.t2.toConsumableArray.call(_context4.t2, _context4.t3); _context4.t0.apply.call(_context4.t0, _context4.t1, _context4.t4); case 19: if (!searchDirectory) { _context4.next = 31; break; } _context4.next = 22; return regeneratorRuntime.awrap(getTrackedFiles$1()); case 22: _trackedFiles = _context4.sent; _context4.t5 = (_files3 = files).push; _context4.t6 = _files3; _context4.t7 = babelHelpers$1; _context4.next = 28; return regeneratorRuntime.awrap(getFilesUnderPath$1(searchDirectory, function _callee2(path$$1) { return regeneratorRuntime.async(function _callee2$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return regeneratorRuntime.awrap(shouldConvertFile(path$$1, recognizer, _trackedFiles)); case 2: return _context3.abrupt('return', _context3.sent); case 3: case 'end': return _context3.stop(); } } }, null, _this); })); case 28: _context4.t8 = _context4.sent; _context4.t9 = _context4.t7.toConsumableArray.call(_context4.t7, _context4.t8); _context4.t5.apply.call(_context4.t5, _context4.t6, _context4.t9); case 31: files = files.map(function (path$$1) { return resolve(path$$1); }); files = Array.from(new Set(files)).sort(); return _context4.abrupt('return', files); case 34: case 'end': return _context4.stop(); } } }, null, this); } function resolveFileFilter(filesToProcess, config) { if (!config.fileFilterFn) { return filesToProcess; } return filesToProcess.filter(function (path$$1) { return config.fileFilterFn(path$$1); }); } function validateFilesToProcess(filesToProcess, config) { var trackedFiles, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, path$$1, jsPath; return regeneratorRuntime.async(function validateFilesToProcess$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: _context5.next = 2; return regeneratorRuntime.awrap(getTrackedFiles$1()); case 2: trackedFiles = _context5.sent; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context5.prev = 6; _iterator = filesToProcess[Symbol.iterator](); case 8: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context5.next = 23; break; } path$$1 = _step.value; if (trackedFiles.has(path$$1)) { _context5.next = 12; break; } throw new CLIError('The file ' + path$$1 + ' is not tracked in the git repo.'); case 12: jsPath = jsPathFor(path$$1, config); _context5.t0 = jsPath !== path$$1; if (!_context5.t0) { _context5.next = 18; break; } _context5.next = 17; return regeneratorRuntime.awrap(exists(jsPath)); case 17: _context5.t0 = _context5.sent; case 18: if (!_context5.t0) { _context5.next = 20; break; } throw new CLIError('The file ' + jsPath + ' already exists.'); case 20: _iteratorNormalCompletion = true; _context5.next = 8; break; case 23: _context5.next = 29; break; case 25: _context5.prev = 25; _context5.t1 = _context5['catch'](6); _didIteratorError = true; _iteratorError = _context5.t1; case 29: _context5.prev = 29; _context5.prev = 30; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 32: _context5.prev = 32; if (!_didIteratorError) { _context5.next = 35; break; } throw _iteratorError; case 35: return _context5.finish(32); case 36: return _context5.finish(29); case 37: case 'end': return _context5.stop(); } } }, null, this, [[6, 25, 29, 37], [30,, 32, 36]]); } function makeCLIFn(commandByPath) { return function _callee(path$$1) { return regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.prev = 0; _context.next = 3; return regeneratorRuntime.awrap(exec(commandByPath(path$$1), { maxBuffer: 5 * 1024 * 1024 })); case 3: return _context.abrupt('return', { path: path$$1, error: null }); case 6: _context.prev = 6; _context.t0 = _context['catch'](0); return _context.abrupt('return', { path: path$$1, error: _context.t0.message }); case 9: case 'end': return _context.stop(); } } }, null, this, [[0, 6]]); }; } function makeDecaffeinateVerifyFn(config) { var decaffeinatePath = config.decaffeinatePath, decaffeinateArgs = config.decaffeinateArgs; return makeCLIFn(function (path$$1) { var literateFlag = isLiterate(path$$1) ? '--literate' : ''; return decaffeinatePath + ' ' + literateFlag + ' ' + decaffeinateArgs.join(' ') + ' < ' + path$$1; }); } /** * Run the given one-argument async function on an array of arguments, keeping a * logical worker pool to increase throughput without overloading the system. * * Results are provided as they come in with the result handler. Results look * like {index: 3, result: "Hello"}. This can be used e.g. to update a progress * bar. * * An array of all results is returned at the end. */ var runInParallel$1 = (function runInParallel(args, asyncFn, numConcurrentProcesses, resultHandler) { var _this = this; var results, activePromises, handleResult, _loop, i; return regeneratorRuntime.async(function runInParallel$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: results = []; activePromises = {}; handleResult = function handleResult(_ref) { var index = _ref.index, result = _ref.result; results[index] = result; delete activePromises[index]; resultHandler({ index: index, result: result }); }; _loop = function _callee2(i) { var arg; return regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: arg = args[i]; activePromises[i] = function _callee() { return regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.t0 = i; _context.next = 3; return regeneratorRuntime.awrap(asyncFn(arg)); case 3: _context.t1 = _context.sent; return _context.abrupt("return", { index: _context.t0, result: _context.t1 }); case 5: case "end": return _context.stop(); } } }, null, this); }(); if (!(Object.keys(activePromises).length >= numConcurrentProcesses)) { _context2.next = 8; break; } _context2.t0 = handleResult; _context2.next = 6; return regeneratorRuntime.awrap(Promise.race(Object.values(activePromises))); case 6: _context2.t1 = _context2.sent; (0, _context2.t0)(_context2.t1); case 8: case "end": return _context2.stop(); } } }, null, _this); }; i = 0; case 5: if (!(i < args.length)) { _context3.next = 11; break; } _context3.next = 8; return regeneratorRuntime.awrap(_loop(i)); case 8: i++; _context3.next = 5; break; case 11: if (!(Object.keys(activePromises).length > 0)) { _context3.next = 19; break; } _context3.t0 = handleResult; _context3.next = 15; return regeneratorRuntime.awrap(Promise.race(Object.values(activePromises))); case 15: _context3.t1 = _context3.sent; (0, _context3.t0)(_context3.t1); _context3.next = 11; break; case 19: return _context3.abrupt("return", results); case 20: case "end": return _context3.stop(); } } }, null, this); }); function pluralize(num, noun) { return num === 1 ? num + " " + noun : num + " " + noun + "s"; } /** * Copied from moment-precise-range, which is MIT-licensed, with minor cleanups * to appease ESLint and remove an unused option. * * https://github.com/codebox/moment-precise-range * * The original plugin worked by modifying the global moment installation, which * caused problems if multiple moment instances were installed, so this should * avoid that. */ var STRINGS = { nodiff: '', year: 'year', years: 'years', month: 'month', months: 'months', day: 'day', days: 'days', hour: 'hour', hours: 'hours', minute: 'minute', minutes: 'minutes', second: 'second', seconds: 'seconds', delimiter: ' ' }; function pluralize$1(num, word) { return num + ' ' + STRINGS[word + (num === 1 ? '' : 's')]; } function buildStringFromValues(yDiff, mDiff, dDiff, hourDiff, minDiff, secDiff) { var result = []; if (yDiff) { result.push(pluralize$1(yDiff, 'year')); } if (mDiff) { result.push(pluralize$1(mDiff, 'month')); } if (dDiff) { result.push(pluralize$1(dDiff, 'day')); } if (hourDiff) { result.push(pluralize$1(hourDiff, 'hour')); } if (minDiff) { result.push(pluralize$1(minDiff, 'minute')); } if (secDiff) { result.push(pluralize$1(secDiff, 'second')); } return result.join(STRINGS.delimiter); } function momentPreciseDiff(m1, m2) { m1.add(m2.utcOffset() - m1.utcOffset(), 'minutes'); // shift timezone of m1 to m2 if (m1.isSame(m2)) { return STRINGS.nodiff; } if (m1.isAfter(m2)) { var tmp = m1; m1 = m2; m2 = tmp; } var yDiff = m2.year() - m1.year(); var mDiff = m2.month() - m1.month(); var dDiff = m2.date() - m1.date(); var hourDiff = m2.hour() - m1.hour(); var minDiff = m2.minute() - m1.minute(); var secDiff = m2.second() - m1.second(); if (secDiff < 0) { secDiff = 60 + secDiff; minDiff--; } if (minDiff < 0) { minDiff = 60 + minDiff; hourDiff--; } if (hourDiff < 0) { hourDiff = 24 + hourDiff; dDiff--; } if (dDiff < 0) { var daysInLastFullMonth = moment(m2.year() + '-' + (m2.month() + 1), 'YYYY-MM').subtract(1, 'M').daysInMonth(); if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03 dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth); } else { dDiff = daysInLastFullMonth + dDiff; } mDiff--; } if (mDiff < 0) { mDiff = 12 + mDiff; yDiff--; } return buildStringFromValues(yDiff, mDiff, dDiff, hourDiff, minDiff, secDiff); } /** * Run the given command in parallel, showing a progress bar of results. * * The provided async function should return an object that at least contains * a field called "error" that is truthy if there was a problem, but may contain * any other fields. */ var runWithProgressBar$1 = (function runWithProgressBar(config, description, files, asyncFn) { var _ref = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}, runInSeries = _ref.runInSeries, allowFailures = _ref.allowFailures; var numProcessed, numFailures, numTotal, startTime, numConcurrentProcesses, results, endTime, diffStr; return regeneratorRuntime.async(function runWithProgressBar$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: numProcessed = 0; numFailures = 0; numTotal = files.length; startTime = moment(); numConcurrentProcesses = runInSeries ? 1 : config.numWorkers; console.log(description + ' (' + pluralize(numConcurrentProcesses, 'worker') + ')'); results = void 0; _context.prev = 7; _context.next = 10; return regeneratorRuntime.awrap(runInParallel$1(files, asyncFn, numConcurrentProcesses, function (_ref2) { var result = _ref2.result; if (result && result.error) { if (!allowFailures) { throw new CLIError('Error:\n' + result.error); } numFailures++; } numProcessed++; var errorString = numFailures === 0 ? '' : ' (' + pluralize(numFailures, 'failure') + ' so far)'; process.stdout.write('\r' + numProcessed + '/' + numTotal + errorString); })); case 10: results = _context.sent; case 11: _context.prev = 11; process.stdout.write('\n'); endTime = moment(); diffStr = momentPreciseDiff(startTime, endTime) || '0 seconds'; console.log('Finished in ' + diffStr + ' (Time: ' + moment().format() + ')'); return _context.finish(11); case 17: return _context.abrupt('return', results); case 18: case 'end': return _context.stop(); } } }, null, this, [[7,, 11, 17]]); }); var check$1 = (function check(config) { var filesToProcess, decaffeinateResults; return regeneratorRuntime.async(function check$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(getFilesToProcess$1(config, COFFEE_FILE_RECOGNIZER)); case 2: filesToProcess = _context.sent; _context.next = 5; return regeneratorRuntime.awrap(runWithProgressBar$1(config, 'Doing a dry run of decaffeinate on ' + pluralize(filesToProcess.length, 'file') + '...', filesToProcess, makeDecaffeinateVerifyFn(config), { allowFailures: true })); case 5: decaffeinateResults = _context.sent; _context.next = 8; return regeneratorRuntime.awrap(printResults(decaffeinateResults)); case 8: case 'end': return _context.stop(); } } }, null, this); }); function printResults(results) { var errorResults, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, successPaths; return regeneratorRuntime.async(function printResults$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: errorResults = results.filter(function (r) { return r.error !== null; }); if (!(errorResults.length === 0)) { _context2.next = 6; break; } console.log('All checks succeeded! decaffeinate can convert all ' + pluralize(results.length, 'file') + '.'); console.log('Run "bulk-decaffeinate convert" to convert the files to JavaScript.'); _context2.next = 37; break; case 6: console.log(pluralize(errorResults.length, 'file') + ' failed to convert:'); _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context2.prev = 10; for (_iterator = errorResults[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { result = _step.value; console.log(result.path); } _context2.next = 18; break; case 14: _context2.prev = 14; _context2.t0 = _context2['catch'](10); _didIteratorError = true; _iteratorError = _context2.t0; case 18: _context2.prev = 18; _context2.prev = 19; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 21: _context2.prev = 21; if (!_didIteratorError) { _context2.next = 24; break; } throw _iteratorError; case 24: return _context2.finish(21); case 25: return _context2.finish(18); case 26: successPaths = results.filter(function (r) { return r.error === null; }).map(function (r) { return r.path; }); console.log(); _context2.next = 30; return regeneratorRuntime.awrap(writeFile('decaffeinate-errors.log', getVerboseErrors(results))); case 30: _context2.next = 32; return regeneratorRuntime.awrap(writeFile('decaffeinate-results.json', JSON.stringify(results, null, 2))); case 32: _context2.next = 34; return regeneratorRuntime.awrap(writeFile('decaffeinate-successful-files.txt', successPaths.join('\n'))); case 34: console.log('Wrote decaffeinate-errors.log and decaffeinate-results.json with more detailed info.'); console.log('To open failures in the online repl, run "bulk-decaffeinate view-errors".'); console.log('To convert the successful files, run "bulk-decaffeinate convert -p decaffeinate-successful-files.txt".'); case 37: case 'end': return _context2.stop(); } } }, null, this, [[10, 14, 18, 26], [19,, 21, 25]]); } function getVerboseErrors(results) { var errorMessages = []; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = results[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _step2$value = _step2.value, path$$1 = _step2$value.path, error = _step2$value.error; if (error) { errorMessages.push('===== ' + path$$1); errorMessages.push(getStdout(error)); } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return errorMessages.join('\n'); } function getStdout(message) { var matchString = '\nstdin: '; if (message.indexOf(matchString) !== -1) { return message.substring(message.indexOf(matchString) + matchString.length); } else { return message.substring(message.indexOf('\n') + 1); } } var clean$1 = (function clean() { var filesToDelete, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, path$$1; return regeneratorRuntime.async(function clean$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(getFilesUnderPath$1('.', function (p) { return basename(p).includes('.original'); })); case 2: filesToDelete = _context.sent; if (!(filesToDelete.length === 0)) { _context.next = 6; break; } console.log('No .original files were found.'); return _context.abrupt('return');