Skip to content

Commit eefbe8f

Browse files
committed
Merge pull request #339 from NativeScript/cankov/ios-debug-emulator
Move the NativeScript iOS debug from common to the NativeScript CLI, add debug on emulator
2 parents f4215fc + c8eeb36 commit eefbe8f

File tree

13 files changed

+563
-190
lines changed

13 files changed

+563
-190
lines changed

lib/bootstrap.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ $injector.require("projectTemplatesService", "./services/project-templates-servi
1515
$injector.require("platformsData", "./platforms-data");
1616
$injector.require("platformService", "./services/platform-service");
1717

18+
$injector.require("iOSDebugService", "./services/ios-debug-service");
19+
$injector.require("androidDebugService", "./services/android-debug-service");
20+
1821
$injector.require("userSettingsService", "./services/user-settings-service");
1922
$injector.require("analyticsSettingsService", "./services/analytics-settings-service");
2023

@@ -29,7 +32,10 @@ $injector.requireCommand("platform|update", "./commands/update-platform");
2932
$injector.requireCommand("library|add", "./commands/add-library");
3033
$injector.requireCommand("run|ios", "./commands/run");
3134
$injector.requireCommand("run|android", "./commands/run");
32-
$injector.requireCommand("debug", "./commands/debug");
35+
36+
$injector.requireCommand("debug|ios", "./commands/debug");
37+
$injector.requireCommand("debug|android", "./commands/debug");
38+
3339
$injector.requireCommand("prepare", "./commands/prepare");
3440
$injector.requireCommand("build|ios", "./commands/build");
3541
$injector.requireCommand("build|android", "./commands/build");

lib/commands/debug.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
///<reference path="../.d.ts"/>
22
"use strict";
33

4-
import helpers = require("./../common/helpers");
5-
import util = require("util")
4+
export class DebugPlatformCommand implements ICommand {
5+
constructor(private debugService: IDebugService) { }
66

7-
export class DebugCommand implements ICommand {
8-
constructor(private $platformService: IPlatformService,
9-
private $platformCommandParameter: ICommandParameter) { }
7+
execute(args: string[]): IFuture<void> {
8+
return this.debugService.debug();
9+
}
1010

11-
execute(args: string[]): IFuture<void> {
12-
return this.$platformService.debugPlatform(args[0]);
13-
}
11+
allowedParameters: ICommandParameter[] = [];
12+
}
13+
14+
export class DebugIOSCommand extends DebugPlatformCommand {
15+
constructor(private $iOSDebugService: IDebugService) {
16+
super($iOSDebugService);
17+
}
18+
}
19+
$injector.registerCommand("debug|ios", DebugIOSCommand);
1420

15-
allowedParameters = [this.$platformCommandParameter];
21+
export class DebugAndroidCommand extends DebugPlatformCommand {
22+
constructor(private $androidDebugService: IDebugService) {
23+
super($androidDebugService);
24+
}
1625
}
17-
$injector.registerCommand("debug", DebugCommand);
18-
26+
$injector.registerCommand("debug|android", DebugAndroidCommand);

lib/definitions/debug.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface IDebugService {
2+
debug(): IFuture<void>;
3+
}

lib/definitions/platform.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ interface IPlatformService {
66
removePlatforms(platforms: string[]): IFuture<void>;
77
updatePlatforms(platforms: string[]): IFuture<void>;
88
runPlatform(platform: string): IFuture<void>;
9-
debugPlatform(platform: string): IFuture<void>;
109
preparePlatform(platform: string): IFuture<void>;
1110
buildPlatform(platform: string): IFuture<void>;
1211
deployOnDevice(platform: string): IFuture<void>;
1312
deployOnEmulator(platform: string): IFuture<void>;
1413
validatePlatformInstalled(platform: string): void;
1514
validatePlatform(platform: string): void;
1615
addLibrary(platform: string, libraryPath: string): IFuture<void>;
16+
17+
getLatestApplicationPackageForDevice(platformData: IPlatformData): IFuture<IApplicationPackage>;
18+
getLatestApplicationPackageForEmulator(platformData: IPlatformData): IFuture<IApplicationPackage>;
1719
}
1820

1921
interface IPlatformData {

lib/definitions/project.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ interface IPlatformProjectService {
3030
buildProject(projectRoot: string): IFuture<void>;
3131
isPlatformPrepared(projectRoot: string): IFuture<boolean>;
3232
addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void>;
33-
getDebugOnDeviceSetup(): Mobile.IDebugOnDeviceSetup;
3433
canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean>;
3534
updatePlatform(currentVersion: string, newVersion: string): IFuture<void>;
3635
}

lib/options.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import commonOptions = require("./common/options");
66
import osenv = require("osenv");
77
import hostInfo = require("./common/host-info");
88

9-
var knownOpts:any = {
9+
var knownOpts: any = {
1010
"frameworkPath": String,
1111
"copy-from": String,
1212
"link-to": String,
1313
"release": Boolean,
1414
"emulator": Boolean,
1515
"symlink": Boolean,
1616
"for-device": Boolean,
17+
"client": Boolean,
1718
"keyStorePath": String,
1819
"keyStorePassword": String,
1920
"keyStoreAlias": String,

lib/services/android-debug-service.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import options = require("./../common/options");
2+
import iOSProxyServices = require("./../common/mobile/ios/ios-proxy-services");
3+
import iOSDevice = require("./../common/mobile/ios/ios-device");
4+
import net = require("net");
5+
6+
class AndroidDebugService implements IDebugService {
7+
constructor(private $devicesServices: Mobile.IDevicesServices,
8+
private $platformService: IPlatformService,
9+
private $platformsData: IPlatformsData,
10+
private $projectData: IProjectData,
11+
private $logger: ILogger) { }
12+
13+
private get platform() { return "android"; }
14+
15+
public debug(): IFuture<void> {
16+
return options.emulator
17+
? this.debugOnEmulator()
18+
: this.debugOnDevice();
19+
}
20+
21+
public debugOnEmulator(): IFuture<void> {
22+
return (() => {
23+
this.$platformService.deployOnEmulator(this.platform).wait();
24+
this.debugOnDevice().wait();
25+
}).future<void>()();
26+
}
27+
28+
public debugOnDevice(): IFuture<void> {
29+
return (() => {
30+
var platformData = this.$platformsData.getPlatformData(this.platform);
31+
var packageFile = "";
32+
var platformData = this.$platformsData.getPlatformData(this.platform);
33+
34+
if (options["debug-brk"]) {
35+
this.$platformService.preparePlatform(this.platform).wait();
36+
37+
var cachedDeviceOption = options.forDevice;
38+
options.forDevice = true;
39+
this.$platformService.buildPlatform(this.platform).wait();
40+
options.forDevice = cachedDeviceOption;
41+
42+
packageFile = this.$platformService.getLatestApplicationPackageForDevice(platformData).wait().packageName;
43+
this.$logger.out("Using ", packageFile);
44+
}
45+
46+
this.$devicesServices.initialize({ platform: this.platform, deviceId: options.device}).wait();
47+
var action = (device: Mobile.IAndroidDevice): IFuture<void> => { return device.debug(packageFile, this.$projectData.projectId) };
48+
this.$devicesServices.execute(action).wait();
49+
50+
}).future<void>()();
51+
}
52+
}
53+
$injector.register("androidDebugService", AndroidDebugService);

lib/services/android-project-service.ts

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class AndroidProjectService implements IPlatformProjectService {
140140
return assetsDirectory;
141141

142142
}).future<string>()();
143-
}
143+
}
144144

145145
public getDebugOnDeviceSetup(): Mobile.IDebugOnDeviceSetup {
146146
return { };
@@ -156,112 +156,112 @@ class AndroidProjectService implements IPlatformProjectService {
156156
return (() => { }).future<void>()();
157157
}
158158

159-
private updateMetadata(projectRoot: string): void {
160-
var projMetadataDir = path.join(projectRoot, "assets", "metadata");
161-
var libsmetadataDir = path.join(projectRoot, "../../lib", this.platformData.normalizedPlatformName, AndroidProjectService.METADATA_DIRNAME);
162-
shell.cp("-f", path.join(libsmetadataDir, "*.dat"), projMetadataDir);
163-
}
159+
private updateMetadata(projectRoot: string): void {
160+
var projMetadataDir = path.join(projectRoot, "assets", "metadata");
161+
var libsmetadataDir = path.join(projectRoot, "../../lib", this.platformData.normalizedPlatformName, AndroidProjectService.METADATA_DIRNAME);
162+
shell.cp("-f", path.join(libsmetadataDir, "*.dat"), projMetadataDir);
163+
}
164164

165-
private generateMetadata(projectRoot: string): void {
166-
var metadataGeneratorPath = path.join(__dirname, "../../resources/tools/metadata-generator.jar");
167-
var libsFolder = path.join(projectRoot, "../../lib", this.platformData.normalizedPlatformName);
165+
private generateMetadata(projectRoot: string): void {
166+
var metadataGeneratorPath = path.join(__dirname, "../../resources/tools/metadata-generator.jar");
167+
var libsFolder = path.join(projectRoot, "../../lib", this.platformData.normalizedPlatformName);
168168
var metadataDirName = AndroidProjectService.METADATA_DIRNAME;
169-
var outDir = path.join(libsFolder, metadataDirName);
170-
this.$fs.ensureDirectoryExists(outDir).wait();
169+
var outDir = path.join(libsFolder, metadataDirName);
170+
this.$fs.ensureDirectoryExists(outDir).wait();
171171

172172
shell.cp("-f", path.join(__dirname, "../../resources/tools/android.jar"), libsFolder);
173173
shell.cp("-f", path.join(__dirname, "../../resources/tools/android-support-v4.jar"), libsFolder);
174174
shell.cp("-f", path.join(projectRoot, "libs/*.jar"), libsFolder);
175175

176176
this.spawn('java', ['-jar', metadataGeneratorPath, libsFolder, outDir]).wait();
177-
}
177+
}
178178

179179
public buildProject(projectRoot: string): IFuture<void> {
180180
return (() => {
181181
var buildConfiguration = options.release ? "release" : "debug";
182-
var args = this.getAntArgs(buildConfiguration, projectRoot);
182+
var args = this.getAntArgs(buildConfiguration, projectRoot);
183183
var argsSaved = this.getAntArgs(buildConfiguration, projectRoot);
184-
this.spawn('ant', args).wait();
185-
this.generateMetadata(projectRoot);
186-
this.updateMetadata(projectRoot);
187-
// build the project again in order to include the newly generated metadata
184+
this.spawn('ant', args).wait();
185+
this.generateMetadata(projectRoot);
186+
this.updateMetadata(projectRoot);
187+
// build the project again in order to include the newly generated metadata
188188
this.spawn('ant', argsSaved).wait();
189189
}).future<void>()();
190190
}
191191

192192
public isPlatformPrepared(projectRoot: string): IFuture<boolean> {
193193
return this.$fs.exists(path.join(projectRoot, "assets", constants.APP_FOLDER_NAME));
194-
}
194+
}
195195

196-
private generateBuildFile(projDir: string, targetSdk: string): void {
197-
this.$logger.info("Generate build.xml for %s", projDir);
198-
var cmd = util.format("android update project -p %s --target %s --subprojects", projDir, targetSdk);
199-
this.$childProcess.exec(cmd).wait();
200-
}
196+
private generateBuildFile(projDir: string, targetSdk: string): void {
197+
this.$logger.info("Generate build.xml for %s", projDir);
198+
var cmd = util.format("android update project -p %s --target %s --subprojects", projDir, targetSdk);
199+
this.$childProcess.exec(cmd).wait();
200+
}
201201

202-
private parseProjectProperties(projDir: string, destDir: string): void {
203-
var projProp = path.join(projDir, "project.properties");
202+
private parseProjectProperties(projDir: string, destDir: string): void {
203+
var projProp = path.join(projDir, "project.properties");
204204

205-
if (!this.$fs.exists(projProp).wait()) {
206-
this.$logger.warn("Warning: File %s does not exist", projProp);
207-
return;
208-
}
205+
if (!this.$fs.exists(projProp).wait()) {
206+
this.$logger.warn("Warning: File %s does not exist", projProp);
207+
return;
208+
}
209209

210210
var lines = this.$fs.readText(projProp, "utf-8").wait().split(os.EOL);
211211

212212
var regEx = /android\.library\.reference\.(\d+)=(.*)/;
213-
lines.forEach(elem => {
214-
var match = elem.match(regEx);
215-
if (match) {
216-
var libRef: ILibRef = { idx: parseInt(match[1]), path: match[2].trim() };
217-
libRef.adjustedPath = this.$fs.isRelativePath(libRef.path) ? path.join(projDir, libRef.path) : libRef.path;
218-
this.parseProjectProperties(libRef.adjustedPath, destDir);
219-
}
220-
});
221-
222-
this.$logger.info("Copying %s", projDir);
223-
shell.cp("-Rf", projDir, destDir);
224-
225-
var targetDir = path.join(destDir, path.basename(projDir));
226-
// TODO: parametrize targetSdk
227-
var targetSdk = "android-17";
228-
this.generateBuildFile(targetDir, targetSdk);
229-
}
230-
231-
private getProjectReferences(projDir: string): ILibRef[]{
232-
var projProp = path.join(projDir, "project.properties");
213+
lines.forEach(elem => {
214+
var match = elem.match(regEx);
215+
if (match) {
216+
var libRef: ILibRef = { idx: parseInt(match[1]), path: match[2].trim() };
217+
libRef.adjustedPath = this.$fs.isRelativePath(libRef.path) ? path.join(projDir, libRef.path) : libRef.path;
218+
this.parseProjectProperties(libRef.adjustedPath, destDir);
219+
}
220+
});
221+
222+
this.$logger.info("Copying %s", projDir);
223+
shell.cp("-Rf", projDir, destDir);
224+
225+
var targetDir = path.join(destDir, path.basename(projDir));
226+
// TODO: parametrize targetSdk
227+
var targetSdk = "android-17";
228+
this.generateBuildFile(targetDir, targetSdk);
229+
}
230+
231+
private getProjectReferences(projDir: string): ILibRef[]{
232+
var projProp = path.join(projDir, "project.properties");
233233

234234
var lines = this.$fs.readText(projProp, "utf-8").wait().split(os.EOL);
235235

236-
var refs: ILibRef[] = [];
236+
var refs: ILibRef[] = [];
237237

238238
var regEx = /android\.library\.reference\.(\d+)=(.*)/;
239-
lines.forEach(elem => {
240-
var match = elem.match(regEx);
241-
if (match) {
242-
var libRef: ILibRef = { idx: parseInt(match[1]), path: match[2] };
243-
libRef.adjustedPath = path.join(projDir, libRef.path);
244-
refs.push(libRef);
245-
}
246-
});
247-
248-
return refs;
249-
}
250-
251-
private updateProjectReferences(projDir: string, libraryPath: string): void {
252-
var refs = this.getProjectReferences(projDir);
239+
lines.forEach(elem => {
240+
var match = elem.match(regEx);
241+
if (match) {
242+
var libRef: ILibRef = { idx: parseInt(match[1]), path: match[2] };
243+
libRef.adjustedPath = path.join(projDir, libRef.path);
244+
refs.push(libRef);
245+
}
246+
});
247+
248+
return refs;
249+
}
250+
251+
private updateProjectReferences(projDir: string, libraryPath: string): void {
252+
var refs = this.getProjectReferences(projDir);
253253
var maxIdx = refs.length > 0 ? _.max(refs, r => r.idx).idx : 0;
254254

255-
var relLibDir = path.relative(projDir, libraryPath).split("\\").join("/");
255+
var relLibDir = path.relative(projDir, libraryPath).split("\\").join("/");
256256

257-
var libRefExists = _.any(refs, r => path.normalize(r.path) === path.normalize(relLibDir));
257+
var libRefExists = _.any(refs, r => path.normalize(r.path) === path.normalize(relLibDir));
258258

259-
if (!libRefExists) {
260-
var projRef = util.format("%sandroid.library.reference.%d=%s", os.EOL, maxIdx + 1, relLibDir);
261-
var projProp = path.join(projDir, "project.properties");
262-
fs.appendFileSync(projProp, projRef, { encoding: "utf-8" });
263-
}
264-
}
259+
if (!libRefExists) {
260+
var projRef = util.format("%sandroid.library.reference.%d=%s", os.EOL, maxIdx + 1, relLibDir);
261+
var projProp = path.join(projDir, "project.properties");
262+
fs.appendFileSync(projProp, projRef, { encoding: "utf-8" });
263+
}
264+
}
265265

266266
public addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void> {
267267
return (() => {
@@ -279,12 +279,12 @@ class AndroidProjectService implements IPlatformProjectService {
279279

280280
var targetLibPath = path.join(targetPath, path.basename(libraryPath));
281281

282-
var libProjProp = path.join(libraryPath, "project.properties");
283-
if (this.$fs.exists(libProjProp).wait()) {
284-
this.updateProjectReferences(platformData.projectRoot, targetLibPath);
285-
}
282+
var libProjProp = path.join(libraryPath, "project.properties");
283+
if (this.$fs.exists(libProjProp).wait()) {
284+
this.updateProjectReferences(platformData.projectRoot, targetLibPath);
285+
}
286286
}).future<void>()();
287-
}
287+
}
288288

289289
public getFrameworkFilesExtensions(): string[] {
290290
return [".jar", ".dat"];

0 commit comments

Comments
 (0)