Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 138a263

Browse files
FatmeFatme
Fatme
authored and
Fatme
committed
Merge pull request #376 from telerik/fatme/ns-livesync
LiveSync support
2 parents 2639b35 + 98a1cdf commit 138a263

37 files changed

+1072
-1116
lines changed

bootstrap.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ $injector.requireCommand("device|ios", "./common/commands/device/list-devices");
4242

4343
$injector.requireCommand("device|log", "./common/commands/device/device-log-stream");
4444
$injector.requireCommand("device|run", "./common/commands/device/run-application");
45+
$injector.requireCommand("device|stop", "./common/commands/device/stop-application");
4546
$injector.requireCommand("device|list-applications", "./common/commands/device/list-applications");
4647
$injector.requireCommand("device|uninstall", "./common/commands/device/uninstall-application");
4748
$injector.requireCommand("device|list-files", "./common/commands/device/list-files");
@@ -70,6 +71,9 @@ $injector.require("iOSDevice", "./common/mobile/ios/ios-device");
7071
$injector.require("androidDevice", "./common/mobile/android/android-device");
7172
$injector.require("logcatHelper", "./common/mobile/android/logcat-helper");
7273

74+
$injector.require("localToDevicePathDataFactory", "./common/mobile/local-to-device-path-data-factory");
75+
$injector.require("deviceAppDataFactory", "./common/mobile/device-app-data/device-app-data-factory");
76+
7377
$injector.require("devicesServices", "./common/mobile/mobile-core/devices-services");
7478
$injector.require("projectNameValidator", "./common/validators/project-name-validator");
7579

@@ -85,4 +89,4 @@ $injector.require("mobileHelper", "./common/mobile/mobile-helper");
8589
$injector.require("devicePlatformsConstants", "./common/mobile/device-platforms-constants");
8690
$injector.require("htmlHelpService", "./common/services/html-help-service");
8791
$injector.requireCommand("dev-preuninstall", "./common/commands/preuninstall");
88-
$injector.requireCommand("doctor", "./common/commands/doctor");
92+
$injector.requireCommand("doctor", "./common/commands/doctor");

commands/device/get-file.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class GetFileCommand implements ICommand {
1212
return (() => {
1313
this.$devicesServices.initialize({ deviceId: this.$options.device, skipInferPlatform: true }).wait();
1414

15-
let action = (device: Mobile.IDevice) => { return (() => device.getFile(args[0]).wait()).future<void>()(); };
15+
let action = (device: Mobile.IDevice) => { return (() => device.fileSystem.getFile(args[0]).wait()).future<void>()(); };
1616
this.$devicesServices.execute(action).wait();
1717
}).future<void>()();
1818
}

