diff --git a/src/omnisharp/launcher.ts b/src/omnisharp/launcher.ts index 6348163..f73da1b 100644 --- a/src/omnisharp/launcher.ts +++ b/src/omnisharp/launcher.ts @@ -50,261 +50,265 @@ export function getDefaultFlavor(kind: LaunchTargetKind) { * (if it doesn't contain a `project.json` file, but `project.json` files exist). */ export function findLaunchTargets(): Thenable { - if (!vscode.workspace.rootPath) { - return Promise.resolve([]); - } + if (!vscode.workspace.rootPath) { + return Promise.resolve([]); + } - return vscode.workspace.findFiles( - /*include*/ '{**/*.sln,**/*.csproj,**/project.json}', - /*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}', - /*maxResults*/ 100) - .then(resources => { - return select(resources, vscode.workspace.rootPath); - }); + return vscode.workspace.findFiles( + /*include*/ '{**/*.sln,**/*.csproj,**/project.json}', + /*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}', + /*maxResults*/ 100) + .then(resources => { + return select(resources, vscode.workspace.rootPath); + }); } function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] { // The list of launch targets is calculated like so: - // * If there are .csproj files, .sln files are considered as launch targets. - // * 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. - // - // TODO: - // * 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 - // within the root. + // * If there are .csproj files, .sln files are considered as launch targets. + // * 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. + // + // TODO: + // * 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 + // within the root. - if (!Array.isArray(resources)) { - return []; - } + if (!Array.isArray(resources)) { + return []; + } - let targets: LaunchTarget[] = [], - hasCsProjFiles = false, - hasProjectJson = false, - hasProjectJsonAtRoot = false; + let targets: LaunchTarget[] = [], + hasCsProjFiles = false, + hasProjectJson = false, + hasProjectJsonAtRoot = false; - hasCsProjFiles = resources.some(isCSharpProject); + hasCsProjFiles = resources.some(isCSharpProject); - resources.forEach(resource => { - // Add .sln files if there are .csproj files - if (hasCsProjFiles && isSolution(resource)) { - targets.push({ - label: path.basename(resource.fsPath), - description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), - target: resource.fsPath, - directory: path.dirname(resource.fsPath), - kind: LaunchTargetKind.Solution - }); - } + resources.forEach(resource => { + // Add .sln files if there are .csproj files + if (hasCsProjFiles && isSolution(resource)) { + targets.push({ + label: path.basename(resource.fsPath), + description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), + target: resource.fsPath, + directory: path.dirname(resource.fsPath), + kind: LaunchTargetKind.Solution + }); + } - // Add project.json files - if (isProjectJson(resource)) { - const dirname = path.dirname(resource.fsPath); - hasProjectJson = true; - hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === rootPath; + // Add project.json files + if (isProjectJson(resource)) { + const dirname = path.dirname(resource.fsPath); + hasProjectJson = true; + hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === rootPath; - targets.push({ - label: path.basename(resource.fsPath), - description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), - target: dirname, - directory: dirname, - kind: LaunchTargetKind.ProjectJson - }); - } - }); + targets.push({ + label: path.basename(resource.fsPath), + description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), + target: dirname, + directory: dirname, + kind: LaunchTargetKind.ProjectJson + }); + } + }); - // Add the root folder if there are project.json files, but none in the root. - if (hasProjectJson && !hasProjectJsonAtRoot) { - targets.push({ - label: path.basename(rootPath), - description: '', - target: rootPath, - directory: rootPath, - kind: LaunchTargetKind.Folder - }); - } + // Add the root folder if there are project.json files, but none in the root. + if (hasProjectJson && !hasProjectJsonAtRoot) { + targets.push({ + label: path.basename(rootPath), + description: '', + target: rootPath, + directory: rootPath, + 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 { - return /\.csproj$/i.test(resource.fsPath); + return /\.csproj$/i.test(resource.fsPath); } function isSolution(resource: vscode.Uri): boolean { - return /\.sln$/i.test(resource.fsPath); + return /\.sln$/i.test(resource.fsPath); } function isProjectJson(resource: vscode.Uri): boolean { - return /\project.json$/i.test(resource.fsPath); + return /\project.json$/i.test(resource.fsPath); } export interface LaunchDetails { - serverPath: string; - flavor: omnisharp.Flavor; - cwd: string; - args: string[]; + serverPath: string; + flavor: omnisharp.Flavor; + cwd: string; + args: string[]; } export interface LaunchResult { process: ChildProcess; command: string; - usingMono: boolean; + usingMono: boolean; } export function launchOmniSharp(details: LaunchDetails): Promise { - return new Promise((resolve, reject) => { - try { - return launch(details).then(result => { - // async error - when target not not ENEOT - result.process.on('error', reject); + return new Promise((resolve, reject) => { + try { + return launch(details).then(result => { + // async error - when target not not ENEOT + result.process.on('error', reject); - // success after a short freeing event loop - setTimeout(function () { - resolve(result); - }, 0); - }, err => { - reject(err); - }); - } catch (err) { - reject(err); - } - }); + // success after a short freeing event loop + setTimeout(function () { + resolve(result); + }, 0); + }, err => { + reject(err); + }); + } catch (err) { + reject(err); + } + }); } function launch(details: LaunchDetails): Promise { - if (platform === Platform.Windows) { - return launchWindows(details); - } else { - return launchNix(details); - } + if (platform === Platform.Windows) { + return launchWindows(details); + } + else { + return launchNix(details); + } } function launchWindows(details: LaunchDetails): Promise { - return new Promise(resolve => { + return new Promise(resolve => { - function escapeIfNeeded(arg: string) { - const hasSpaceWithoutQuotes = /^[^"].* .*[^"]/; - return hasSpaceWithoutQuotes.test(arg) - ? `"${arg}"` - : arg; - } + function escapeIfNeeded(arg: string) { + const hasSpaceWithoutQuotes = /^[^"].* .*[^"]/; + return hasSpaceWithoutQuotes.test(arg) + ? `"${arg}"` + : arg; + } - let args = details.args.slice(0); // create copy of details.args - args.unshift(details.serverPath); - args = [[ - '/s', - '/c', - '"' + args.map(escapeIfNeeded).join(' ') + '"' - ].join(' ')]; + let args = details.args.slice(0); // create copy of details.args + args.unshift(details.serverPath); + args = [[ + '/s', + '/c', + '"' + args.map(escapeIfNeeded).join(' ') + '"' + ].join(' ')]; - let process = spawn('cmd', args, { - windowsVerbatimArguments: true, - detached: false, - cwd: details.cwd - }); + let process = spawn('cmd', args, { + windowsVerbatimArguments: true, + detached: false, + cwd: details.cwd + }); - return resolve({ - process, - command: details.serverPath, - usingMono: false - }); - }); + return resolve({ + process, + command: details.serverPath, + usingMono: false + }); + }); } function launchNix(details: LaunchDetails): Promise { - if (details.flavor === omnisharp.Flavor.CoreCLR) { - return launchNixCoreCLR(details); - } - else if (details.flavor === omnisharp.Flavor.Mono) { - return launchNixMono(details); - } - else { - throw new Error(`Unexpected OmniSharp flavor: ${details.flavor}`); - } + if (details.flavor === omnisharp.Flavor.CoreCLR) { + return launchNixCoreCLR(details); + } + else if (details.flavor === omnisharp.Flavor.Mono) { + return launchNixMono(details); + } + else { + throw new Error(`Unexpected OmniSharp flavor: ${details.flavor}`); + } } function launchNixCoreCLR(details: LaunchDetails): Promise { return new Promise(resolve => { - let process = spawn(details.serverPath, details.args, { - detached: false, - cwd: details.cwd - }); + let process = spawn(details.serverPath, details.args, { + detached: false, + cwd: details.cwd + }); - return resolve({ - process, - command: details.serverPath, - usingMono: false - }); + return resolve({ + process, + command: details.serverPath, + usingMono: false + }); }); } function launchNixMono(details: LaunchDetails): Promise { - return new Promise((resolve, reject) => { - return canLaunchMono().then(() => { - let args = details.args.slice(0); // create copy of details.args - args.unshift(details.serverPath); + return new Promise((resolve, reject) => { + return canLaunchMono().then(() => { + let args = details.args.slice(0); // create copy of details.args + args.unshift(details.serverPath); - let process = spawn('mono', args, { - detached: false, - cwd: details.cwd - }); + let process = spawn('mono', args, { + detached: false, + cwd: details.cwd + }); - return resolve({ - process, - command: details.serverPath, - usingMono: true - }); - }); - }); + return resolve({ + process, + command: details.serverPath, + usingMono: true + }); + }); + }); } function canLaunchMono(): Promise { - return new Promise((resolve, reject) => { - hasMono('>=4.0.1').then(success => { - if (success) { - return resolve(); - } - else { - return reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required.')); - } - }); - }); + return new Promise((resolve, reject) => { + hasMono('>=4.0.1').then(success => { + if (success) { + return resolve(); + } + else { + return reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required.')); + } + }); + }); } export function hasMono(range?: string): Promise { - const versionRegexp = /(\d+\.\d+\.\d+)/; + const versionRegexp = /(\d+\.\d+\.\d+)/; - return new Promise((resolve, reject) => { - let childprocess: ChildProcess; - try { - childprocess = spawn('mono', ['--version']); - } catch (e) { - return resolve(false); - } + return new Promise((resolve, reject) => { + let childprocess: ChildProcess; + try { + childprocess = spawn('mono', ['--version']); + } + catch (e) { + return resolve(false); + } - childprocess.on('error', function (err: any) { - resolve(false); - }); + childprocess.on('error', function (err: any) { + resolve(false); + }); - let stdout = ''; - childprocess.stdout.on('data', (data: NodeBuffer) => { - stdout += data.toString(); - }); + let stdout = ''; + childprocess.stdout.on('data', (data: NodeBuffer) => { + stdout += data.toString(); + }); - childprocess.stdout.on('close', () => { - let match = versionRegexp.exec(stdout), - ret: boolean; + childprocess.stdout.on('close', () => { + let match = versionRegexp.exec(stdout), + ret: boolean; - if (!match) { - ret = false; - } else if (!range) { - ret = true; - } else { - ret = satisfies(match[1], range); - } + if (!match) { + ret = false; + } + else if (!range) { + ret = true; + } + else { + ret = satisfies(match[1], range); + } - resolve(ret); - }); - }); + resolve(ret); + }); + }); } \ No newline at end of file