From ecdbe721a1be10a59e7ee1b2f446b20c1e7de95b Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 28 Jun 2022 16:28:09 -0400 Subject: [PATCH] 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. --- .../architect/src/create-builder.ts | 8 ++++- .../architect/src/index_spec.ts | 32 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/angular_devkit/architect/src/create-builder.ts b/packages/angular_devkit/architect/src/create-builder.ts index f5f19dc75c..6aa83bd36c 100644 --- a/packages/angular_devkit/architect/src/create-builder.ts +++ b/packages/angular_devkit/architect/src/create-builder.ts @@ -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 { + // Allow the log queue to flush + await new Promise(setImmediate); + + return value; + }), ) .subscribe( (message) => observer.next(message as OutT), diff --git a/packages/angular_devkit/architect/src/index_spec.ts b/packages/angular_devkit/architect/src/index_spec.ts index 803bae9d16..8e5ae5138a 100644 --- a/packages/angular_devkit/architect/src/index_spec.ts +++ b/packages/angular_devkit/architect/src/index_spec.ts @@ -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',