Skip to content

Commit ca657e0

Browse files
author
Mikhail Arkhipov
authored
Changes to IntelliCode and engine downloads (#1715)
* Undo changes * Test fixes * Increase timeout * Remove double event listening * Remove test * Revert "Remove test" This reverts commit e240c3f. * Revert "Remove double event listening" This reverts commit af573be. * #1096 The if statement is automatically formatted incorrectly * Merge fix * Add more tests * More tests * Typo * Test * Also better handle multiline arguments * Add a couple missing periods [skip ci] * Undo changes * Test fixes * Increase timeout * Remove double event listening * Remove test * Revert "Remove test" This reverts commit e240c3f. * Revert "Remove double event listening" This reverts commit af573be. * Merge fix * #1257 On type formatting errors for args and kwargs * Handle f-strings * Stop importing from test code * #1308 Single line statements leading to an indentation on the next line * #726 editing python after inline if statement invalid indent * Undo change * Move constant * Harden LS startup error checks * #1364 Intellisense doesn't work after specific const string * Telemetry for the analysis enging * PR feedback * Fix typo * Test baseline update * Jedi 0.12 * Priority to goto_defition * News * Replace unzip * Linux flavors + test * Grammar check * Grammar test * Test baselines * Add news * Pin dependency [skip ci] * Specify markdown as preferable format * Improve function argument detection * Specify markdown * Pythia setting * Baseline updates * Baseline update * Improve startup * Handle missing interpreter better * Handle interpreter change * Delete old file * Fix LS startup time reporting * Remove Async suffix from IFileSystem * Remove Pythia * Remove pre-packaged MSIL * Exe name on Unix * Plain linux * Fix casing * Fix message * Update PTVS engine activation steps
1 parent 35fe3c0 commit ca657e0

8 files changed

+27
-109
lines changed

CONTRIBUTING - PYTHON_ANALYSIS.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Visual Studio 2017:
3232
3. Binaries arrive in *Python/BuildOutput/VsCode/raw*
3333
4. Delete contents of the *analysis* folder in the Python Extension folder
3434
5. Copy *.dll, *.pdb, *.json fron *Python/BuildOutput/VsCode/raw* to *analysis*
35+
6. In VS Code set setting *python.downloadCodeAnalysis* to *false*
3536

3637
### Debugging code in Python Extension to VS Code
3738
Folow regular TypeScript debugging steps

package.json

-6
Original file line numberDiff line numberDiff line change
@@ -1232,12 +1232,6 @@
12321232
"description": "Whether to install Python modules globally when not using an environment.",
12331233
"scope": "resource"
12341234
},
1235-
"python.pythiaEnabled": {
1236-
"type": "boolean",
1237-
"default": true,
1238-
"description": "Enables AI-driven additions to the completion list. Does not apply to Jedi.",
1239-
"scope": "resource"
1240-
},
12411235
"python.jediEnabled": {
12421236
"type": "boolean",
12431237
"default": true,

src/client/activation/analysis.ts

+7-34
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { IApplicationShell } from '../common/application/types';
99
import { isTestExecution, STANDARD_OUTPUT_CHANNEL } from '../common/constants';
1010
import { createDeferred, Deferred } from '../common/helpers';
1111
import { IFileSystem, IPlatformService } from '../common/platform/types';
12-
import { IProcessServiceFactory } from '../common/process/types';
1312
import { StopWatch } from '../common/stopWatch';
1413
import { IConfigurationService, IOutputChannel, IPythonSettings } from '../common/types';
1514
import { IEnvironmentVariablesProvider } from '../common/variables/types';
@@ -103,32 +102,19 @@ export class AnalysisExtensionActivator implements IExtensionActivator {
103102
// Determine if we are running MSIL/Universal via dotnet or self-contained app.
104103
const mscorlib = path.join(context.extensionPath, analysisEngineFolder, 'mscorlib.dll');
105104
const downloader = new AnalysisEngineDownloader(this.services, analysisEngineFolder);
106-
let downloadPackage = false;
107105

108106
const reporter = getTelemetryReporter();
109107
reporter.sendTelemetryEvent(PYTHON_ANALYSIS_ENGINE_ENABLED);
110108

111-
await this.checkPythiaModel(context, downloader);
112-
113-
if (!await this.fs.fileExists(mscorlib)) {
114-
// Depends on .NET Runtime or SDK
109+
const settings = this.configuration.getSettings();
110+
if (!settings.downloadCodeAnalysis) {
111+
// Depends on .NET Runtime or SDK. Typically development-only case.
115112
this.languageClient = this.createSimpleLanguageClient(context, clientOptions);
116-
try {
117-
await this.tryStartLanguageClient(context, this.languageClient);
118-
return true;
119-
} catch (ex) {
120-
if (await this.isDotNetInstalled()) {
121-
this.appShell.showErrorMessage(`.NET Runtime appears to be installed but the language server did not start. Error ${ex}`);
122-
reporter.sendTelemetryEvent(PYTHON_ANALYSIS_ENGINE_ERROR, { error: 'Failed to start (MSIL)' });
123-
return false;
124-
}
125-
// No .NET Runtime, no mscorlib - need to download self-contained package.
126-
downloadPackage = true;
127-
}
113+
await this.tryStartLanguageClient(context, this.languageClient);
114+
return true;
128115
}
129116

130-
if (downloadPackage) {
131-
this.appShell.showWarningMessage('.NET Runtime is not found, platform-specific Python Analysis Engine will be downloaded.');
117+
if (!await this.fs.fileExists(mscorlib)) {
132118
await downloader.downloadAnalysisEngine(context);
133119
reporter.sendTelemetryEvent(PYTHON_ANALYSIS_ENGINE_DOWNLOADED);
134120
}
@@ -254,22 +240,9 @@ export class AnalysisExtensionActivator implements IExtensionActivator {
254240
maxDocumentationTextLength: 0
255241
},
256242
asyncStartup: true,
257-
pythiaEnabled: settings.pythiaEnabled,
243+
intelliCodeEnabled: settings.intelliCodeEnabled,
258244
testEnvironment: isTestExecution()
259245
}
260246
};
261247
}
262-
263-
private async isDotNetInstalled(): Promise<boolean> {
264-
const ps = await this.services.get<IProcessServiceFactory>(IProcessServiceFactory).create();
265-
const result = await ps.exec('dotnet', ['--version']).catch(() => { return { stdout: '' }; });
266-
return result.stdout.trim().startsWith('2.');
267-
}
268-
269-
private async checkPythiaModel(context: ExtensionContext, downloader: AnalysisEngineDownloader): Promise<void> {
270-
const settings = this.configuration.getSettings();
271-
if (settings.pythiaEnabled) {
272-
await downloader.downloadPythiaModel(context);
273-
}
274-
}
275248
}