commands/device/list-applications.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export class ListApplicationsCommand implements ICommand {
1818
let output: string[] = [];
1919

2020
let action = (device: Mobile.IDevice) => { return (() => {
21-
let applications = device.getInstalledApplications().wait();
22-
output.push(util.format("%s=====Installed applications on device with UDID '%s' are:", os.EOL, device.getIdentifier()));
21+
let applications = device.applicationManager.getInstalledApplications().wait();
22+
output.push(util.format("%s=====Installed applications on device with UDID '%s' are:", os.EOL, device.deviceInfo.identifier));
2323
_.each(applications, (applicationId: string) => output.push(applicationId));
2424
}).future<void>()(); };
2525
this.$devicesServices.execute(action).wait();

commands/device/list-devices.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ export class ListDevicesCommand implements ICommand {
2222
this.$logger.setLevel("ERROR");
2323
action = (device) => {
2424
return (() => { this.$logger.out(JSON.stringify({
25-
identifier: device.getIdentifier(),
26-
platform: device.getPlatform(),
27-
model: device.getModel(),
28-
name: device.getDisplayName(),
29-
version: device.getVersion(),
30-
vendor: device.getVendor()
25+
identifier: device.deviceInfo.identifier,
26+
platform: device.deviceInfo.platform,
27+
model: device.deviceInfo.model,
28+
name: device.deviceInfo.displayName,
29+
version: device.deviceInfo.version,
30+
vendor: device.deviceInfo.vendor
3131
}))}).future<void>()();
3232
};
3333
} else {
3434
action = (device) => {
35-
return (() => { this.$logger.out("%s: '%s'", (index++).toString(), device.getDisplayName(), device.getPlatform(), device.getIdentifier()); }).future<void>()();
35+
return (() => { this.$logger.out("%s: '%s'", (index++).toString(), device.deviceInfo.displayName, device.deviceInfo.platform, device.deviceInfo.identifier) }).future<void>()();
3636
};
3737
}
3838

commands/device/list-files.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class ListFilesCommand implements ICommand {
1212
return (() => {
1313
this.$devicesServices.initialize({ deviceId: this.$options.device, skipInferPlatform: true }).wait();
1414

15-
let action = (device: Mobile.IDevice) => { return (() => device.listFiles(args[0]).wait()).future<void>()(); };
15+
let action = (device: Mobile.IDevice) => { return (() => device.fileSystem.listFiles(args[0]).wait()).future<void>()(); };
1616
this.$devicesServices.execute(action).wait();
1717
}).future<void>()();
1818
}

commands/device/put-file.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class PutFileCommand implements ICommand {
1212
return (() => {
1313
this.$devicesServices.initialize({ deviceId: this.$options.device, skipInferPlatform: true }).wait();
1414

15-
let action = (device: Mobile.IDevice) => { return (() => device.putFile(args[0], args[1]).wait()).future<void>()(); };
15+
let action = (device: Mobile.IDevice) => { return (() => device.fileSystem.putFile(args[0], args[1]).wait()).future<void>()(); };
1616
this.$devicesServices.execute(action).wait();
1717
}).future<void>()();
1818
}

commands/device/run-application.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class RunApplicationOnDeviceCommand implements ICommand {
2121
this.$errors.fail("More than one device found. Specify device explicitly with --device option.To discover device ID, use $%s device command.", this.$staticConfig.CLIENT_NAME.toLowerCase());
2222
}
2323

24-
let action = (device: Mobile.IDevice) => { return (() => device.runApplication(args[0]).wait()).future<void>()(); };
24+
let action = (device: Mobile.IDevice) => { return (() => device.applicationManager.startApplication(args[0]).wait()).future<void>()(); };
2525
this.$devicesServices.execute(action).wait();
2626
}).future<void>()();
2727
}

commands/device/stop-application.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
///<reference path="../../../.d.ts"/>
3+
"use strict";
4+
5+
import helpers = require("./../../helpers");
6+
import Future = require("fibers/future");
7+
8+
export class StopApplicationOnDeviceCommand implements ICommand {
9+
10+
constructor(private $devicesServices: Mobile.IDevicesServices,
11+
private $errors: IErrors,
12+
private $stringParameter: ICommandParameter,
13+
private $staticConfig: Config.IStaticConfig,
14+
private $options: IOptions) { }
15+
16+
allowedParameters: ICommandParameter[] = [this.$stringParameter];
17+
18+
public execute(args: string[]): IFuture<void> {
19+
return (() => {
20+
this.$devicesServices.initialize({ deviceId: this.$options.device, skipInferPlatform: true }).wait();
21+
22+
if (this.$devicesServices.deviceCount > 1) {
23+
this.$errors.failWithoutHelp("More than one device found. Specify device explicitly with --device option.To discover device ID, use $%s device command.", this.$staticConfig.CLIENT_NAME.toLowerCase());
24+
}
25+
26+
let action = (device: Mobile.IDevice) => { return (() => device.applicationManager.stopApplication(args[0]).wait()).future<void>()(); };
27+
this.$devicesServices.execute(action).wait();
28+
}).future<void>()();
29+
}
30+
}
31+
$injector.registerCommand("device|stop", StopApplicationOnDeviceCommand);

