Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not cache calls to dotnet info #6180

Merged
merged 2 commits into from
Aug 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 36 additions & 27 deletions src/shared/utils/getDotnetInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,55 @@ import { join } from 'path';
import { execChildProcess } from '../../common';
import { CoreClrDebugUtil } from '../../coreclrDebug/util';
import { DotnetInfo } from './dotnetInfo';

let _dotnetInfo: DotnetInfo | undefined;
import { EOL } from 'os';

// This function calls `dotnet --info` and returns the result as a DotnetInfo object.
export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInfo> {
if (_dotnetInfo !== undefined) {
return _dotnetInfo;
}

const dotnetExecutablePath = getDotNetExecutablePath(dotNetCliPaths);

const data = await runDotnetInfo(dotnetExecutablePath);
const dotnetInfo = await parseDotnetInfo(data, dotnetExecutablePath);
return dotnetInfo;
}

export function getDotNetExecutablePath(dotNetCliPaths: string[]): string | undefined {
const dotnetExeName = `dotnet${CoreClrDebugUtil.getPlatformExeExtension()}`;
let dotnetExecutablePath: string | undefined;

for (const dotnetPath of dotNetCliPaths) {
const dotnetFullPath = join(dotnetPath, dotnetExeName);
if (CoreClrDebugUtil.existsSync(dotnetFullPath)) {
dotnetExecutablePath = dotnetFullPath;
break;
}
}
return dotnetExecutablePath;
}

async function runDotnetInfo(dotnetExecutablePath: string | undefined): Promise<string> {
try {
const env = {
...process.env,
DOTNET_CLI_UI_LANGUAGE: 'en-US',
};
const data = await execChildProcess(`${dotnetExecutablePath ?? 'dotnet'} --info`, process.cwd(), env);
return data;
} catch (error) {
const message = error instanceof Error ? error.message : `${error}`;
throw new Error(`Error running dotnet --info: ${message}`);
}
}

async function parseDotnetInfo(dotnetInfo: string, dotnetExecutablePath: string | undefined): Promise<DotnetInfo> {
try {
const cliPath = dotnetExecutablePath;
const fullInfo = data;
const fullInfo = dotnetInfo;

let version: string | undefined;
let runtimeId: string | undefined;
let architecture: string | undefined;

let lines = data.replace(/\r/gm, '').split('\n');
let lines = dotnetInfo.replace(/\r/gm, '').split('\n');
for (const line of lines) {
let match: RegExpMatchArray | null;
if ((match = /^\s*Version:\s*([^\s].*)$/.exec(line))) {
Expand Down Expand Up @@ -62,34 +85,20 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf
}

if (version !== undefined) {
_dotnetInfo = {
const dotnetInfo: DotnetInfo = {
CliPath: cliPath,
FullInfo: fullInfo,
Version: version,
RuntimeId: runtimeId,
Architecture: architecture,
Runtimes: runtimeVersions,
};
return _dotnetInfo;
return dotnetInfo;
}

throw new Error('Failed to parse dotnet version information');
} catch {
// something went wrong with spawning 'dotnet --info'
throw new Error('A valid dotnet installation could not be found');
}
}

export function getDotNetExecutablePath(dotNetCliPaths: string[]): string | undefined {
const dotnetExeName = `dotnet${CoreClrDebugUtil.getPlatformExeExtension()}`;
let dotnetExecutablePath: string | undefined;

for (const dotnetPath of dotNetCliPaths) {
const dotnetFullPath = join(dotnetPath, dotnetExeName);
if (CoreClrDebugUtil.existsSync(dotnetFullPath)) {
dotnetExecutablePath = dotnetFullPath;
break;
}
} catch (error) {
const message = error instanceof Error ? error.message : `${error}`;
throw new Error(`Error parsing dotnet --info: ${message}, raw info was:${EOL}${dotnetInfo}`);
}
return dotnetExecutablePath;
}