-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathwindows-admin.js
136 lines (125 loc) · 3.9 KB
/
windows-admin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'use strict';
const chalk = require('chalk');
class WindowsSymlinkChecker {
/**
*
* On Windows, users will have a much better experience if symlinks are enabled
* and usable. When queried, this object informs Windows users regarding
* improving their 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 user is an admin, the process needs to have been started with elevated privileges
* * if the user is not an admin, a specific setting needs to be enabled
* <= Windows 10
* * 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 https://cli.emberjs.com/release/appendix/windows/ for details.\n');
}
resolve({
windows: true,
elevated,
});
});
});
}
}
module.exports = WindowsSymlinkChecker;