Skip to content

Commit 1955028

Browse files
rosen-vladimirovMitko-Kerezov
authored andcommitted
Separate preparation of JS from native code (#2983)
* Separate preparation of JS from native code * Introduce new parameter prepareNative to indicate that native code preparation is explicitly required. * Cache additional data in .nsprepareinfo file: * nativePlatformStatus - indicates whether native platform should be added, prepared or there's no need to do so; * projectFileHash - saves package.json file's contents hash for the current platform. We use this for better heuristics for checking whether package.json is changed. * Re-factoring i.e. extract common code to methods * Fix debug command and unit tests * Fix npm support tests Fix the tests by modifying current logic: - stop using ensurePrepareInfo for setting `nativePlatformStatus` property - introduce new method for setting it. The problem with using `ensurePrepareInfo` is that it saves the prepareInfo and calling checkForChanges after that is incorrect in case we modify the `bundle` option. Check test: `Ensures that tns_modules absent when bundling` - the last case was failing because when we call ensurePrepareInfo last time, bundle is false, we overwrite the prepareInfo in the file and checkForChanges says that bundle is currently false and has been false in the previous case. - in case prepareInfo is missing, we should not call addPlatform again - the else in `ensurePlatformInstalled` is not correct in case we execute `tns platform add <platform>` and then try `tns run/build/prepare <platform>` - in this case we do not have prepareInfo, so we try adding platform again. However, due to current implementation, we are sure that when we do not have prepareInfo, we've called platform add from CLI, so the platform is already added correctly. - fix a strange if inside `preparePlatformCoreNative` - we must prepare the node_modules in case `--bundle` is passed or the modulesChanged property of `changesInfo` is true. * Fix tests requiring package.json at the root of the project As projectChangesService now checks the package.json at the root of the project, several tests are failing as they are mocking the project creation and there's no package.json at the specified place. Fix this by creating the package.json in the tests. * Remove incorrect passing of skipNativePrepare * Cache instances of "base" commands in debug and run * Fix run android and run ios - set the platform correctly * Fix run command Fix run command by setting correct platform. * Update common lib * Fix PR comments
1 parent dea71ce commit 1955028

24 files changed

+500
-313
lines changed

lib/bootstrap.ts

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ $injector.require("devicePathProvider", "./device-path-provider");
105105
$injector.requireCommand("platform|clean", "./commands/platform-clean");
106106

107107
$injector.requirePublicClass("liveSyncService", "./services/livesync/livesync-service");
108+
$injector.require("liveSyncCommandHelper", "./services/livesync/livesync-command-helper");
108109
$injector.require("debugLiveSyncService", "./services/livesync/debug-livesync-service");
109110
$injector.require("androidLiveSyncService", "./services/livesync/android-livesync-service");
110111
$injector.require("iOSLiveSyncService", "./services/livesync/ios-livesync-service");

lib/commands/debug.ts

+50-72
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import { CONNECTED_STATUS } from "../common/constants";
22
import { isInteractive } from "../common/helpers";
3+
import { cache } from "../common/decorators";
34
import { DebugCommandErrors } from "../constants";
45

5-
export abstract class DebugPlatformCommand implements ICommand {
6+
export class DebugPlatformCommand implements ICommand {
67
public allowedParameters: ICommandParameter[] = [];
7-
public platform: string;
88

99
constructor(private debugService: IPlatformDebugService,
10-
private $devicesService: Mobile.IDevicesService,
11-
private $debugDataService: IDebugDataService,
10+
private platform: string,
11+
protected $devicesService: Mobile.IDevicesService,
1212
protected $platformService: IPlatformService,
1313
protected $projectData: IProjectData,
1414
protected $options: IOptions,
1515
protected $platformsData: IPlatformsData,
1616
protected $logger: ILogger,
1717
protected $errors: IErrors,
18+
private $debugDataService: IDebugDataService,
1819
private $debugLiveSyncService: IDebugLiveSyncService,
1920
private $config: IConfiguration,
20-
private $prompter: IPrompter) {
21-
this.$projectData.initializeProjectData();
21+
private $prompter: IPrompter,
22+
private $liveSyncCommandHelper: ILiveSyncCommandHelper) {
2223
}
2324

2425
public async execute(args: string[]): Promise<void> {
@@ -36,41 +37,7 @@ export abstract class DebugPlatformCommand implements ICommand {
3637

3738
const selectedDeviceForDebug = await this.getDeviceForDebug();
3839

39-
const deviceDescriptors: ILiveSyncDeviceInfo[] = [selectedDeviceForDebug]
40-
.map(d => {
41-
const info: ILiveSyncDeviceInfo = {
42-
identifier: d.deviceInfo.identifier,
43-
buildAction: async (): Promise<string> => {
44-
const buildConfig: IBuildConfig = {
45-
buildForDevice: !d.isEmulator,
46-
projectDir: this.$options.path,
47-
clean: this.$options.clean,
48-
teamId: this.$options.teamId,
49-
device: this.$options.device,
50-
provision: this.$options.provision,
51-
release: this.$options.release,
52-
keyStoreAlias: this.$options.keyStoreAlias,
53-
keyStorePath: this.$options.keyStorePath,
54-
keyStoreAliasPassword: this.$options.keyStoreAliasPassword,
55-
keyStorePassword: this.$options.keyStorePassword
56-
};
57-
58-
await this.$platformService.buildPlatform(d.deviceInfo.platform, buildConfig, this.$projectData);
59-
const pathToBuildResult = await this.$platformService.lastOutputPath(d.deviceInfo.platform, buildConfig, this.$projectData);
60-
return pathToBuildResult;
61-
}
62-
};
63-
64-
return info;
65-
});
66-
67-
const liveSyncInfo: ILiveSyncInfo = {
68-
projectDir: this.$projectData.projectDir,
69-
skipWatcher: !this.$options.watch || this.$options.justlaunch,
70-
watchAllFiles: this.$options.syncAllFiles
71-
};
72-
73-
await this.$debugLiveSyncService.liveSync(deviceDescriptors, liveSyncInfo);
40+
await this.$liveSyncCommandHelper.getDevicesLiveSyncInfo([selectedDeviceForDebug], this.$debugLiveSyncService, this.platform);
7441
}
7542

7643
public async getDeviceForDebug(): Promise<Mobile.IDevice> {
@@ -149,63 +116,74 @@ export abstract class DebugPlatformCommand implements ICommand {
149116
}
150117
}
151118

152-
export class DebugIOSCommand extends DebugPlatformCommand {
119+
export class DebugIOSCommand implements ICommand {
120+
121+
@cache()
122+
private get debugPlatformCommand(): DebugPlatformCommand {
123+
return this.$injector.resolve<DebugPlatformCommand>(DebugPlatformCommand, { debugService: this.$iOSDebugService, platform: this.platform });
124+
}
125+
126+
public allowedParameters: ICommandParameter[] = [];
127+
153128
constructor(protected $errors: IErrors,
154129
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
155-
$logger: ILogger,
156-
$iOSDebugService: IPlatformDebugService,
157-
$devicesService: Mobile.IDevicesService,
158-
$config: IConfiguration,
159-
$debugDataService: IDebugDataService,
160-
$platformService: IPlatformService,
161-
$options: IOptions,
162-
$projectData: IProjectData,
163-
$platformsData: IPlatformsData,
164-
$iosDeviceOperations: IIOSDeviceOperations,
165-
$debugLiveSyncService: IDebugLiveSyncService,
166-
$prompter: IPrompter) {
167-
super($iOSDebugService, $devicesService, $debugDataService, $platformService, $projectData, $options, $platformsData, $logger,
168-
$errors, $debugLiveSyncService, $config, $prompter);
130+
private $platformService: IPlatformService,
131+
private $options: IOptions,
132+
private $injector: IInjector,
133+
private $projectData: IProjectData,
134+
private $platformsData: IPlatformsData,
135+
private $iOSDebugService: IDebugService,
136+
$iosDeviceOperations: IIOSDeviceOperations) {
137+
this.$projectData.initializeProjectData();
169138
// Do not dispose ios-device-lib, so the process will remain alive and the debug application (NativeScript Inspector or Chrome DevTools) will be able to connect to the socket.
170139
// In case we dispose ios-device-lib, the socket will be closed and the code will fail when the debug application tries to read/send data to device socket.
171140
// That's why the `$ tns debug ios --justlaunch` command will not release the terminal.
172141
// In case we do not set it to false, the dispose will be called once the command finishes its execution, which will prevent the debugging.
173142
$iosDeviceOperations.setShouldDispose(false);
174143
}
175144

145+
public execute(args: string[]): Promise<void> {
146+
return this.debugPlatformCommand.execute(args);
147+
}
148+
176149
public async canExecute(args: string[]): Promise<boolean> {
177150
if (!this.$platformService.isPlatformSupportedForOS(this.$devicePlatformsConstants.iOS, this.$projectData)) {
178151
this.$errors.fail(`Applications for platform ${this.$devicePlatformsConstants.iOS} can not be built on this OS`);
179152
}
180153

181-
return await super.canExecute(args) && await this.$platformService.validateOptions(this.$options.provision, this.$projectData, this.$platformsData.availablePlatforms.iOS);
154+
return await this.debugPlatformCommand.canExecute(args) && await this.$platformService.validateOptions(this.$options.provision, this.$projectData, this.$platformsData.availablePlatforms.iOS);
182155
}
183156

184157
public platform = this.$devicePlatformsConstants.iOS;
185158
}
186159

187160
$injector.registerCommand("debug|ios", DebugIOSCommand);
188161

189-
export class DebugAndroidCommand extends DebugPlatformCommand {
162+
export class DebugAndroidCommand implements ICommand {
163+
164+
@cache()
165+
private get debugPlatformCommand(): DebugPlatformCommand {
166+
return this.$injector.resolve<DebugPlatformCommand>(DebugPlatformCommand, { debugService: this.$androidDebugService, platform: this.platform });
167+
}
168+
169+
public allowedParameters: ICommandParameter[] = [];
170+
190171
constructor(protected $errors: IErrors,
191172
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
192-
$logger: ILogger,
193-
$androidDebugService: IPlatformDebugService,
194-
$devicesService: Mobile.IDevicesService,
195-
$config: IConfiguration,
196-
$debugDataService: IDebugDataService,
197-
$platformService: IPlatformService,
198-
$options: IOptions,
199-
$projectData: IProjectData,
200-
$platformsData: IPlatformsData,
201-
$debugLiveSyncService: IDebugLiveSyncService,
202-
$prompter: IPrompter) {
203-
super($androidDebugService, $devicesService, $debugDataService, $platformService, $projectData, $options, $platformsData, $logger,
204-
$errors, $debugLiveSyncService, $config, $prompter);
173+
private $platformService: IPlatformService,
174+
private $options: IOptions,
175+
private $injector: IInjector,
176+
private $projectData: IProjectData,
177+
private $platformsData: IPlatformsData,
178+
private $androidDebugService: IDebugService) {
179+
this.$projectData.initializeProjectData();
205180
}
206181

182+
public execute(args: string[]): Promise<void> {
183+
return this.debugPlatformCommand.execute(args);
184+
}
207185
public async canExecute(args: string[]): Promise<boolean> {
208-
return await super.canExecute(args) && await this.$platformService.validateOptions(this.$options.provision, this.$projectData, this.$platformsData.availablePlatforms.Android);
186+
return await this.debugPlatformCommand.canExecute(args) && await this.$platformService.validateOptions(this.$options.provision, this.$projectData, this.$platformsData.availablePlatforms.Android);
209187
}
210188

211189
public platform = this.$devicePlatformsConstants.Android;

0 commit comments

Comments
 (0)