Clean up whitespace in launcher.ts
This commit is contained in:
Родитель
fbbf5a13ee
Коммит
a745a28fce
|
@ -50,261 +50,265 @@ export function getDefaultFlavor(kind: LaunchTargetKind) {
|
||||||
* (if it doesn't contain a `project.json` file, but `project.json` files exist).
|
* (if it doesn't contain a `project.json` file, but `project.json` files exist).
|
||||||
*/
|
*/
|
||||||
export function findLaunchTargets(): Thenable<LaunchTarget[]> {
|
export function findLaunchTargets(): Thenable<LaunchTarget[]> {
|
||||||
if (!vscode.workspace.rootPath) {
|
if (!vscode.workspace.rootPath) {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vscode.workspace.findFiles(
|
return vscode.workspace.findFiles(
|
||||||
/*include*/ '{**/*.sln,**/*.csproj,**/project.json}',
|
/*include*/ '{**/*.sln,**/*.csproj,**/project.json}',
|
||||||
/*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}',
|
/*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}',
|
||||||
/*maxResults*/ 100)
|
/*maxResults*/ 100)
|
||||||
.then(resources => {
|
.then(resources => {
|
||||||
return select(resources, vscode.workspace.rootPath);
|
return select(resources, vscode.workspace.rootPath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] {
|
function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] {
|
||||||
// The list of launch targets is calculated like so:
|
// The list of launch targets is calculated like so:
|
||||||
// * If there are .csproj files, .sln files are considered as launch targets.
|
// * If there are .csproj files, .sln files are considered as launch targets.
|
||||||
// * Any project.json file is considered a launch target.
|
// * Any project.json file is considered a launch target.
|
||||||
// * If there is no project.json file in the root, the root as added as a launch target.
|
// * If there is no project.json file in the root, the root as added as a launch target.
|
||||||
//
|
//
|
||||||
// TODO:
|
// TODO:
|
||||||
// * It should be possible to choose a .csproj as a launch target
|
// * It should be possible to choose a .csproj as a launch target
|
||||||
// * It should be possible to choose a .sln file even when no .csproj files are found
|
// * It should be possible to choose a .sln file even when no .csproj files are found
|
||||||
// within the root.
|
// within the root.
|
||||||
|
|
||||||
if (!Array.isArray(resources)) {
|
if (!Array.isArray(resources)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let targets: LaunchTarget[] = [],
|
let targets: LaunchTarget[] = [],
|
||||||
hasCsProjFiles = false,
|
hasCsProjFiles = false,
|
||||||
hasProjectJson = false,
|
hasProjectJson = false,
|
||||||
hasProjectJsonAtRoot = false;
|
hasProjectJsonAtRoot = false;
|
||||||
|
|
||||||
hasCsProjFiles = resources.some(isCSharpProject);
|
hasCsProjFiles = resources.some(isCSharpProject);
|
||||||
|
|
||||||
resources.forEach(resource => {
|
resources.forEach(resource => {
|
||||||
// Add .sln files if there are .csproj files
|
// Add .sln files if there are .csproj files
|
||||||
if (hasCsProjFiles && isSolution(resource)) {
|
if (hasCsProjFiles && isSolution(resource)) {
|
||||||
targets.push({
|
targets.push({
|
||||||
label: path.basename(resource.fsPath),
|
label: path.basename(resource.fsPath),
|
||||||
description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)),
|
description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)),
|
||||||
target: resource.fsPath,
|
target: resource.fsPath,
|
||||||
directory: path.dirname(resource.fsPath),
|
directory: path.dirname(resource.fsPath),
|
||||||
kind: LaunchTargetKind.Solution
|
kind: LaunchTargetKind.Solution
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add project.json files
|
// Add project.json files
|
||||||
if (isProjectJson(resource)) {
|
if (isProjectJson(resource)) {
|
||||||
const dirname = path.dirname(resource.fsPath);
|
const dirname = path.dirname(resource.fsPath);
|
||||||
hasProjectJson = true;
|
hasProjectJson = true;
|
||||||
hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === rootPath;
|
hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === rootPath;
|
||||||
|
|
||||||
targets.push({
|
targets.push({
|
||||||
label: path.basename(resource.fsPath),
|
label: path.basename(resource.fsPath),
|
||||||
description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)),
|
description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)),
|
||||||
target: dirname,
|
target: dirname,
|
||||||
directory: dirname,
|
directory: dirname,
|
||||||
kind: LaunchTargetKind.ProjectJson
|
kind: LaunchTargetKind.ProjectJson
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add the root folder if there are project.json files, but none in the root.
|
// Add the root folder if there are project.json files, but none in the root.
|
||||||
if (hasProjectJson && !hasProjectJsonAtRoot) {
|
if (hasProjectJson && !hasProjectJsonAtRoot) {
|
||||||
targets.push({
|
targets.push({
|
||||||
label: path.basename(rootPath),
|
label: path.basename(rootPath),
|
||||||
description: '',
|
description: '',
|
||||||
target: rootPath,
|
target: rootPath,
|
||||||
directory: rootPath,
|
directory: rootPath,
|
||||||
kind: LaunchTargetKind.Folder
|
kind: LaunchTargetKind.Folder
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return targets.sort((a, b) => a.directory.localeCompare(b.directory));
|
return targets.sort((a, b) => a.directory.localeCompare(b.directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCSharpProject(resource: vscode.Uri): boolean {
|
function isCSharpProject(resource: vscode.Uri): boolean {
|
||||||
return /\.csproj$/i.test(resource.fsPath);
|
return /\.csproj$/i.test(resource.fsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSolution(resource: vscode.Uri): boolean {
|
function isSolution(resource: vscode.Uri): boolean {
|
||||||
return /\.sln$/i.test(resource.fsPath);
|
return /\.sln$/i.test(resource.fsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isProjectJson(resource: vscode.Uri): boolean {
|
function isProjectJson(resource: vscode.Uri): boolean {
|
||||||
return /\project.json$/i.test(resource.fsPath);
|
return /\project.json$/i.test(resource.fsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LaunchDetails {
|
export interface LaunchDetails {
|
||||||
serverPath: string;
|
serverPath: string;
|
||||||
flavor: omnisharp.Flavor;
|
flavor: omnisharp.Flavor;
|
||||||
cwd: string;
|
cwd: string;
|
||||||
args: string[];
|
args: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LaunchResult {
|
export interface LaunchResult {
|
||||||
process: ChildProcess;
|
process: ChildProcess;
|
||||||
command: string;
|
command: string;
|
||||||
usingMono: boolean;
|
usingMono: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function launchOmniSharp(details: LaunchDetails): Promise<LaunchResult> {
|
export function launchOmniSharp(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
return new Promise<LaunchResult>((resolve, reject) => {
|
return new Promise<LaunchResult>((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
return launch(details).then(result => {
|
return launch(details).then(result => {
|
||||||
// async error - when target not not ENEOT
|
// async error - when target not not ENEOT
|
||||||
result.process.on('error', reject);
|
result.process.on('error', reject);
|
||||||
|
|
||||||
// success after a short freeing event loop
|
// success after a short freeing event loop
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, err => {
|
}, err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function launch(details: LaunchDetails): Promise<LaunchResult> {
|
function launch(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
if (platform === Platform.Windows) {
|
if (platform === Platform.Windows) {
|
||||||
return launchWindows(details);
|
return launchWindows(details);
|
||||||
} else {
|
}
|
||||||
return launchNix(details);
|
else {
|
||||||
}
|
return launchNix(details);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchWindows(details: LaunchDetails): Promise<LaunchResult> {
|
function launchWindows(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
return new Promise<LaunchResult>(resolve => {
|
return new Promise<LaunchResult>(resolve => {
|
||||||
|
|
||||||
function escapeIfNeeded(arg: string) {
|
function escapeIfNeeded(arg: string) {
|
||||||
const hasSpaceWithoutQuotes = /^[^"].* .*[^"]/;
|
const hasSpaceWithoutQuotes = /^[^"].* .*[^"]/;
|
||||||
return hasSpaceWithoutQuotes.test(arg)
|
return hasSpaceWithoutQuotes.test(arg)
|
||||||
? `"${arg}"`
|
? `"${arg}"`
|
||||||
: arg;
|
: arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = details.args.slice(0); // create copy of details.args
|
let args = details.args.slice(0); // create copy of details.args
|
||||||
args.unshift(details.serverPath);
|
args.unshift(details.serverPath);
|
||||||
args = [[
|
args = [[
|
||||||
'/s',
|
'/s',
|
||||||
'/c',
|
'/c',
|
||||||
'"' + args.map(escapeIfNeeded).join(' ') + '"'
|
'"' + args.map(escapeIfNeeded).join(' ') + '"'
|
||||||
].join(' ')];
|
].join(' ')];
|
||||||
|
|
||||||
let process = spawn('cmd', args, <any>{
|
let process = spawn('cmd', args, <any>{
|
||||||
windowsVerbatimArguments: true,
|
windowsVerbatimArguments: true,
|
||||||
detached: false,
|
detached: false,
|
||||||
cwd: details.cwd
|
cwd: details.cwd
|
||||||
});
|
});
|
||||||
|
|
||||||
return resolve({
|
return resolve({
|
||||||
process,
|
process,
|
||||||
command: details.serverPath,
|
command: details.serverPath,
|
||||||
usingMono: false
|
usingMono: false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchNix(details: LaunchDetails): Promise<LaunchResult> {
|
function launchNix(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
if (details.flavor === omnisharp.Flavor.CoreCLR) {
|
if (details.flavor === omnisharp.Flavor.CoreCLR) {
|
||||||
return launchNixCoreCLR(details);
|
return launchNixCoreCLR(details);
|
||||||
}
|
}
|
||||||
else if (details.flavor === omnisharp.Flavor.Mono) {
|
else if (details.flavor === omnisharp.Flavor.Mono) {
|
||||||
return launchNixMono(details);
|
return launchNixMono(details);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Error(`Unexpected OmniSharp flavor: ${details.flavor}`);
|
throw new Error(`Unexpected OmniSharp flavor: ${details.flavor}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchNixCoreCLR(details: LaunchDetails): Promise<LaunchResult> {
|
function launchNixCoreCLR(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
return new Promise<LaunchResult>(resolve => {
|
return new Promise<LaunchResult>(resolve => {
|
||||||
let process = spawn(details.serverPath, details.args, {
|
let process = spawn(details.serverPath, details.args, {
|
||||||
detached: false,
|
detached: false,
|
||||||
cwd: details.cwd
|
cwd: details.cwd
|
||||||
});
|
});
|
||||||
|
|
||||||
return resolve({
|
return resolve({
|
||||||
process,
|
process,
|
||||||
command: details.serverPath,
|
command: details.serverPath,
|
||||||
usingMono: false
|
usingMono: false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchNixMono(details: LaunchDetails): Promise<LaunchResult> {
|
function launchNixMono(details: LaunchDetails): Promise<LaunchResult> {
|
||||||
return new Promise<LaunchResult>((resolve, reject) => {
|
return new Promise<LaunchResult>((resolve, reject) => {
|
||||||
return canLaunchMono().then(() => {
|
return canLaunchMono().then(() => {
|
||||||
let args = details.args.slice(0); // create copy of details.args
|
let args = details.args.slice(0); // create copy of details.args
|
||||||
args.unshift(details.serverPath);
|
args.unshift(details.serverPath);
|
||||||
|
|
||||||
let process = spawn('mono', args, {
|
let process = spawn('mono', args, {
|
||||||
detached: false,
|
detached: false,
|
||||||
cwd: details.cwd
|
cwd: details.cwd
|
||||||
});
|
});
|
||||||
|
|
||||||
return resolve({
|
return resolve({
|
||||||
process,
|
process,
|
||||||
command: details.serverPath,
|
command: details.serverPath,
|
||||||
usingMono: true
|
usingMono: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function canLaunchMono(): Promise<void> {
|
function canLaunchMono(): Promise<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
hasMono('>=4.0.1').then(success => {
|
hasMono('>=4.0.1').then(success => {
|
||||||
if (success) {
|
if (success) {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required.'));
|
return reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required.'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasMono(range?: string): Promise<boolean> {
|
export function hasMono(range?: string): Promise<boolean> {
|
||||||
const versionRegexp = /(\d+\.\d+\.\d+)/;
|
const versionRegexp = /(\d+\.\d+\.\d+)/;
|
||||||
|
|
||||||
return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
let childprocess: ChildProcess;
|
let childprocess: ChildProcess;
|
||||||
try {
|
try {
|
||||||
childprocess = spawn('mono', ['--version']);
|
childprocess = spawn('mono', ['--version']);
|
||||||
} catch (e) {
|
}
|
||||||
return resolve(false);
|
catch (e) {
|
||||||
}
|
return resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
childprocess.on('error', function (err: any) {
|
childprocess.on('error', function (err: any) {
|
||||||
resolve(false);
|
resolve(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
let stdout = '';
|
let stdout = '';
|
||||||
childprocess.stdout.on('data', (data: NodeBuffer) => {
|
childprocess.stdout.on('data', (data: NodeBuffer) => {
|
||||||
stdout += data.toString();
|
stdout += data.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
childprocess.stdout.on('close', () => {
|
childprocess.stdout.on('close', () => {
|
||||||
let match = versionRegexp.exec(stdout),
|
let match = versionRegexp.exec(stdout),
|
||||||
ret: boolean;
|
ret: boolean;
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
ret = false;
|
ret = false;
|
||||||
} else if (!range) {
|
}
|
||||||
ret = true;
|
else if (!range) {
|
||||||
} else {
|
ret = true;
|
||||||
ret = satisfies(match[1], range);
|
}
|
||||||
}
|
else {
|
||||||
|
ret = satisfies(match[1], range);
|
||||||
|
}
|
||||||
|
|
||||||
resolve(ret);
|
resolve(ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
Загрузка…
Ссылка в новой задаче