commands/device/uninstall-application.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class UninstallApplicationCommand implements ICommand {
1212
return (() => {
1313
this.$devicesServices.initialize({ deviceId: this.$options.device, skipInferPlatform: true }).wait();
1414

15-
let action = (device: Mobile.IDevice) => { return (() => device.uninstallApplication(args[0]).wait()).future<void>()(); };
15+
let action = (device: Mobile.IDevice) => { return (() => device.applicationManager.uninstallApplication(args[0]).wait()).future<void>()(); };
1616
this.$devicesServices.execute(action).wait();
1717
}).future<void>()();
1818
}

declarations.d.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ interface IFileSystem {
7878
chmod(path: string, mode: string): IFuture<any>;
7979

8080
setCurrentUserAsOwner(path: string, owner: string): IFuture<void>;
81-
enumerateFilesInDirectorySync(directoryPath: string, filterCallback?: (file: string, stat: IFsStats) => boolean): string[];
81+
enumerateFilesInDirectorySync(directoryPath: string, filterCallback?: (file: string, stat: IFsStats) => boolean, opts?: { enumerateDirectories?: boolean }): string[];
8282
}
8383

8484
// duplicated from fs.Stats, because I cannot import it here
@@ -261,6 +261,14 @@ interface IHtmlHelpService {
261261
openHelpForCommandInBrowser(commandName: string): IFuture<void>;
262262
}
263263

