UNPKG

ember-cli

Version:

Command line tool for developing ambitious ember.js apps

138 lines (126 loc) 4.04 kB
'use strict'; const Promise = require('rsvp').Promise; const chalk = require('chalk'); class WindowsSymlinkChecker { /** * * On windows users will have a much better experience if symlinks are enabled * an usable. This object when queried informs windows users, if they can * improve there build performance, and how. * * > Windows vista: nothing we can really do, so we fall back to junctions for folders + copying of files * <= Windows vista: symlinks are available but using them is somewhat tricky * * if the users is an admin, the process needed to have been started with elevated privs * * if the user is not an admin, a specific setting needs to be enabled * <= Windows 10 Insiders build 14972 * * if developer mode is enabled, symlinks "just work" * * https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10 * * ```js * let checker = WindowsSymlinkChecker; * let { * windows, * elevated * } = await = checker.checkIfSymlinksNeedToBeEnabled(); // aslso emits helpful warnings * ``` * * @public * @class WindowsSymlinkChecker */ constructor(ui, isWindows, canSymlink, exec) { this.ui = ui; this.isWindows = isWindows; this.canSymlink = canSymlink; this.exec = exec; } /** * * if not windows, will fulfill with: * `{ windows: false, elevated: null)` * * if windows, and elevated will fulfill with: * `{ windows: false, elevated: true)` * * if windows, and is NOT elevated will fulfill with: * `{ windows: false, elevated: false)` * * will include heplful warning, so that users know (if possible) how to * achieve better windows build performance * * @public * @method checkIfSymlinksNeedToBeEnabled * @return {Promise<Object>} Object describing whether we're on windows and if admin rights exist */ static checkIfSymlinksNeedToBeEnabled(ui) { return this._setup(ui).checkIfSymlinksNeedToBeEnabled(); } /** * sets up a WindowsSymlinkChecker * * providing it with defaults for: * * * if we are on windows * * if we can symlink * * a reference to exec * * @private * @method _setup * @param UI {UI} * @return {WindowsSymlinkChecker} */ static _setup(ui) { const exec = require('child_process').exec; const symlinkOrCopy = require('symlink-or-copy'); return new WindowsSymlinkChecker(ui, /^win/.test(process.platform), symlinkOrCopy.canSymlink, exec); } /** * @public * @method checkIfSymlinksNeedToBeEnabled * @return {Promise<Object>} Object describing whether we're on windows and if admin rights exist */ checkIfSymlinksNeedToBeEnabled() { return new Promise(resolve => { if (!this.isWindows) { resolve({ windows: false, elevated: null, }); } else if (this.canSymlink) { resolve({ windows: true, elevated: null, }); } else { resolve(this._checkForElevatedRights(this.ui)); } }); } /** * * Uses the eon-old command NET SESSION to determine whether or not the * current user has elevated rights (think sudo, but Windows). * * @private * @method _checkForElevatedRights * @param {Object} ui - ui object used to call writeLine(); * @return {Object} Object describing whether we're on windows and if admin rights exist */ _checkForElevatedRights() { let ui = this.ui; let exec = this.exec; return new Promise(resolve => { exec('NET SESSION', (error, stdout, stderr) => { let elevated = !stderr || stderr.length === 0; if (!elevated) { ui.writeLine(chalk.yellow('\nRunning without permission to symlink will degrade build performance.')); ui.writeLine('See http://ember-cli.com/user-guide/#windows for details.\n'); } resolve({ windows: true, elevated, }); }); }); } } module.exports = WindowsSymlinkChecker;