Get Python's path from az
This commit is contained in:
Родитель
1c0b2551f7
Коммит
a407c95d8c
|
@ -70,11 +70,12 @@
|
|||
"test": "node ./node_modules/vscode/bin/test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jmespath": "^0.15.0",
|
||||
"@types/mocha": "^2.2.32",
|
||||
"@types/node": "^7.0.13",
|
||||
"mocha": "^2.3.3",
|
||||
"tslint": "^5.1.0",
|
||||
"typescript": "^2.0.3",
|
||||
"typescript": "^2.3.1",
|
||||
"vscode": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
# TODO: Find reliable way to locate az
|
||||
source ~/lib/azure-cli/bin/activate || exit 1
|
||||
source ${1:-~/lib/azure-cli/bin/activate} || exit 1
|
||||
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { join, dirname } from 'path';
|
||||
|
||||
import { exec } from './utils';
|
||||
|
||||
export type CompletionKind = 'group' | 'command' | 'parameter_name' | 'parameter_value';
|
||||
|
||||
|
@ -33,42 +35,55 @@ interface Response {
|
|||
|
||||
export class AzService {
|
||||
|
||||
private process: ChildProcess | null;
|
||||
private process: Promise<ChildProcess> | undefined;
|
||||
private data = '';
|
||||
private listeners: { [sequence: number]: ((response: Response) => void); } = {};
|
||||
private nextSequenceNumber = 1;
|
||||
|
||||
constructor() {
|
||||
this.spawn();
|
||||
this.getProcess();
|
||||
}
|
||||
|
||||
getCompletions(query: CompletionQuery) {
|
||||
if (!this.process) {
|
||||
this.spawn();
|
||||
}
|
||||
return new Promise<Completion[]>((resolve, reject) => {
|
||||
const sequence = this.nextSequenceNumber++;
|
||||
this.listeners[sequence] = response => {
|
||||
try {
|
||||
resolve(response.completions);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
if (this.process) {
|
||||
async getCompletions(query: CompletionQuery): Promise<Completion[]> {
|
||||
try {
|
||||
const process = await this.getProcess();
|
||||
return new Promise<Completion[]>((resolve, reject) => {
|
||||
const sequence = this.nextSequenceNumber++;
|
||||
this.listeners[sequence] = response => {
|
||||
try {
|
||||
resolve(response.completions);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
};
|
||||
const request: Request = { sequence, query };
|
||||
const data = JSON.stringify(request);
|
||||
this.process.stdin.write(data + '\n', 'utf8');
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
process.stdin.write(data + '\n', 'utf8');
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private async getProcess(): Promise<ChildProcess> {
|
||||
if (this.process) {
|
||||
return this.process;
|
||||
}
|
||||
return this.process = exec('az --version').then(({stdout}) => {
|
||||
const pythonLocation = (/^Python location '([^']*)'/m.exec(stdout) || [])[1];
|
||||
return this.spawn(pythonLocation);
|
||||
}).catch(err => {
|
||||
this.process = undefined;
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
private spawn() {
|
||||
this.process = spawn(join(__dirname, '../../service/az-service'));
|
||||
this.process.stdout.setEncoding('utf8');
|
||||
this.process.stdout.on('data', data => {
|
||||
private spawn(pythonLocation: string) {
|
||||
const args = pythonLocation ? [join(dirname(pythonLocation), 'activate')] : [];
|
||||
const process = spawn(join(__dirname, '../../service/az-service'), args);
|
||||
process.stdout.setEncoding('utf8');
|
||||
process.stdout.on('data', data => {
|
||||
this.data += data;
|
||||
const nl = this.data.indexOf('\n');
|
||||
if (nl !== -1) {
|
||||
|
@ -82,16 +97,17 @@ export class AzService {
|
|||
}
|
||||
}
|
||||
});
|
||||
this.process.stderr.setEncoding('utf8');
|
||||
this.process.stderr.on('data', data => {
|
||||
process.stderr.setEncoding('utf8');
|
||||
process.stderr.on('data', data => {
|
||||
console.error(data);
|
||||
});
|
||||
this.process.on('error', err => {
|
||||
process.on('error', err => {
|
||||
console.error(err);
|
||||
});
|
||||
this.process.on('exit', (code, signal) => {
|
||||
process.on('exit', (code, signal) => {
|
||||
console.error(`Exit code ${code}, signal ${signal}`);
|
||||
this.process = null;
|
||||
this.process = undefined;
|
||||
});
|
||||
return process;
|
||||
}
|
||||
}
|
|
@ -2,13 +2,12 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as cp from 'child_process';
|
||||
|
||||
import * as jmespath from 'jmespath';
|
||||
|
||||
import { ExtensionContext, TextDocument, TextDocumentChangeEvent, Disposable, TextEditor, Selection, languages, commands, Range, ViewColumn, Position, CancellationToken, ProviderResult, CompletionItem, CompletionList, CompletionItemKind, CompletionItemProvider, window, workspace } from 'vscode';
|
||||
|
||||
import { AzService, CompletionKind, Arguments } from './azService';
|
||||
import { exec } from './utils';
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
context.subscriptions.push(languages.registerCompletionItemProvider('sha', new AzCompletionItemProvider(), ' '));
|
||||
|
@ -170,19 +169,5 @@ function replaceContent(editor: TextEditor, content: string) {
|
|||
.then(() => editor.selections = [new Selection(0, 0, 0, 0)]);
|
||||
}
|
||||
|
||||
interface ExecResult {
|
||||
error: Error;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
function exec(command: string) {
|
||||
return new Promise<ExecResult>((resolve, reject) => {
|
||||
cp.exec(command, (error, stdout, stderr) => {
|
||||
(error || stderr ? reject : resolve)({ error, stdout, stderr });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import * as cp from 'child_process';
|
||||
|
||||
export interface ExecResult {
|
||||
error: Error;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
export function exec(command: string) {
|
||||
return new Promise<ExecResult>((resolve, reject) => {
|
||||
cp.exec(command, (error, stdout, stderr) => {
|
||||
(error || stderr ? reject : resolve)({ error, stdout, stderr });
|
||||
});
|
||||
});
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"strictNullChecks": true,
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
|
|
Загрузка…
Ссылка в новой задаче