264+
interface IUsbLiveSyncServiceBase {
265+
initialize(platform: string): IFuture<string>;
266+
sync(platform: string, appIdentifier: string, localProjectRootPath: string, projectFilesPath: string, excludedProjectDirsAndFiles: string[], watchGlob: any,
267+
restartAppOnDeviceAction: (device: Mobile.IDevice, deviceAppData: Mobile.IDeviceAppData) => IFuture<void>,
268+
notInstalledAppOnDeviceAction: (device: Mobile.IDevice) => IFuture<void>,
269+
beforeBatchLiveSyncAction?: (filePath: string) => IFuture<void>): IFuture<void>;
270+
}
271+
264272
interface ISysInfoData {
265273
/** name and version of the CLI app itself */
266274
procInfo: string;
@@ -360,6 +368,7 @@ interface ICommonOptions {
360368
file: string;
361369
analyticsClient: string;
362370
force: boolean;
371+
companion: boolean;
363372
}
364373

365374
interface IYargArgv extends IDictionary<any> {

definitions/config.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ declare module Config {
1212
SYS_REQUIREMENTS_LINK: string;
1313
version: string;
1414
helpTextPath: string;
15-
adbFilePath: string;
15+
getAdbFilePath(): IFuture<string>;
1616
disableAnalytics?: boolean;
1717
disableHooks?: boolean;
1818
enableDeviceRunCommandOnWindows?: boolean;

definitions/mobile.d.ts

+80-30
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,88 @@ declare module Mobile {
66
skipRefresh?: boolean;
77
}
88

9+
interface IDeviceInfo {
10+
identifier: string;
11+
displayName: string;
12+
model: string;
13+
version: string;
14+
vendor: string;
15+
platform: string;
16+
}
17+
918
interface IDevice {
10-
getIdentifier(): string;
11-
getInstalledApplications(): IFuture<string[]>;
12-
getDisplayName(): string;
13-
getModel(): string;
14-
getVersion(): string;
15-
getVendor(): string;
16-
getPlatform(): string;
19+
deviceInfo: Mobile.IDeviceInfo;
20+
applicationManager: Mobile.IDeviceApplicationManager;
21+
fileSystem: Mobile.IDeviceFileSystem;
1722
deploy(packageFile: string, packageName: string): IFuture<void>;
18-
sync(localToDevicePaths: ILocalToDevicePathData[], appIdentifier: IAppIdentifier, liveSyncUrl: string): IFuture<void>;
19-
sync(localToDevicePaths: ILocalToDevicePathData[], appIdentifier: IAppIdentifier, liveSyncUrl: string, options: ISyncOptions): IFuture<void>;
2023
openDeviceLogStream(): void;
21-
runApplication(applicationId: string): IFuture<void>;
22-
uninstallApplication(applicationId: string): IFuture<void>;
23-
listFiles(devicePath: string): IFuture<void>;
24-
getFile(deviceFilePath: string): IFuture<void>;
25-
putFile(localFilePath: string, deviceFilePath: string): IFuture<void>;
2624
}
27-
28-
interface IAppIdentifier {
29-
appIdentifier: string;
30-
deviceProjectPath: string;
31-
liveSyncFormat: string;
32-
encodeLiveSyncHostUri(hostUri: string): string;
33-
isLiveSyncSupported(device: any): IFuture<boolean>;
34-
getLiveSyncNotSupportedError(device: any): string;
35-
}
36-
25+
3726
interface IAndroidDevice extends IDevice {
38-
debug(packageFile: string, packageName: string, debuggerSetup?: any): IFuture<void>;
27+
adb: Mobile.IAndroidDebugBridge;
3928
}
4029

41-
interface IIOSDevice extends IDevice {
30+
interface IiOSDevice extends IDevice {
4231
startService(serviceName: string): number;
32+
mountImage(): IFuture<void>;
33+
tryExecuteFunction<TResult>(func: () => TResult): TResult;
34+
}
35+
36+
interface IDeviceAppData {
37+
appIdentifier: string;
38+
deviceProjectRootPath: string;
39+
isLiveSyncSupported(device: Mobile.IDevice): IFuture<boolean>;
40+
}
41+
42+
interface IDeviceAppDataFactory {
43+
create(appIdentifier: string, platform: string): Mobile.IDeviceAppData;
44+
}
45+
46+
interface IDeviceAppDataFactoryRule {
47+
vanilla: any;
48+
companion?: any;
49+
}
50+
51+
interface IDeviceAppDataProvider {
52+
createFactoryRules(): IDictionary<Mobile.IDeviceAppDataFactoryRule>;
53+
}
54+
55+
interface IAndroidLiveSyncService {
56+
liveSyncCommands: any;
57+
livesync(appIdentifier: string, liveSyncRoot: string, commands: string[]): IFuture<void>;
58+
createCommandsFileOnDevice(commandsFileDevicePath: string, commands: string[]): IFuture<void>;
4359
}
4460

4561
interface ILogcatHelper {
46-
start(deviceIdentifier: string, adbPath: string): any;
62+
start(deviceIdentifier: string): any;
4763
}
4864

4965
interface ILogcatPrinter {
5066
print(line: string): void;
5167
}
68+
69+
interface IDeviceApplicationManager {
70+
getInstalledApplications(): IFuture<string[]>;
71+
installApplication(packageFilePath: string): IFuture<void>;
72+
uninstallApplication(appIdentifier: string): IFuture<void>;
73+
startApplication(appIdentifier: string): IFuture<void>;
74+
stopApplication(appIdentifier: string): IFuture<void>;
75+
restartApplication(applicationId: string): IFuture<void>;
76+
}
77+
78+
interface IDeviceFileSystem {
79+
listFiles(devicePath: string): IFuture<void>;
80+
getFile(deviceFilePath: string): IFuture<void>;
81+
putFile(localFilePath: string, deviceFilePath: string): IFuture<void>;
82+
transferFiles(appIdentifier: string, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void>;
83+
transferFile?(localFilePath: string, deviceFilePath: string): IFuture<void>;
84+
}
85+
86+
interface IAndroidDebugBridge {
87+
executeCommand(...args: string[]): IFuture<any>;
88+
executeShellCommand(...args: string[]): IFuture<any>;
89+
sendBroadcastToDevice(action: string, extras?: IStringDictionary): IFuture<number>;
90+
}
5291

5392
interface IDebugOnDeviceSetup {
5493
frontEndPath?: string;
@@ -144,6 +183,7 @@ declare module Mobile {
144183
afcConnectionOpen(service: number, timeout: number, afcConnection: NodeBuffer): number;
145184
afcConnectionClose(afcConnection: NodeBuffer): number;
146185
afcDirectoryCreate(afcConnection: NodeBuffer, path: string): number;
186+
afcFileInfoOpen(afcConnection: NodeBuffer, path: string, afcDirectory: NodeBuffer): number;
147187
afcFileRefOpen(afcConnection: NodeBuffer, path: string, mode: number, afcFileRef: NodeBuffer): number;
148188
afcFileRefClose(afcConnection: NodeBuffer, afcFileRef: number): number;
149189
afcFileRefWrite(afcConnection: NodeBuffer, afcFileRef: number, buffer: NodeBuffer, byteLength: number): number;
@@ -172,7 +212,6 @@ declare module Mobile {
172212
interface IAfcClient {
173213
open(path: string, mode: string): Mobile.IAfcFile;
174214
transfer(localFilePath: string, devicePath: string): IFuture<void>;
175-
transferCollection(localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void>;
176215
deleteFile(devicePath: string): void;
177216
mkdir(path: string): void;
178217
listDir(path: string): string[];
@@ -189,6 +228,10 @@ declare module Mobile {
189228
getDevicePath(): string;
190229
getRelativeToProjectBasePath(): string;
191230
}
231+
232+
interface ILocalToDevicePathDataFactory {
233+
create(fileName: string, localProjectRootPath: string, onDeviceFileName: string, deviceProjectRootPath: string): Mobile.ILocalToDevicePathData;
234+
}
192235

193236
interface IiOSSocketResponseData {
194237
Status?: string;
@@ -209,7 +252,8 @@ declare module Mobile {
209252
}
210253

211254
interface IGDBServer {
212-
run(argv: string[]): void;
255+
run(argv: string[]): IFuture<void>;
256+
kill(bundleExecutableName: string): IFuture<void>;
213257
}
214258

215259
interface INotificationProxyClient {
@@ -271,12 +315,18 @@ declare module Mobile {
271315
isPlatformSupported(platform: string): boolean;
272316
validatePlatformName(platform: string): string;
273317
getPlatformCapabilities(platform: string): Mobile.IPlatformCapabilities;
274-
generateLocalToDevicePathData(localPath: string, devicePath: string, relativeToProjectBasePath: string): Mobile.ILocalToDevicePathData;
318+
buildDevicePath(...args: string[]): string;
319+
correctDevicePath(filePath: string): string;
275320
}
276321

277322
interface IDevicePlatformsConstants {
278323
iOS: string;
279324
Android: string;
280325
WP8: string;
281326
}
327+
328+
interface IDeviceApplication {
329+
CFBundleExecutable: string;
330+
Path: string;
331+
}
282332
}

file-system.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ export class FileSystem implements IFileSystem {
422422
}
423423

424424
// filterCallback: function(path: String, stat: fs.Stats): Boolean
425-
public enumerateFilesInDirectorySync(directoryPath: string, filterCallback?: (file: string, stat: IFsStats) => boolean, foundFiles?: string[]): string[] {
425+
public enumerateFilesInDirectorySync(directoryPath: string, filterCallback?: (file: string, stat: IFsStats) => boolean, opts?: { enumerateDirectories?: boolean }, foundFiles?: string[]): string[] {
426426
foundFiles = foundFiles || [];
427427
let contents = this.readDirectory(directoryPath).wait();
428428
for (let i = 0; i < contents.length; ++i) {
@@ -433,7 +433,10 @@ export class FileSystem implements IFileSystem {
433433
}
434434

435435
if (stat.isDirectory()) {
436-
this.enumerateFilesInDirectorySync(file, filterCallback, foundFiles);
436+
if(opts && opts.enumerateDirectories) {
437+
foundFiles.push(file);
438+
}
439+
this.enumerateFilesInDirectorySync(file, filterCallback, opts, foundFiles);
437440
} else {
438441
foundFiles.push(file);
439442
}

0 commit comments

Comments
 (0)