Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 68 additions & 3 deletions src/debug-adapter/webKitDebugAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
Services.logger().log(`${args.request}(${JSON.stringify(args)})`);
}

private processRequest(args: DebugProtocol.IRequestArgs): Promise<void> {
private async processRequest(args: DebugProtocol.IRequestArgs) {
// Initialize the request
this.configureLoggingForRequest(args);
Services.appRoot = args.appRoot;
return Services.extensionClient().getInitSettings().then(settings => {
return Services.extensionClient().getInitSettings().then(async settings => {
Services.cliPath = settings.tnsPath || Services.cliPath;
this._request = new DebugRequest(args, Services.cli());
Services.extensionClient().analyticsLaunchDebugger({ request: args.request, platform: args.platform });
Expand All @@ -147,7 +147,22 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
Services.logger().log('[NSDebugAdapter] Running tns command...', Tags.FrontendMessage);
let cliCommand: DebugResult;
if (this._request.isLaunch) {
cliCommand = this._request.project.debug({ stopOnEntry: this._request.launchArgs.stopOnEntry, watch: this._request.launchArgs.watch }, this._request.args.tnsArgs);
let tnsArgs = this._request.args.tnsArgs;

// For iOS the TeamID is required if there's more than one.
// Therefore if not set, show selection to the user.
if(args.platform && args.platform.toLowerCase() === 'ios') {
let teamId = this.getTeamId(path.join(Services.appRoot, 'app'), this._request.args.tnsArgs);
if(!teamId) {
let selectedTeam = (await Services.extensionClient().selectTeam());
if(selectedTeam) {
// add the selected by the user Team Id
tnsArgs = (tnsArgs || []).concat(['--teamId', selectedTeam.id]);
}
}
}

cliCommand = this._request.project.debug({ stopOnEntry: this._request.launchArgs.stopOnEntry, watch: this._request.launchArgs.watch }, tnsArgs);
}
else if (this._request.isAttach) {
cliCommand = this._request.project.attach(this._request.args.tnsArgs);
Expand Down Expand Up @@ -687,6 +702,56 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
private scriptIsNotUnknown(scriptId: WebKitProtocol.Debugger.ScriptId): boolean {
return !!this._scriptsById.get(scriptId);
}

private getTeamId(appRoot: string, tnsArgs?: string[]): string {
// try to get the TeamId from the TnsArgs
if(tnsArgs) {
const teamIdArgIndex = tnsArgs.indexOf('--teamId');
if(teamIdArgIndex > 0 && teamIdArgIndex + 1 < tnsArgs.length) {
return tnsArgs[ teamIdArgIndex + 1 ];
}
}

// try to get the TeamId from the buildxcconfig or teamid file
const teamIdFromConfig = this.readTeamId(appRoot);
if(teamIdFromConfig) {
return teamIdFromConfig;
}

// we should get the Teams from the machine and ask the user if they are more than 1
return null;
}

private readXCConfig(appRoot: string, flag: string): string {
let xcconfigFile = path.join(appRoot, "App_Resources/iOS/build.xcconfig");
if (fs.existsSync(xcconfigFile)) {
let text = fs.readFileSync(xcconfigFile, { encoding: 'utf8'});
let teamId: string;
text.split(/\r?\n/).forEach((line) => {
line = line.replace(/\/(\/)[^\n]*$/, "");
if (line.indexOf(flag) >= 0) {
teamId = line.split("=")[1].trim();
if (teamId[teamId.length - 1] === ';') {
teamId = teamId.slice(0, -1);
}
}
});
if (teamId) {
return teamId;
}
}

let fileName = path.join(appRoot, "teamid");
if (fs.existsSync(fileName)) {
return fs.readFileSync(fileName, { encoding: 'utf8' });
}

return null;
}

private readTeamId(appRoot): string {
return this.readXCConfig(appRoot, "DEVELOPMENT_TEAM");
}
}

function scriptIdToSourceReference(scriptId: WebKitProtocol.Debugger.ScriptId): number {
Expand Down
4 changes: 4 additions & 0 deletions src/ipc/extensionClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ export class ExtensionClient {
public runRunCommand(args: extProtocol.AnalyticsRunRunCommandArgs): Promise<any> {
return this.callRemoteMethod('runRunCommand', args);
}

public selectTeam(): Promise<{ id: string, name: string }> {
return this.callRemoteMethod('selectTeam');
}
}
60 changes: 60 additions & 0 deletions src/ipc/extensionServer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs';
import * as crypto from 'crypto';
import * as vscode from 'vscode';
import * as extProtocol from './extensionProtocol';
Expand Down Expand Up @@ -68,4 +69,63 @@ export class ExtensionServer {
public runRunCommand(args: extProtocol.AnalyticsRunRunCommandArgs): Promise<any> {
return Services.analyticsService().runRunCommand(args.platform);
}

public selectTeam() : Promise<{ id: string, name: string }> {
return new Promise((resolve, reject) => {
let developmentTeams = this.getDevelopmentTeams();
if(developmentTeams.length > 1) {
let quickPickItems = developmentTeams.map((team) => {
return {
label: team.name,
description: team.id
};
});
vscode.window.showQuickPick(quickPickItems)
.then(val => resolve({
id: val.description,
label: val.label
}));
} else {
resolve();
}
});
}

private getDevelopmentTeams(): Array<{ id: string, name: string }> {
let dir = path.join(process.env.HOME, "Library/MobileDevice/Provisioning Profiles/");
let files = fs.readdirSync(dir);
let teamIds: any = {};
for (let file of files) {
let filePath = path.join(dir, file);
let data = fs.readFileSync(filePath, { encoding: "utf8" });
let teamId = this.getProvisioningProfileValue("TeamIdentifier", data);
let teamName = this.getProvisioningProfileValue("TeamName", data);
if (teamId) {
teamIds[teamId] = teamName;
}
}

let teamIdsArray = new Array<{ id: string, name: string }>();
for (let teamId in teamIds) {
teamIdsArray.push({ id: teamId, name: teamIds[teamId] });
}

return teamIdsArray;
}

private getProvisioningProfileValue(name: string, text: string): string {
let findStr = "<key>" + name + "</key>";
let index = text.indexOf(findStr);
if (index > 0) {
index = text.indexOf("<string>", index + findStr.length);
if (index > 0) {
index += "<string>".length;
let endIndex = text.indexOf("</string>", index);
let result = text.substring(index, endIndex);
return result;
}
}

return null;
}
}