1
0
mirror of https://github.com/angular/angular-cli.git synced 2025-05-18 20:02:40 +08:00

fix(@angular-devkit/architect): complete builders on the next event loop iteration

Waiting to complete the builder until the next tick allows the logging
subscription to flush and provide queued logging entries to the builder
consumer.
This commit is contained in:
Charles Lyding 2022-06-28 16:28:09 -04:00 committed by Charles
parent f86895306e
commit ecdbe721a1
2 changed files with 38 additions and 2 deletions
packages/angular_devkit/architect/src

@ -8,7 +8,7 @@
import { analytics, experimental, json, logging } from '@angular-devkit/core';
import { Observable, Subscription, from, isObservable, of, throwError } from 'rxjs';
import { tap } from 'rxjs/operators';
import { mergeMap, tap } from 'rxjs/operators';
import {
BuilderContext,
BuilderHandlerFn,
@ -223,6 +223,12 @@ export function createBuilder<OptT = json.JsonObject, OutT extends BuilderOutput
progress({ state: BuilderProgressState.Running, current: total }, context);
progress({ state: BuilderProgressState.Stopped }, context);
}),
mergeMap(async (value) => {
// Allow the log queue to flush
await new Promise<void>(setImmediate);
return value;
}),
)
.subscribe(
(message) => observer.next(message as OutT),

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import { json, schema } from '@angular-devkit/core';
import { json, logging, schema } from '@angular-devkit/core';
import { timer } from 'rxjs';
import { map, take, tap, toArray } from 'rxjs/operators';
import { promisify } from 'util';
@ -206,6 +206,36 @@ describe('architect', () => {
expect(all.length).toBe(10);
});
it('propagates all logging entries', async () => {
const logCount = 100;
testArchitectHost.addBuilder(
'package:test-logging',
createBuilder(async (_, context) => {
for (let i = 0; i < logCount; ++i) {
context.logger.info(i.toString());
}
return { success: true };
}),
);
const logger = new logging.Logger('test-logger');
const logs: string[] = [];
logger.subscribe({
next(entry) {
logs.push(entry.message);
},
});
const run = await architect.scheduleBuilder('package:test-logging', {}, { logger });
expect(await run.result).toEqual(jasmine.objectContaining({ success: true }));
await run.stop();
for (let i = 0; i < logCount; ++i) {
expect(logs[i]).toBe(i.toString());
}
});
it('reports errors in the builder', async () => {
testArchitectHost.addBuilder(
'package:error',