|
1 | 1 | import * as child_process from 'child_process';
|
2 | 2 | import {blue, yellow} from 'chalk';
|
| 3 | +import {Subject, Observable} from 'rxjs'; |
3 | 4 | import {getGlobalVariable} from './env';
|
4 | 5 | import {rimraf} from './fs';
|
5 | 6 | import {wait} from './utils';
|
@@ -91,6 +92,11 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise<Proce
|
91 | 92 | resolve({ stdout, stderr });
|
92 | 93 | }
|
93 | 94 | });
|
| 95 | + childProcess.stderr.on('data', (data: Buffer) => { |
| 96 | + if (data.toString().match(options.waitForMatch)) { |
| 97 | + resolve({ stdout, stderr }); |
| 98 | + } |
| 99 | + }); |
94 | 100 | }
|
95 | 101 | });
|
96 | 102 | }
|
@@ -140,25 +146,27 @@ export function silentExec(cmd: string, ...args: string[]) {
|
140 | 146 | }
|
141 | 147 |
|
142 | 148 | export function execAndWaitForOutputToMatch(cmd: string, args: string[], match: RegExp) {
|
143 |
| - let maybeWait = Promise.resolve(); |
144 | 149 | if (cmd === 'ng' && args[0] === 'serve') {
|
145 |
| - // Webpack watcher can rebuild a few times due to files changes that happened just before the |
146 |
| - // build (e.g. `git clean`), so we wait here. |
147 |
| - maybeWait = wait(5000); |
148 |
| - } |
149 |
| - return maybeWait.then(() => _exec({ waitForMatch: match }, cmd, args)); |
150 |
| -} |
151 |
| - |
152 |
| -export function silentExecAndWaitForOutputToMatch(cmd: string, args: string[], match: RegExp) { |
153 |
| - let maybeWait = Promise.resolve(); |
154 |
| - if (cmd === 'ng' && args[0] === 'serve') { |
155 |
| - // See execAndWaitForOutputToMatch for why the wait. |
156 |
| - maybeWait = wait(5000); |
| 150 | + // Accept matches up to 20 times after the initial match. |
| 151 | + // Useful because the Webpack watcher can rebuild a few times due to files changes that |
| 152 | + // happened just before the build (e.g. `git clean`). |
| 153 | + // This seems to be due to host file system differences, see |
| 154 | + // https://nodejs.org/docs/latest/api/fs.html#fs_caveats |
| 155 | + return Observable.fromPromise(_exec({ waitForMatch: match }, cmd, args)) |
| 156 | + .concat( |
| 157 | + Observable.defer(() => |
| 158 | + Observable.fromPromise(waitForAnyProcessOutputToMatch(match, 2500)) |
| 159 | + .repeat(20) |
| 160 | + .catch(_x => Observable.empty()) |
| 161 | + ) |
| 162 | + ) |
| 163 | + .takeLast(1) |
| 164 | + .toPromise(); |
| 165 | + } else { |
| 166 | + return _exec({ waitForMatch: match }, cmd, args); |
157 | 167 | }
|
158 |
| - return maybeWait.then(() => _exec({ silent: true, waitForMatch: match }, cmd, args)); |
159 | 168 | }
|
160 | 169 |
|
161 |
| - |
162 | 170 | let npmInstalledEject = false;
|
163 | 171 | export function ng(...args: string[]) {
|
164 | 172 | const argv = getGlobalVariable('argv');
|
|
0 commit comments