Skip to content

Commit d67764a

Browse files
Merge pull request #3343 from NativeScript/vladimirov/merge-rel-master
chore: merge release in master
2 parents ab4e6e4 + a594679 commit d67764a

20 files changed

+123
-69
lines changed

PublicAPI.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ Provides methods for debugging applications on devices. The service is also even
424424
* Usage:
425425
```JavaScript
426426
tns.debugService.on("connectionError", errorData => {
427-
console.log(`Unable to start debug operation on device ${errorData.deviceId}. Error is: ${errorData.message}.`);
427+
console.log(`Unable to start debug operation on device ${errorData.deviceIdentifier}. Error is: ${errorData.message}.`);
428428
});
429429
```
430430
@@ -522,7 +522,7 @@ interface IDebugOptions {
522522
* Usage:
523523
```JavaScript
524524
tns.debugService.on("connectionError", errorData => {
525-
console.log(`Unable to start debug operation on device ${errorData.deviceId}. Error is: ${errorData.message}.`);
525+
console.log(`Unable to start debug operation on device ${errorData.deviceIdentifier}. Error is: ${errorData.message}.`);
526526
});
527527

528528
const debugData = {
@@ -903,4 +903,4 @@ CLI is designed as command line tool and when it is used as a library, it does n
903903
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.
904904
905905
More information how to add a method to public API is available [here](https://github.com/telerik/mobile-cli-lib#how-to-make-a-method-public).
906-
After that add each method that you've exposed to the tests in `tests/nativescript-cli-lib.ts` file. There you'll find an object describing each publicly available module and the methods that you can call.
906+
After that add each method that you've exposed to the tests in `tests/nativescript-cli-lib.ts` file. There you'll find an object describing each publicly available module and the methods that you can call.

lib/android-tools-info.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { appendZeroesToVersion } from './common/helpers';
66

77
export class AndroidToolsInfo implements IAndroidToolsInfo {
88
private static ANDROID_TARGET_PREFIX = "android";
9-
private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26"];
9+
private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26", "android-27"];
1010
private static MIN_REQUIRED_COMPILE_TARGET = 22;
1111
private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23";
1212
private static VERSION_REGEX = /((\d+\.){2}\d+)/;
@@ -306,6 +306,10 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
306306
if (this.androidHome && requiredAppCompatRange) {
307307
const pathToAppCompat = path.join(this.androidHome, "extras", "android", "m2repository", "com", "android", "support", "appcompat-v7");
308308
selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, requiredAppCompatRange);
309+
if (!selectedAppCompatVersion) {
310+
// get latest matching version, as there's no available appcompat versions for latest SDK versions.
311+
selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, "*");
312+
}
309313
}
310314

311315
this.$logger.trace(`Selected AppCompat version is: ${selectedAppCompatVersion}`);

lib/declarations.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ interface IAndroidToolsInfoData {
544544

545545
interface ISocketProxyFactory extends NodeJS.EventEmitter {
546546
createTCPSocketProxy(factory: () => Promise<any>): Promise<any>;
547-
createWebSocketProxy(factory: () => Promise<any>): Promise<any>;
547+
createWebSocketProxy(factory: () => Promise<any>, deviceIdentifier: string): Promise<any>;
548548
}
549549

550550
interface IiOSNotification {

lib/definitions/livesync.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ interface ILiveSyncProcessInfo {
6060
timer: NodeJS.Timer;
6161
watcherInfo: {
6262
watcher: IFSWatcher,
63-
pattern: string | string[]
63+
patterns: string[]
6464
};
6565
actionsChain: Promise<any>;
6666
isStopped: boolean;

lib/device-sockets/ios/socket-proxy-factory.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
7272
return server;
7373
}
7474

75-
public async createWebSocketProxy(factory: () => Promise<net.Socket>): Promise<ws.Server> {
75+
public async createWebSocketProxy(factory: () => Promise<net.Socket>, deviceIdentifier: string): Promise<ws.Server> {
7676
// NOTE: We will try to provide command line options to select ports, at least on the localhost.
7777
const localPort = await this.$net.getAvailablePortInRange(41000);
7878

@@ -92,6 +92,7 @@ export class SocketProxyFactory extends EventEmitter implements ISocketProxyFact
9292
try {
9393
_socket = await factory();
9494
} catch (err) {
95+
err.deviceIdentifier = deviceIdentifier;
9596
this.$logger.trace(err);
9697
this.emit(CONNECTION_ERROR_EVENT_NAME, err);
9798
this.$errors.failWithoutHelp("Cannot connect to device socket.");

lib/services/doctor-service.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { EOL } from "os";
22
import * as semver from "semver";
33
import * as path from "path";
44
import * as helpers from "../common/helpers";
5-
const clui = require("clui");
65

76
class DoctorService implements IDoctorService {
87
private static PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__";
@@ -166,7 +165,7 @@ class DoctorService implements IDoctorService {
166165
};
167166
this.$fs.writeJson(path.join(projDir, "package.json"), packageJsonData);
168167

169-
const spinner = new clui.Spinner("Installing iOS runtime.");
168+
const spinner = this.$progressIndicator.getSpinner("Installing iOS runtime.");
170169
try {
171170
spinner.start();
172171
await this.$npm.install("tns-ios", projDir, {

lib/services/ios-debug-service.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
2323
constructor(protected device: Mobile.IDevice,
2424
protected $devicesService: Mobile.IDevicesService,
2525
private $platformService: IPlatformService,
26-
private $iOSEmulatorServices: Mobile.IEmulatorPlatformServices,
26+
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
2727
private $childProcess: IChildProcess,
2828
private $hostInfo: IHostInfo,
2929
private $logger: ILogger,
@@ -32,7 +32,8 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
3232
private $iOSNotification: IiOSNotification,
3333
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
3434
private $processService: IProcessService,
35-
private $socketProxyFactory: ISocketProxyFactory) {
35+
private $socketProxyFactory: ISocketProxyFactory,
36+
private $net: INet) {
3637
super(device, $devicesService);
3738
this.$processService.attachToProcessExitSignals(this, this.debugStop);
3839
this.$socketProxyFactory.on(CONNECTION_ERROR_EVENT_NAME, (e: Error) => this.emit(CONNECTION_ERROR_EVENT_NAME, e));
@@ -145,6 +146,8 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
145146
}
146147
});
147148

149+
await this.waitForBackendPortToBeOpened(debugData.deviceIdentifier);
150+
148151
return this.wireDebuggerClient(debugData, debugOptions);
149152
}
150153

@@ -153,11 +156,21 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
153156

154157
const attachRequestMessage = this.$iOSNotification.getAttachRequest(debugData.applicationIdentifier);
155158

156-
const iOSEmulator = <Mobile.IiOSSimulatorService>this.$iOSEmulatorServices;
157-
await iOSEmulator.postDarwinNotification(attachRequestMessage);
159+
const iOSEmulatorService = <Mobile.IiOSSimulatorService>this.$iOSEmulatorServices;
160+
await iOSEmulatorService.postDarwinNotification(attachRequestMessage);
161+
await this.waitForBackendPortToBeOpened(debugData.deviceIdentifier);
158162
return result;
159163
}
160164

165+
private async waitForBackendPortToBeOpened(deviceIdentifier: string): Promise<void> {
166+
const portListens = await this.$net.waitForPortToListen({ port: inspectorBackendPort, timeout: 10000, interval: 200 });
167+
if (!portListens) {
168+
const error = <Mobile.IDeviceError>new Error("Unable to connect to application. Ensure application is running on simulator.");
169+
error.deviceIdentifier = deviceIdentifier;
170+
throw error;
171+
}
172+
}
173+
161174
private async deviceDebugBrk(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
162175
await this.$devicesService.initialize({ platform: this.platform, deviceId: debugData.deviceIdentifier });
163176
const action = async (device: iOSDevice.IOSDevice): Promise<string> => {
@@ -212,7 +225,8 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
212225
this.$logger.info("'--chrome' is the default behavior. Use --inspector to debug iOS applications using the Safari Web Inspector.");
213226
}
214227

215-
this._socketProxy = await this.$socketProxyFactory.createWebSocketProxy(this.getSocketFactory(device));
228+
const deviceIdentifier = device ? device.deviceInfo.identifier : debugData.deviceIdentifier;
229+
this._socketProxy = await this.$socketProxyFactory.createWebSocketProxy(this.getSocketFactory(device), deviceIdentifier);
216230
return this.getChromeDebugUrl(debugOptions, this._socketProxy.options.port);
217231
}
218232
}

lib/services/livesync/ios-device-livesync-service.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as helpers from "../../common/helpers";
21
import * as constants from "../../constants";
32
import * as minimatch from "minimatch";
43
import * as net from "net";
@@ -30,10 +29,8 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
3029

3130
if (this.device.isEmulator) {
3231
await this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.getAttachRequest(projectId));
33-
try {
34-
this.socket = await helpers.connectEventuallyUntilTimeout(() => net.connect(IOSDeviceLiveSyncService.BACKEND_PORT), 5000);
35-
} catch (e) {
36-
this.$logger.debug(e);
32+
this.socket = await this.$iOSEmulatorServices.connectToPort({ port: IOSDeviceLiveSyncService.BACKEND_PORT });
33+
if (!this.socket) {
3734
return false;
3835
}
3936
} else {

lib/services/livesync/livesync-service.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -513,21 +513,21 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
513513
}
514514

515515
private async startWatcher(projectData: IProjectData, liveSyncData: ILiveSyncInfo): Promise<void> {
516-
const pattern = [APP_FOLDER_NAME];
516+
const patterns = [APP_FOLDER_NAME];
517517

518518
if (liveSyncData.watchAllFiles) {
519519
const productionDependencies = this.$nodeModulesDependenciesBuilder.getProductionDependencies(projectData.projectDir);
520-
pattern.push(PACKAGE_JSON_FILE_NAME);
520+
patterns.push(PACKAGE_JSON_FILE_NAME);
521521

522522
// watch only production node_module/packages same one prepare uses
523523
for (const index in productionDependencies) {
524-
pattern.push(productionDependencies[index].directory);
524+
patterns.push(productionDependencies[index].directory);
525525
}
526526
}
527527

528528
const currentWatcherInfo = this.liveSyncProcessesInfo[liveSyncData.projectDir].watcherInfo;
529-
530-
if (!currentWatcherInfo || currentWatcherInfo.pattern !== pattern) {
529+
const areWatcherPatternsDifferent = () => _.xor(currentWatcherInfo.patterns, patterns).length;
530+
if (!currentWatcherInfo || areWatcherPatternsDifferent()) {
531531
if (currentWatcherInfo) {
532532
currentWatcherInfo.watcher.close();
533533
}
@@ -630,7 +630,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
630630
ignored: ["**/.*", ".*"] // hidden files
631631
};
632632

633-
const watcher = choki.watch(pattern, watcherOptions)
633+
const watcher = choki.watch(patterns, watcherOptions)
634634
.on("all", async (event: string, filePath: string) => {
635635
clearTimeout(timeoutTimer);
636636

@@ -650,7 +650,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
650650
}
651651
});
652652

653-
this.liveSyncProcessesInfo[liveSyncData.projectDir].watcherInfo = { watcher, pattern };
653+
this.liveSyncProcessesInfo[liveSyncData.projectDir].watcherInfo = { watcher, patterns };
654654
this.liveSyncProcessesInfo[liveSyncData.projectDir].timer = timeoutTimer;
655655

656656
this.$processService.attachToProcessExitSignals(this, () => {

lib/services/platform-service.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { AppFilesUpdater } from "./app-files-updater";
99
import { attachAwaitDetach } from "../common/helpers";
1010
import * as temp from "temp";
1111
temp.track();
12-
const clui = require("clui");
1312

1413
const buildInfoFileName = ".nsbuildinfo";
1514

@@ -25,6 +24,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
2524
constructor(private $devicesService: Mobile.IDevicesService,
2625
private $preparePlatformNativeService: IPreparePlatformService,
2726
private $preparePlatformJSService: IPreparePlatformService,
27+
private $progressIndicator: IProgressIndicator,
2828
private $errors: IErrors,
2929
private $fs: IFileSystem,
3030
private $logger: ILogger,
@@ -115,7 +115,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
115115
npmOptions["version"] = version;
116116
}
117117

118-
const spinner = new clui.Spinner("Installing " + packageToInstall);
118+
const spinner = this.$progressIndicator.getSpinner("Installing " + packageToInstall);
119119
const projectDir = projectData.projectDir;
120120
const platformPath = path.join(projectData.platformsDir, platform);
121121

@@ -560,6 +560,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
560560
return null;
561561
}
562562

563+
@helpers.hook('cleanApp')
563564
public async cleanDestinationApp(platformInfo: IPreparePlatformInfo): Promise<void> {
564565
await this.ensurePlatformInstalled(platformInfo.platform, platformInfo.platformTemplate, platformInfo.projectData, platformInfo.config);
565566

0 commit comments

Comments
 (0)