src/client/activation/analysisEngineHashes.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,4 @@
77
export const analysis_engine_win_x86_sha512 = 'win-x86';
88
export const analysis_engine_win_x64_sha512 = 'win-x64';
99
export const analysis_engine_osx_x64_sha512 = 'osx-x64';
10-
export const analysis_engine_centos_x64_sha512 = 'centos-x64';
11-
export const analysis_engine_debian_x64_sha512 = 'debian-x64';
12-
export const analysis_engine_fedora_x64_sha512 = 'fedora-x64';
13-
export const analysis_engine_ol_x64_sha512 = 'ol-x64';
14-
export const analysis_engine_opensuse_x64_sha512 = 'opensuse-x64';
15-
export const analysis_engine_rhel_x64_sha512 = 'rhel-x64';
16-
export const analysis_engine_ubuntu_x64_sha512 = 'ubuntu-x64';
10+
export const analysis_engine_linux_x64_sha512 = 'linux-x64';

src/client/activation/downloader.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ import { PlatformData } from './platformData';
1818
const StreamZip = require('node-stream-zip');
1919

2020
const downloadUriPrefix = 'https://pvsc.blob.core.windows.net/python-analysis';
21-
const downloadBaseFileName = 'python-analysis-vscode';
21+
const downloadBaseFileName = 'Python-Analysis-VSCode';
2222
const downloadVersion = '0.1.0';
2323
const downloadFileExtension = '.nupkg';
24-
const pythiaModelName = 'model-sequence.json.gz';
24+
const modelName = 'model-sequence.json.gz';
2525

