Skip to content

Commit

Permalink
Merge pull request #6175 from dibarbet/correctly_use_runtime_version
Browse files Browse the repository at this point in the history
Use dotnet --list-runtimes instead of version from dotnet --info
  • Loading branch information
dibarbet authored Aug 19, 2023
2 parents 675d74e + 2b68d4b commit 0ba29bf
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '5.0.0',
RuntimeId: 'win10-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -32,6 +33,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'win10-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -45,6 +47,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'win10-arm64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -60,6 +63,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '5.0.0',
RuntimeId: 'linux-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -75,6 +79,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '5.0.0',
RuntimeId: 'osx.11.0-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -88,6 +93,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '5.0.0',
RuntimeId: 'osx.11.0-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -101,6 +107,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-arm64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -114,6 +121,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-x64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, undefined, dotnetInfo);
Expand All @@ -127,6 +135,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-arm64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, 'arm64', dotnetInfo);
Expand All @@ -140,6 +149,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-x86_64',
Runtimes: {},
};

const targetArchitecture = getTargetArchitecture(platformInfo, 'x86_64', dotnetInfo);
Expand All @@ -153,6 +163,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-x86_64',
Runtimes: {},
};

const fn = function () {
Expand All @@ -170,6 +181,7 @@ suite('getTargetArchitecture Tests', () => {
FullInfo: 'Irrelevant',
Version: '6.0.0',
RuntimeId: 'osx.11.0-FUTURE_ISA',
Runtimes: {},
};

const fn = function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ suite(`${reportIssue.name}`, () => {
FullInfo: 'myDotnetInfo',
Version: '1.0.x',
RuntimeId: 'win10-x64',
Runtimes: {},
};

let fakeMonoResolver: FakeMonoResolver;
Expand Down
24 changes: 17 additions & 7 deletions src/lsptoolshost/dotnetRuntimeExtensionResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface IDotnetAcquireResult {
* Resolves the dotnet runtime for a server executable from given options and the dotnet runtime VSCode extension.
*/
export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
private readonly minimumDotnetVersion = '7.0.100';
private readonly minimumDotnetRuntimeVersion = '7.0';
constructor(
private platformInfo: PlatformInformation,
/**
Expand Down Expand Up @@ -132,7 +132,6 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
private async findDotnetFromPath(): Promise<string | undefined> {
try {
const dotnetInfo = await getDotnetInfo([]);
const dotnetVersionStr = dotnetInfo.Version;

const extensionArchitecture = await this.getArchitectureFromTargetPlatform();
const dotnetArchitecture = dotnetInfo.Architecture;
Expand All @@ -145,14 +144,25 @@ export class DotnetRuntimeExtensionResolver implements IHostExecutableResolver {
);
}

const dotnetVersion = semver.parse(dotnetVersionStr);
if (!dotnetVersion) {
throw new Error(`Unknown result output from 'dotnet --version'. Received ${dotnetVersionStr}`);
// Verify that the dotnet we found includes a runtime version that is compatible with our requirement.
const requiredRuntimeVersion = semver.parse(`${this.minimumDotnetRuntimeVersion}.0`);
if (!requiredRuntimeVersion) {
throw new Error(`Unable to parse minimum required version ${this.minimumDotnetRuntimeVersion}`);
}

if (semver.lt(dotnetVersion, this.minimumDotnetVersion)) {
const coreRuntimeVersions = dotnetInfo.Runtimes['Microsoft.NETCore.App'];
let foundRuntimeVersion = false;
for (const version of coreRuntimeVersions) {
// We consider a match if the runtime is greater than or equal to the required version since we roll forward.
if (semver.gt(version, requiredRuntimeVersion)) {
foundRuntimeVersion = true;
break;
}
}

if (!foundRuntimeVersion) {
throw new Error(
`Found dotnet version ${dotnetVersion}. Minimum required version is ${this.minimumDotnetVersion}.`
`No compatible .NET runtime found. Minimum required version is ${this.minimumDotnetRuntimeVersion}.`
);
}

Expand Down
4 changes: 4 additions & 0 deletions src/shared/utils/dotnetInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as semver from 'semver';

type RuntimeVersionMap = { [runtime: string]: semver.SemVer[] };
export interface DotnetInfo {
CliPath?: string;
FullInfo: string;
Version: string;
/* a runtime-only install of dotnet will not output a runtimeId in dotnet --info. */
RuntimeId?: string;
Architecture?: string;
Runtimes: RuntimeVersionMap;
}
26 changes: 24 additions & 2 deletions src/shared/utils/getDotnetInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as semver from 'semver';
import { join } from 'path';
import { execChildProcess } from '../../common';
import { CoreClrDebugUtil } from '../../coreclrDebug/util';
Expand All @@ -19,7 +20,11 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf
const dotnetExecutablePath = getDotNetExecutablePath(dotNetCliPaths);

try {
const data = await execChildProcess(`${dotnetExecutablePath ?? 'dotnet'} --info`, process.cwd(), process.env);
const env = {
...process.env,
DOTNET_CLI_UI_LANGUAGE: 'en-US',
};
const data = await execChildProcess(`${dotnetExecutablePath ?? 'dotnet'} --info`, process.cwd(), env);

const cliPath = dotnetExecutablePath;
const fullInfo = data;
Expand All @@ -28,7 +33,7 @@ export async function getDotnetInfo(dotNetCliPaths: string[]): Promise<DotnetInf
let runtimeId: string | undefined;
let architecture: string | undefined;

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

const runtimeVersions: { [runtime: string]: semver.SemVer[] } = {};
const listRuntimes = await execChildProcess('dotnet --list-runtimes', process.cwd(), process.env);
lines = listRuntimes.split(/\r?\n/);
for (const line of lines) {
let match: RegExpMatchArray | null;
if ((match = /^([\w.]+) ([^ ]+) \[([^\]]+)\]$/.exec(line))) {
const runtime = match[1];
const runtimeVersion = match[2];
if (runtime in runtimeVersions) {
runtimeVersions[runtime].push(semver.parse(runtimeVersion)!);
} else {
runtimeVersions[runtime] = [semver.parse(runtimeVersion)!];
}
}
}

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

0 comments on commit 0ba29bf

Please sign in to comment.