Skip to content

Commit 5cf5643

Browse files
committed
Decouple cli and project services
1 parent 5cca759 commit 5cf5643

21 files changed

+469
-467
lines changed

src/analytics/AnalyticsService.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { Version } from '../common/version';
44
import { GUAService } from './GUAService';
55
import { TelerikAnalyticsService } from './TelerikAnalyticsService';
66
import { AnalyticsBaseInfo, OperatingSystem } from './AnalyticsBaseInfo';
7-
import { ExtensionVersionService } from '../common/ExtensionVersionService';
8-
import * as ns from '../project/NsCliService';
7+
import { ExtensionHostServices as Services } from '../services/extensionHostServices';
8+
import * as utils from '../common/utilities';
99

1010
export class AnalyticsService {
1111
private _baseInfo: AnalyticsBaseInfo;
@@ -39,8 +39,8 @@ export class AnalyticsService {
3939
};
4040

4141
this._baseInfo = {
42-
cliVersion: ns.CliVersionInfo.getInstalledCliVersion().toString(),
43-
extensionVersion: require('../../../package.json').version,
42+
cliVersion: Services.cli.version.toString(),
43+
extensionVersion: utils.getInstalledExtensionVersion().toString(),
4444
operatingSystem: operatingSystem,
4545
userId: AnalyticsService.generateMachineId()
4646
};

src/common/extensionVersionService.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as https from 'https';
22
import * as vscode from 'vscode';
33
import {Version} from './version';
4+
import * as utils from './utilities';
45

56
export type LatestPublishedVersionCheckResult = {latestPublishedVersion: string, timestamp: number};
67

@@ -74,7 +75,7 @@ export class ExtensionVersionService {
7475

7576
public get isLatestInstalled(): Promise<{ result: boolean, error: string }> {
7677
return this.latestPublishedVersion.then(latestVersion => {
77-
let extensionVersion = Version.parse(require('../../package.json').version);
78+
let extensionVersion = utils.getInstalledExtensionVersion();
7879
let isLatest: boolean = extensionVersion.compareBySubminorTo(latestVersion) >= 0;
7980
let error = isLatest ? null : `A new version of the NativeScript extension is available. Open "Extensions" panel to update to v${latestVersion}.`;
8081
return {result: isLatest, error: error};

src/debug-adapter/utilities.ts renamed to src/common/utilities.ts

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as os from 'os';
99
import * as fs from 'fs';
1010
import * as url from 'url';
1111
import * as path from 'path';
12+
import {Version} from './Version';
1213

1314
export const enum Platform {
1415
Windows, OSX, Linux
@@ -376,3 +377,11 @@ export function lstrip(s: string, lStr: string): string {
376377
s.substr(lStr.length) :
377378
s;
378379
}
380+
381+
export function getInstalledExtensionVersion(): Version {
382+
return Version.parse(require('../../package.json').version);
383+
}
384+
385+
export function getMinSupportedCliVersion(): Version {
386+
return Version.parse(require('../../package.json').minNativescriptCliVersion);
387+
}

src/debug-adapter/adapter/adapterProxy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (C) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------*/
44

5-
import * as utils from '../utilities';
5+
import * as utils from '../../common/utilities';
66
import {DebugAdapterServices as Services} from '../../services/debugAdapterServices';
77
import {DebugProtocol} from 'vscode-debugprotocol';
88

src/debug-adapter/adapter/pathTransformer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (C) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------*/
44

5-
import * as utils from '../utilities';
5+
import * as utils from '../../common/utilities';
66
import {DebugAdapterServices as Services} from '../../services/debugAdapterServices';
77
import {DebugProtocol} from 'vscode-debugprotocol';
88

src/debug-adapter/adapter/sourceMaps/pathUtilities.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import * as Path from 'path';
88
import * as URL from 'url';
99
import {DebugAdapterServices as Services} from '../../../services/debugAdapterServices';
10-
import * as utils from '../../utilities';
10+
import * as utils from '../../../common/utilities';
1111

1212
export function getPathRoot(p: string) {
1313
if (p) {

src/debug-adapter/adapter/sourceMaps/sourceMapTransformer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as fs from 'fs';
77
import {DebugAdapterServices as Services} from '../../../services/debugAdapterServices';
88
import {DebugProtocol} from 'vscode-debugprotocol';
99
import {ISourceMaps, SourceMaps} from './sourceMaps';
10-
import * as utils from '../../utilities';
10+
import * as utils from '../../../common/utilities';
1111

1212
interface IPendingBreakpoint {
1313
resolve: () => void;

src/debug-adapter/adapter/sourceMaps/sourceMaps.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as URL from 'url';
99
import * as FS from 'fs';
1010
import {SourceMapConsumer} from 'source-map';
1111
import * as PathUtils from './pathUtilities';
12-
import * as utils from '../../utilities';
12+
import * as utils from '../../../common/utilities';
1313
import {DebugAdapterServices as Services} from '../../../services/debugAdapterServices';
1414

1515

src/debug-adapter/connection/iosConnection.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as net from 'net';
66
import * as stream from 'stream';
77
import {EventEmitter} from 'events';
88
import {INSDebugConnection} from './INSDebugConnection';
9-
import * as utils from '../utilities';
9+
import * as utils from '../../common/utilities';
1010
import {DebugAdapterServices as Services} from '../../services/debugAdapterServices';
1111

1212
interface IMessageWithId {

src/debug-adapter/consoleHelper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*--------------------------------------------------------*/
44

55
import * as url from 'url';
6-
import * as Utilities from './utilities';
6+
import * as Utilities from '../common/utilities';
77

88
export function formatConsoleMessage(m: WebKitProtocol.Console.Message, isClientPath :boolean = false): { text: string, isError: boolean } {
99
let outputText: string;

src/debug-adapter/debugConfiguration.ts renamed to src/debug-adapter/debugRequest.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import {DebugProtocol} from 'vscode-debugprotocol';
2+
import {Project} from '../project/project';
3+
import {IosProject} from '../project/iosProject';
4+
import {AndroidProject} from '../project/androidProject';
5+
import {DebugAdapterServices as Services} from '../services/debugAdapterServices';
6+
import {NativeScriptCli} from '../project/nativeScriptCli';
27

3-
export class DebugConfiguration {
8+
export class DebugRequest {
49
private _requestArgs: DebugProtocol.IRequestArgs;
10+
private _project: Project;
511

6-
constructor(requestArgs: DebugProtocol.IRequestArgs) {
12+
constructor(requestArgs: DebugProtocol.IRequestArgs, cli: NativeScriptCli) {
713
this._requestArgs = requestArgs;
14+
this._project = this.isIos ? new IosProject(this.args.appRoot, cli) : new AndroidProject(this.args.appRoot, cli);
815
}
916

1017
public get isLaunch(): boolean {
@@ -32,10 +39,22 @@ export class DebugConfiguration {
3239
}
3340

3441
public get launchArgs(): DebugProtocol.ILaunchRequestArgs {
35-
return this.isLaunch ? <DebugProtocol.ILaunchRequestArgs>this.args : null;
42+
return (this.isLaunch || this.isSync) ? <DebugProtocol.ILaunchRequestArgs>this.args : null;
3643
}
3744

3845
public get attachArgs(): DebugProtocol.IAttachRequestArgs {
3946
return this.isAttach ? <DebugProtocol.IAttachRequestArgs>this.args : null;
4047
}
48+
49+
public get project(): Project {
50+
return this._project;
51+
}
52+
53+
public get iosProject(): IosProject {
54+
return this.isIos ? <IosProject>this.project : null;
55+
}
56+
57+
public get androidProject(): AndroidProject {
58+
return this.isAndroid ? <AndroidProject>this.project : null;
59+
}
4160
}

src/debug-adapter/webKitDebugAdapter.ts

+54-61
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@
55
import * as os from 'os';
66
import * as fs from 'fs';
77
import * as path from 'path';
8-
import {spawn, ChildProcess} from 'child_process';
98
import {Handles, StoppedEvent, InitializedEvent, TerminatedEvent, OutputEvent} from 'vscode-debugadapter';
109
import {DebugProtocol} from 'vscode-debugprotocol';
1110
import {INSDebugConnection} from './connection/INSDebugConnection';
1211
import {IosConnection} from './connection/iosConnection';
1312
import {AndroidConnection} from './connection/androidConnection';
14-
import * as utils from './utilities';
13+
import {Project, DebugResult} from '../project/project';
14+
import {IosProject} from '../project/iosProject';
15+
import {AndroidProject} from '../project/androidProject';
16+
import * as utils from '../common/utilities';
1517
import {formatConsoleMessage} from './consoleHelper';
16-
import * as ns from '../project/NsCliService';
1718
import {DebugAdapterServices as Services} from '../services/debugAdapterServices';
1819
import {LoggerHandler, Handlers, Tags} from '../common/Logger';
19-
import {DebugConfiguration} from './debugConfiguration';
20+
import {DebugRequest} from './debugRequest';
2021

2122
interface IScopeVarHandle {
2223
objectId: string;
@@ -38,11 +39,9 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
3839
private _setBreakpointsRequestQ: Promise<any>;
3940
private _webKitConnection: INSDebugConnection;
4041
private _eventHandler: (event: DebugProtocol.Event) => void;
41-
private appRoot: string;
42-
private platform: string;
4342
private _lastOutputEvent: OutputEvent;
4443
private _loggerFrontendHandler: LoggerHandler = args => this.fireEvent(new OutputEvent(` ›${args.message}\n`, args.type.toString()));
45-
private _debugConfig: DebugConfiguration;
44+
private _request: DebugRequest;
4645

4746
public constructor() {
4847
this._variableHandles = new Handles<IScopeVarHandle>();
@@ -51,7 +50,7 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
5150
Services.logger.addHandler(this._loggerFrontendHandler, [Tags.FrontendMessage]);
5251
Services.logger.log(`OS: ${os.platform()} ${os.arch()}`);
5352
Services.logger.log('Node version: ' + process.version);
54-
Services.logger.log('Adapter version: ' + require('../../package.json').version);
53+
Services.logger.log('Adapter version: ' + utils.getInstalledExtensionVersion().toString());
5554

5655
this.clearEverything();
5756
}
@@ -108,8 +107,7 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
108107
return this.processRequest(args);
109108
}
110109

111-
private configureLoggingForRequest(): void {
112-
let args = this._debugConfig.args;
110+
private configureLoggingForRequest(args: DebugProtocol.IRequestArgs): void {
113111
if (args.diagnosticLogging) {
114112
// The logger frontend handler is initially configured to handle messages with LoggerTagFrontendMessage tag only.
115113
// We remove the handler and add it again for all messages.
@@ -120,68 +118,63 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
120118
Services.logger.addHandler(Handlers.createStreamHandler(fs.createWriteStream(args.tnsOutput)));
121119
}
122120
Services.logger.log(`initialize(${JSON.stringify(this._initArgs) })`);
123-
Services.logger.log(`${this._debugConfig.args.request}(${JSON.stringify(this._debugConfig.isAttach ? this._debugConfig.attachArgs : this._debugConfig.launchArgs) })`);
121+
Services.logger.log(`${args.request}(${JSON.stringify(args)})`);
124122
}
125123

126124
private processRequest(args: DebugProtocol.IRequestArgs) {
127-
this._debugConfig = new DebugConfiguration(args);
125+
this.configureLoggingForRequest(args);
126+
// Initialize the request
128127
Services.appRoot = args.appRoot;
129-
let analyticsRequest = this._debugConfig.isSync ? "sync" : args.request;
130-
Services.extensionClient.analyticsLaunchDebugger({ request: analyticsRequest, platform: args.platform });
131-
this.configureLoggingForRequest();
132-
this.appRoot = args.appRoot;
133-
this.platform = args.platform;
134-
135-
return ((args.platform == 'ios') ? this._attachIos() : this._attachAndroid())
136-
.then(() => {
137-
this.fireEvent(new InitializedEvent());
138-
},
139-
e => {
140-
Services.logger.error("Command failed: " + e, Tags.FrontendMessage);
141-
this.clearEverything();
142-
return utils.errP(e);
143-
});
144-
}
128+
Services.cliPath = args.nativescriptCliPath || Services.cliPath;
129+
this._request = new DebugRequest(args, Services.cli);
130+
Services.extensionClient.analyticsLaunchDebugger({ request: this._request.isSync ? "sync" : args.request, platform: args.platform });
131+
132+
// Run CLI Command
133+
let cliCommand: DebugResult;
134+
if (this._request.isLaunch) {
135+
cliCommand = this._request.project.debug({ stopOnEntry: this._request.launchArgs.stopOnEntry }, this._request.args.tnsArgs);
136+
}
137+
else if (this._request.isSync) {
138+
cliCommand = this._request.project.debugWithSync({ stopOnEntry: this._request.launchArgs.stopOnEntry, syncAllFiles: this._request.launchArgs.syncAllFiles }, this._request.args.tnsArgs);
139+
}
140+
else if (this._request.isAttach) {
141+
cliCommand = this._request.project.attach(this._request.args.tnsArgs);
142+
}
145143

146-
private _attachIos(): Promise<void> {
147-
let args = this._debugConfig.args;
148-
let iosProject : ns.IosProject = new ns.IosProject(this.appRoot, args.tnsOutput);
144+
if (cliCommand.tnsProcess) {
145+
cliCommand.tnsProcess.stdout.on('data', data => { Services.logger.log(data.toString(), Tags.FrontendMessage); });
146+
cliCommand.tnsProcess.stderr.on('data', data => { Services.logger.error(data.toString(), Tags.FrontendMessage); });
147+
cliCommand.tnsProcess.on('close', (code, signal) => { Services.logger.error(`The tns command finished its execution with code ${code}.`, Tags.FrontendMessage); });
148+
}
149149

150-
return iosProject.debug(args)
151-
.then((socketFilePath) => {
152-
let iosConnection: IosConnection = new IosConnection();
153-
this.setConnection(iosConnection);
154-
return iosConnection.attach(socketFilePath);
150+
// Attach to the running application
151+
let connectionEstablished = cliCommand.backendIsReadyForConnection.then((connectionToken: string | number) => {
152+
if (this._request.isAndroid) {
153+
Services.logger.log(`Attaching to application on port ${connectionToken}`);
154+
let androidConnection = new AndroidConnection();
155+
this.setConnection(androidConnection);
156+
let port: number = <number>connectionToken;
157+
return androidConnection.attach(port, 'localhost');
158+
}
159+
if (this._request.isIos) {
160+
Services.logger.log(`Attaching to application on socket path ${connectionToken}`);
161+
let iosConnection = new IosConnection();
162+
this.setConnection(iosConnection);
163+
let socketFilePath: string = <string>connectionToken;
164+
return iosConnection.attach(socketFilePath);
165+
}
155166
});
156-
}
157-
158-
private _attachAndroid(): Promise<void> {
159-
let args = this._debugConfig.args;
160-
let androidProject: ns.AndroidProject = new ns.AndroidProject(this.appRoot, args.tnsOutput);
161-
let thisAdapter: WebKitDebugAdapter = this;
162-
163-
Services.logger.log("Getting debug port");
164-
let androidConnection: AndroidConnection = null;
165167

166-
let runDebugCommand: Promise<any> = (args.request == 'launch') ? androidProject.debug(args) : Promise.resolve();
167-
168-
return runDebugCommand.then(_ => {
169-
let port: number;
170-
return androidProject.getDebugPort(args).then(debugPort => {
171-
port = debugPort;
172-
if (!thisAdapter._webKitConnection) {
173-
androidConnection = new AndroidConnection();
174-
this.setConnection(androidConnection);
175-
}
176-
}).then(() => {
177-
Services.logger.log("Attaching to debug application");
178-
return androidConnection.attach(port, 'localhost');
179-
});
168+
// Send InitializedEvent
169+
return connectionEstablished.then(() => this.fireEvent(new InitializedEvent()), e => {
170+
Services.logger.error(`Error: ${e}`, Tags.FrontendMessage);
171+
this.clearEverything();
172+
return utils.errP(e);
180173
});
181174
}
182175

183176
private setConnection(connection: INSDebugConnection) : INSDebugConnection {
184-
let args = this._debugConfig.args;
177+
let args = this._request.args;
185178
connection.on('Debugger.paused', params => this.onDebuggerPaused(params));
186179
connection.on('Debugger.resumed', () => this.onDebuggerResumed());
187180
connection.on('Debugger.scriptParsed', params => this.onScriptParsed(params));
@@ -308,7 +301,7 @@ export class WebKitDebugAdapter implements DebugProtocol.IDebugAdapter {
308301
let isClientPath = false;
309302
if (localMessage.url)
310303
{
311-
const clientPath = utils.webkitUrlToClientPath(this.appRoot, this.platform, localMessage.url);
304+
const clientPath = utils.webkitUrlToClientPath(this._request.args.appRoot, this._request.args.platform, localMessage.url);
312305
if (clientPath !== '') {
313306
localMessage.url = clientPath;
314307
isClientPath = true;

0 commit comments

Comments
 (0)