2626
export class AnalysisEngineDownloader {
2727
private readonly output: OutputChannel;
@@ -56,16 +56,16 @@ export class AnalysisEngineDownloader {
5656
}
5757
}
5858

59-
public async downloadPythiaModel(context: ExtensionContext): Promise<void> {
59+
public async downloadIntelliCodeModel(context: ExtensionContext): Promise<void> {
6060
const modelFolder = path.join(context.extensionPath, 'analysis', 'Pythia', 'model');
61-
const localPath = path.join(modelFolder, pythiaModelName);
61+
const localPath = path.join(modelFolder, modelName);
6262
if (await this.fs.fileExists(localPath)) {
6363
return;
6464
}
6565

6666
let localTempFilePath = '';
6767
try {
68-
localTempFilePath = await this.downloadFile(downloadUriPrefix, pythiaModelName, 'Downloading IntelliSense Model File... ');
68+
localTempFilePath = await this.downloadFile(downloadUriPrefix, modelName, 'Downloading IntelliCode Model File... ');
6969
await this.fs.createDirectory(modelFolder);
7070
await this.fs.copyFile(localTempFilePath, localPath);
7171
} catch (err) {
@@ -129,11 +129,10 @@ export class AnalysisEngineDownloader {
129129
if (!await verifier.verifyHash(filePath, platformString, await this.platformData.getExpectedHash())) {
130130
throw new Error('Hash of the downloaded file does not match.');
131131
}
132-
this.output.append('valid.');
132+
this.output.appendLine('valid.');
133133
}
134134

135135
private async unpackArchive(extensionPath: string, tempFilePath: string): Promise<void> {
136-
this.output.appendLine('');
137136
this.output.append('Unpacking archive... ');
138137

139138
const installFolder = path.join(extensionPath, this.engineFolder);
@@ -170,12 +169,12 @@ export class AnalysisEngineDownloader {
170169
});
171170
return deferred.promise;
172171
});
173-
this.output.append('done.');
174172

175173
// Set file to executable
176174
if (!this.platform.isWindows) {
177175
const executablePath = path.join(installFolder, this.platformData.getEngineExecutableName());
178176
fileSystem.chmodSync(executablePath, '0764'); // -rwxrw-r--
179177
}
178+
this.output.appendLine('done.');
180179
}
181180
}

src/client/activation/platformData.ts

+5-51
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,14 @@
33

44
import { IFileSystem, IPlatformService } from '../common/platform/types';
55
import {
6-
analysis_engine_centos_x64_sha512,
7-
analysis_engine_debian_x64_sha512,
8-
analysis_engine_fedora_x64_sha512,
9-
analysis_engine_ol_x64_sha512,
10-
analysis_engine_opensuse_x64_sha512,
6+
analysis_engine_linux_x64_sha512,
117
analysis_engine_osx_x64_sha512,
12-
analysis_engine_rhel_x64_sha512,
13-
analysis_engine_ubuntu_x64_sha512,
148
analysis_engine_win_x64_sha512,
159
analysis_engine_win_x86_sha512
1610
} from './analysisEngineHashes';
1711

