Skip to content

Commit 1606b2a

Browse files
Detach event handlers after action is done (#2703)
In order to not emit `buildOutput` event multiple times during build in a long running process (fusion) we have to detach event handlers after build is done.
1 parent 99c9bf5 commit 1606b2a

File tree

5 files changed

+37
-19
lines changed

5 files changed

+37
-19
lines changed

lib/services/android-project-service.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as constants from "../constants";
44
import * as semver from "semver";
55
import * as projectServiceBaseLib from "./platform-project-service-base";
66
import { DeviceAndroidDebugBridge } from "../common/mobile/android/device-android-debug-bridge";
7+
import { attachAwaitDetach } from "../common/helpers";
78
import { EOL } from "os";
89
import { Configurations } from "../common/constants";
910
import { SpawnOptions } from "child_process";
@@ -257,13 +258,17 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
257258

258259
buildOptions.unshift("buildapk");
259260

260-
this.$childProcess.on(constants.BUILD_OUTPUT_EVENT_NAME, (data: any) => {
261+
const handler = (data: any) => {
261262
this.emit(constants.BUILD_OUTPUT_EVENT_NAME, data);
262-
});
263+
};
263264

264-
await this.executeGradleCommand(this.getPlatformData(projectData).projectRoot, buildOptions,
265-
{ stdio: buildConfig.buildOutputStdio || "inherit" },
266-
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true });
265+
await attachAwaitDetach(constants.BUILD_OUTPUT_EVENT_NAME,
266+
this.$childProcess,
267+
handler,
268+
this.executeGradleCommand(this.getPlatformData(projectData).projectRoot,
269+
buildOptions,
270+
{ stdio: buildConfig.buildOutputStdio || "inherit" },
271+
{ emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME }, throwError: true }));
267272
} else {
268273
this.$errors.failWithoutHelp("Cannot complete build because this project is ANT-based." + EOL +
269274
"Run `tns platform remove android && tns platform add android` to switch to Gradle and try again.");

lib/services/ios-project-service.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as semver from "semver";
55
import * as xcode from "xcode";
66
import * as constants from "../constants";
77
import * as helpers from "../common/helpers";
8+
import { attachAwaitDetach } from "../common/helpers";
89
import * as projectServiceBaseLib from "./platform-project-service-base";
910
import { PlistSession } from "plist-merge-patch";
1011
import { EOL } from "os";
@@ -180,7 +181,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
180181
let projectRoot = this.getPlatformData(projectData).projectRoot;
181182
let archivePath = options && options.archivePath ? path.resolve(options.archivePath) : path.join(projectRoot, "/build/archive/", projectData.projectName + ".xcarchive");
182183
let args = ["archive", "-archivePath", archivePath, "-configuration",
183-
(!buildConfig || buildConfig.release) ? "Release" : "Debug" ]
184+
(!buildConfig || buildConfig.release) ? "Release" : "Debug"]
184185
.concat(this.xcbuildProjectArgs(projectRoot, projectData, "scheme"));
185186
await this.$childProcess.spawnFromEvent("xcodebuild", args, "exit", { stdio: 'inherit' });
186187
return archivePath;
@@ -287,15 +288,21 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
287288
// }
288289
// }
289290

290-
this.$childProcess.on(constants.BUILD_OUTPUT_EVENT_NAME, (data: any) => {
291+
const handler = (data: any) => {
291292
this.emit(constants.BUILD_OUTPUT_EVENT_NAME, data);
292-
});
293+
};
294+
293295
if (buildConfig.buildForDevice) {
294-
await this.buildForDevice(projectRoot, basicArgs, buildConfig, projectData);
296+
await attachAwaitDetach(constants.BUILD_OUTPUT_EVENT_NAME,
297+
this.$childProcess,
298+
handler,
299+
this.buildForDevice(projectRoot, basicArgs, buildConfig, projectData));
295300
} else {
296-
await this.buildForSimulator(projectRoot, basicArgs, projectData, buildConfig.buildOutputStdio);
301+
await attachAwaitDetach(constants.BUILD_OUTPUT_EVENT_NAME,
302+
this.$childProcess,
303+
handler,
304+
this.buildForSimulator(projectRoot, basicArgs, projectData, buildConfig.buildOutputStdio));
297305
}
298-
299306
}
300307

301308
public async validatePlugins(projectData: IProjectData): Promise<void> {

lib/services/local-build-service.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import { EventEmitter } from "events";
22
import { BUILD_OUTPUT_EVENT_NAME } from "../constants";
3+
import { attachAwaitDetach } from "../common/helpers";
34

45
export class LocalBuildService extends EventEmitter {
56
constructor(private $projectData: IProjectData,
6-
private $platformService: IPlatformService) {
7+
private $platformService: IPlatformService) {
78
super();
89
}
910

1011
public async build(platform: string, platformBuildOptions: IPlatformBuildData, platformTemplate?: string): Promise<string> {
1112
this.$projectData.initializeProjectData(platformBuildOptions.projectDir);
1213
await this.$platformService.preparePlatform(platform, platformBuildOptions, platformTemplate, this.$projectData, { provision: platformBuildOptions.provision, sdk: null });
13-
this.$platformService.on(BUILD_OUTPUT_EVENT_NAME, (data: any) => {
14+
const handler = (data: any) => {
1415
data.projectDir = platformBuildOptions.projectDir;
1516
this.emit(BUILD_OUTPUT_EVENT_NAME, data);
16-
});
17+
};
1718
platformBuildOptions.buildOutputStdio = "pipe";
18-
await this.$platformService.buildPlatform(platform, platformBuildOptions, this.$projectData);
19+
20+
await attachAwaitDetach(BUILD_OUTPUT_EVENT_NAME, this.$platformService, handler, this.$platformService.buildPlatform(platform, platformBuildOptions, this.$projectData));
1921
return this.$platformService.lastOutputPath(platform, platformBuildOptions, this.$projectData);
2022
}
2123
}

lib/services/platform-service.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as helpers from "../common/helpers";
55
import * as semver from "semver";
66
import { EventEmitter } from "events";
77
import { AppFilesUpdater } from "./app-files-updater";
8+
import { attachAwaitDetach } from "../common/helpers";
89
import * as temp from "temp";
910
temp.track();
1011
let clui = require("clui");
@@ -425,10 +426,13 @@ export class PlatformService extends EventEmitter implements IPlatformService {
425426
await this.trackActionForPlatform({ action: "Build", platform, isForDevice });
426427

427428
let platformData = this.$platformsData.getPlatformData(platform, projectData);
428-
platformData.platformProjectService.on(constants.BUILD_OUTPUT_EVENT_NAME, (data: any) => {
429+
const handler = (data: any) => {
429430
this.emit(constants.BUILD_OUTPUT_EVENT_NAME, data);
430-
});
431-
await platformData.platformProjectService.buildProject(platformData.projectRoot, projectData, buildConfig);
431+
this.$logger.printInfoMessageOnSameLine(data.data.toString());
432+
};
433+
434+
await attachAwaitDetach(constants.BUILD_OUTPUT_EVENT_NAME, platformData.platformProjectService, handler, platformData.platformProjectService.buildProject(platformData.projectRoot, projectData, buildConfig));
435+
432436
let prepareInfo = this.$projectChangesService.getPrepareInfo(platform, projectData);
433437
let buildInfoFilePath = this.getBuildOutputPath(platform, platformData, buildConfig);
434438
let buildInfoFile = path.join(buildInfoFilePath, buildInfoFileName);

0 commit comments

Comments
 (0)