18-
// '/etc/os-release', ID=flavor
19-
const supportedLinuxFlavors = [
20-
'centos',
21-
'debian',
22-
'fedora',
23-
'ol',
24-
'opensuse',
25-
'rhel',
26-
'ubuntu'
27-
];
28-
2912
export class PlatformData {
30-
constructor(private platform: IPlatformService, private fs: IFileSystem) { }
13+
constructor(private platform: IPlatformService, fs: IFileSystem) { }
3114
public async getPlatformName(): Promise<string> {
3215
if (this.platform.isWindows) {
3316
return this.platform.is64bit ? 'win-x64' : 'win-x86';
@@ -39,14 +22,7 @@ export class PlatformData {
3922
if (!this.platform.is64bit) {
4023
throw new Error('Python Analysis Engine does not support 32-bit Linux.');
4124
}
42-
const linuxFlavor = await this.getLinuxFlavor();
43-
if (linuxFlavor.length === 0) {
44-
throw new Error('Unable to determine Linux flavor from /etc/os-release.');
45-
}
46-
if (supportedLinuxFlavors.indexOf(linuxFlavor) < 0) {
47-
throw new Error(`${linuxFlavor} is not supported.`);
48-
}
49-
return `${linuxFlavor}-x64`;
25+
return 'linux-x64';
5026
}
5127
throw new Error('Unknown OS platform.');
5228
}
@@ -58,7 +34,7 @@ export class PlatformData {
5834
public getEngineExecutableName(): string {
5935
return this.platform.isWindows
6036
? 'Microsoft.PythonTools.VsCode.exe'
61-
: 'Microsoft.PythonTools.VsCode';
37+
: 'Microsoft.PythonTools.VsCode.VsCode';
6238
}
6339

6440
public async getExpectedHash(): Promise<string> {
@@ -69,30 +45,8 @@ export class PlatformData {
6945
return analysis_engine_osx_x64_sha512;
7046
}
7147
if (this.platform.isLinux && this.platform.is64bit) {
72-
const linuxFlavor = await this.getLinuxFlavor();
73-
// tslint:disable-next-line:switch-default
74-
switch (linuxFlavor) {
75-
case 'centos': return analysis_engine_centos_x64_sha512;
76-
case 'debian': return analysis_engine_debian_x64_sha512;
77-
case 'fedora': return analysis_engine_fedora_x64_sha512;
78-
case 'ol': return analysis_engine_ol_x64_sha512;
79-
case 'opensuse': return analysis_engine_opensuse_x64_sha512;
80-
case 'rhel': return analysis_engine_rhel_x64_sha512;
81-
case 'ubuntu': return analysis_engine_ubuntu_x64_sha512;
82-
}
48+
return analysis_engine_linux_x64_sha512;
8349
}
8450
throw new Error('Unknown platform.');
8551
}
86-
87-
private async getLinuxFlavor(): Promise<string> {
88-
const verFile = '/etc/os-release';
89-
const data = await this.fs.readFile(verFile);
90-
if (data) {
91-
const res = /ID=(.*)/.exec(data);
92-
if (res && res.length > 1) {
93-
return res[1];
94-
}
95-
}
96-
return '';
97-
}
9852
}

src/client/common/configSettings.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export const IS_WINDOWS = /^win/.test(process.platform);
2525
// tslint:disable-next-line:completed-docs
2626
export class PythonSettings extends EventEmitter implements IPythonSettings {
2727
private static pythonSettings: Map<string, PythonSettings> = new Map<string, PythonSettings>();
28-
public pythiaEnabled = true;
28+
public intelliCodeEnabled = true;
29+
public downloadCodeAnalysis = true;
2930
public jediEnabled = true;
3031
public jediPath = '';
3132
public jediMemoryLimit = 1024;
@@ -115,6 +116,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings {
115116
this.venvPath = systemVariables.resolveAny(pythonSettings.get<string>('venvPath'))!;
116117
this.venvFolders = systemVariables.resolveAny(pythonSettings.get<string[]>('venvFolders'))!;
117118

119+
this.downloadCodeAnalysis = systemVariables.resolveAny(pythonSettings.get<boolean>('downloadCodeAnalysis', true))!;
118120
this.jediEnabled = systemVariables.resolveAny(pythonSettings.get<boolean>('jediEnabled', true))!;
119121
if (this.jediEnabled) {
120122
// tslint:disable-next-line:no-backbone-get-set-outside-model no-non-null-assertion
@@ -126,7 +128,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings {
126128
}
127129
this.jediMemoryLimit = pythonSettings.get<number>('jediMemoryLimit')!;
128130
} else {
129-
this.pythiaEnabled = systemVariables.resolveAny(pythonSettings.get<boolean>('pythiaEnabled', true))!;
131+
this.intelliCodeEnabled = systemVariables.resolveAny(pythonSettings.get<boolean>('intelliCodeEnabled', true))!;
130132
}
131133

132134
// tslint:disable-next-line:no-backbone-get-set-outside-model no-non-null-assertion

src/client/common/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ export interface IPythonSettings {
100100
readonly pythonPath: string;
101101
readonly venvPath: string;
102102
readonly venvFolders: string[];
103-
readonly pythiaEnabled: boolean;
103+
readonly intelliCodeEnabled: boolean;
104+
readonly downloadCodeAnalysis: boolean;
104105
readonly jediEnabled: boolean;
105106
readonly jediPath: string;
106107
readonly jediMemoryLimit: number;

0 commit comments

Comments
 (0)