Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
d028fd6
update PATH setting description to make it more clear
nagilson Sep 10, 2024
b3bf76d
add very prototype code
nagilson Sep 10, 2024
f8fa947
add tests and get runtime check working
nagilson Sep 11, 2024
14f2930
Merge branch 'main' into nagilson-PATH-setting
nagilson Sep 11, 2024
63f943d
Fix some bugs
nagilson Sep 11, 2024
2e890ee
Merge branch 'nagilson-PATH-setting' of https://github.com/nagilson/v…
nagilson Sep 11, 2024
ccaf4fe
Consider that the .NET SDK can also satisfy the Runtime
nagilson Sep 11, 2024
baaf910
fix typo
nagilson Sep 11, 2024
5ad07f3
fix the tests
nagilson Sep 12, 2024
1ad0921
fix
nagilson Sep 12, 2024
4e1b2c6
fix another test
nagilson Sep 12, 2024
e3c23a7
Fix tests even more
nagilson Sep 13, 2024
c66895b
undo yarn changes
nagilson Sep 13, 2024
61911be
fix the final test hopefully
nagilson Sep 13, 2024
78fa558
undo yarn changes
nagilson Sep 13, 2024
058f209
Dont use dotnet.exe as its not platform agnostic
nagilson Sep 13, 2024
0989525
use "markdownDescription" for nicer rendering in VSCode
baronfel Sep 13, 2024
81aa6a0
Tweak call to action to use VSCode mechanisms first, then our standar…
baronfel Sep 13, 2024
f119def
Fix URLs
baronfel Sep 13, 2024
efc75a5
Move to version 2.1.7
nagilson Sep 16, 2024
b43b737
add basic command'
nagilson Sep 18, 2024
a88e0e2
Ignore existingPath setting for SDK installs.
nagilson Sep 18, 2024
a16491a
Remove warning setting and fix invalid path setting
nagilson Sep 18, 2024
b43a96a
Fix test
nagilson Sep 18, 2024
57f52ce
Merge remote-tracking branch 'upstream/main' into nagilson-PATH-setting
nagilson Sep 18, 2024
3c385b1
Merge branch 'nagilson-PATH-setting' into nagilson-PATH-api
nagilson Sep 18, 2024
2918dfe
Refactor code out into a Validator for Conditions
nagilson Sep 18, 2024
ac7fa96
Prepare code to validate the path
nagilson Sep 18, 2024
f18bca3
Merge remote-tracking branch 'upstream/main' into nagilson-PATH-api
nagilson Sep 18, 2024
1e7958a
add a lot of prototypey code
nagilson Sep 19, 2024
9376b6d
add comment for future work
nagilson Sep 23, 2024
59c6dc3
merge with main
nagilson Sep 23, 2024
22a8eca
look up the architecture
nagilson Sep 23, 2024
0b9d6bc
Improve the code
nagilson Sep 24, 2024
ae1b06b
Go 2 Directories Up to find the True Path on PATH
nagilson Sep 24, 2024
7d4ed97
Merge remote-tracking branch 'upstream/main' into nagilson-PATH-api
nagilson Sep 24, 2024
3755f24
Final initial loop of API code
nagilson Sep 24, 2024
236b667
Fix bug parsing list runtimes
nagilson Sep 24, 2024
1b7dd99
Add tests
nagilson Sep 24, 2024
99387e3
Fix test and search for where if its not installed
nagilson Sep 24, 2024
a91f6f3
Consider where may return multiple values
nagilson Sep 25, 2024
0902d6d
Fix test
nagilson Sep 25, 2024
42b03ee
tests mostly working
nagilson Sep 25, 2024
1a5b9f0
code cleanup - get rid of extra api to set env
nagilson Sep 25, 2024
c502c6b
Restore the env var so we dont edit it for other processes
nagilson Sep 25, 2024
3428c75
Uncomment the remaining tests
nagilson Sep 25, 2024
baf5760
Respond to lint
nagilson Sep 25, 2024
2801e1b
fix callback
nagilson Sep 25, 2024
76a553d
Fix path to be os-gnostic
nagilson Sep 25, 2024
24cf0e2
Only search for where on windows and also search for which
nagilson Sep 26, 2024
9386062
provide env to the find command so /usr/bin/whcih can be used
nagilson Sep 26, 2024
9b803ef
Call which which instead of which so the correct command can be found
nagilson Sep 26, 2024
f34c963
Install 3.1 instead of 7.0 because the DTL CI machines seem to have a…
nagilson Sep 26, 2024
4289ff9
give up on arch check for now because it is inaccurate, see comment
nagilson Sep 26, 2024
183d0de
Add github issue in comment for context
nagilson Sep 26, 2024
1aee50e
make linter happy
nagilson Sep 26, 2024
3ea71a7
Respond to PR feedback
nagilson Sep 30, 2024
17ef50e
Migrate to connection strings
nagilson Sep 30, 2024
31c0d5a
Respond to PR Feedback
nagilson Sep 30, 2024
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
14 changes: 7 additions & 7 deletions sample/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/dotnet/vscode-dotnet-runtime.git"
},
"license": "MIT",
"version": "0.0.1",
"version": "0.0.9",
"publisher": "ms-dotnettools",
"engines": {
"vscode": "^1.75.0"
Expand Down Expand Up @@ -66,6 +66,11 @@
"title": "Install .NET SDK Globally via .NET Install Tool (Former Runtime Extension)",
"category": "Sample"
},
{
"command": "sample.dotnet.findPath",
"title": "Find the .NET on the PATH",
"category": "Sample"
},
{
"command": "sample.dotnet-sdk.acquire",
"title": "Acquire .NET SDK",
Expand Down
63 changes: 48 additions & 15 deletions sample/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import * as path from 'path';
import * as vscode from 'vscode';
import {
DotnetInstallMode,
DotnetVersionSpecRequirement,
IDotnetAcquireContext,
IDotnetAcquireResult,
IDotnetFindPathContext,
IDotnetListVersionsResult,
} from 'vscode-dotnet-runtime-library';
import * as runtimeExtension from 'vscode-dotnet-runtime';
import * as sdkExtension from 'vscode-dotnet-sdk';
import * as runtimeExtension from 'vscode-dotnet-runtime'; // comment this out when packing the extension
import * as sdkExtension from 'vscode-dotnet-sdk'; // comment this out when packing the extension
import { install } from 'source-map-support';

export function activate(context: vscode.ExtensionContext) {
Expand All @@ -33,8 +35,8 @@ export function activate(context: vscode.ExtensionContext) {
*/

const requestingExtensionId = 'ms-dotnettools.sample-extension';
runtimeExtension.activate(context);
sdkExtension.activate(context);
runtimeExtension.activate(context); // comment this out when packing the extension
sdkExtension.activate(context); // comment this out when packing the extension


// --------------------------------------------------------------------------
Expand Down Expand Up @@ -167,17 +169,6 @@ ${stderr}`);
}
});

context.subscriptions.push(
sampleHelloWorldRegistration,
sampleAcquireRegistration,
sampleAcquireASPNETRegistration,
sampleAcquireStatusRegistration,
sampleDotnetUninstallAllRegistration,
sampleConcurrentTest,
sampleConcurrentASPNETTest,
sampleShowAcquisitionLogRegistration,
);

const sampleGlobalSDKFromRuntimeRegistration = vscode.commands.registerCommand('sample.dotnet.acquireGlobalSDK', async (version) => {
if (!version) {
version = await vscode.window.showInputBox({
Expand All @@ -199,6 +190,48 @@ ${stderr}`);
}
});

const sampleFindPathRegistration = vscode.commands.registerCommand('sample.dotnet.findPath', async () =>
{
const version = await vscode.window.showInputBox(
{
placeHolder: '8.0',
value: '8.0',
prompt: 'The .NET runtime version.',
});

const arch = await vscode.window.showInputBox({
placeHolder: 'x64',
value: 'x64',
prompt: 'The .NET runtime architecture.',
});

const requirement = await vscode.window.showInputBox({
placeHolder: 'greater_than_or_equal',
value: 'greater_than_or_equal',
prompt: 'The condition to search for a requirement.',
});

let commandContext : IDotnetFindPathContext = { acquireContext: {version: version, requestingExtensionId: requestingExtensionId, architecture : arch, mode : 'runtime'} as IDotnetAcquireContext,
versionSpecRequirement: requirement as DotnetVersionSpecRequirement};

const result = await vscode.commands.executeCommand('dotnet.findPath', commandContext);

vscode.window.showInformationMessage(`.NET Path Discovered\n
${JSON.stringify(result) ?? 'undefined'}`);
});

context.subscriptions.push(
sampleHelloWorldRegistration,
sampleAcquireRegistration,
sampleAcquireASPNETRegistration,
sampleAcquireStatusRegistration,
sampleDotnetUninstallAllRegistration,
sampleConcurrentTest,
sampleConcurrentASPNETTest,
sampleShowAcquisitionLogRegistration,
sampleFindPathRegistration,
);

// --------------------------------------------------------------------------

// ---------------------sdk extension registrations--------------------------
Expand Down
4 changes: 2 additions & 2 deletions sample/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,7 @@ util-deprecate@^1.0.1:
"@types/vscode" "1.74.0"
"@vscode/extension-telemetry" "^0.9.7"
"@vscode/sudo-prompt" "^9.3.1"
"@vscode/test-electron" "^2.4.1"
axios "^1.7.4"
axios-cache-interceptor "^1.5.3"
axios-retry "^3.4.0"
Expand All @@ -1825,12 +1826,11 @@ util-deprecate@^1.0.1:
semver "^7.6.2"
shelljs "^0.8.5"
typescript "^5.5.4"
vscode-test "^1.6.1"
optionalDependencies:
fsevents "^2.3.3"

"vscode-dotnet-runtime@file:../vscode-dotnet-runtime-extension":
version "2.1.6"
version "2.1.7"
resolved "file:../vscode-dotnet-runtime-extension"
dependencies:
"@types/chai-as-promised" "^7.1.8"
Expand Down
6 changes: 5 additions & 1 deletion vscode-dotnet-runtime-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning].

## [Unreleased]

## [2.1.6] - 2024-09-05
## [2.1.7] - 2024-09-31

Adds the API dotnet.findPath() to see if there's an existing .NET installation on the PATH.

## [2.1.6] - 2024-09-20

Fixes an issue with SDK installs on Mac M1 or Arm Mac where the non-emulation path was used.
Fixes an issue where spaces in the username will cause failure for SDK resolution.
Expand Down
4 changes: 2 additions & 2 deletions vscode-dotnet-runtime-extension/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions vscode-dotnet-runtime-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"author": "Microsoft Corporation",
"displayName": ".NET Install Tool",
"description": "This extension installs and manages different versions of the .NET SDK and Runtime.",
"appInsightsKey": "02dc18e0-7494-43b2-b2a3-18ada5fcb522",
"connectionString": "InstrumentationKey=02dc18e0-7494-43b2-b2a3-18ada5fcb522;IngestionEndpoint=https://westus2-0.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/;ApplicationId=e8e56970-a18a-4101-b7d1-1c5dd7c29eeb",
"icon": "images/dotnetIcon.png",
"version": "2.1.6",
"version": "2.1.7",
"publisher": "ms-dotnettools",
"engines": {
"vscode": "^1.81.1"
Expand Down Expand Up @@ -79,7 +79,7 @@
"dotnetAcquisitionExtension.existingDotnetPath": {
"type": "array",
"markdownDescription": "The path to an existing .NET host executable for an extension's code to run under, not for your project to run under.\nRestart VS Code to apply changes.\n\n⚠️ This is NOT the .NET Runtime that your project will use to run. Extensions such as `C#`, `C# DevKit`, and more have components written in .NET. This .NET PATH is the `dotnet.exe` that these extensions will use to run their code, not your code.\n\nUsing a path value in which .NET does not meet the requirements of a specific extension will cause that extension to fail.\n\n🚀 The version of .NET that is used for your project is determined by the .NET host, or dotnet.exe. The .NET host picks a runtime based on your project. To use a specific version of .NET for your project, install the .NET SDK using the `.NET Install Tool - Install SDK System-Wide` command, install .NET manually using [our instructions](https://dotnet.microsoft.com/download), or edit your PATH environment variable to point to a `dotnet.exe` that has an `/sdk/` folder with only one SDK.",
"description": "The path to an existing .NET host executable for an extension's code to run under, not for your project to run under.\nRestart VS Code to apply changes.\n\n⚠️ This is NOT the .NET Runtime that your project will use to run. Extensions such as 'C#', 'C# DevKit', and more have components written in .NET. This .NET PATH is the 'dotnet.exe' that these extensions will use to run their code, not your code.\n\nUsing a path value in which .NET does not meet the requirements of a specific extension will cause that extension to fail.\n\n🚀 The version of .NET that is used for your project is determined by the .NET host, or dotnet.exe. The .NET host picks a runtime based on your project. To use a specific version of .NET for your project, install the .NET SDK using the '.NET Install Tool - Install SDK System-Wide' command, use the instructions at https://dotnet.microsoft.com/download to manually install the .NET SDK, or edit your PATH environment variable to point to a 'dotnet.exe' that has an '/sdk/' folder with only one SDK.",
"description": "The path to an existing .NET host executable for an extension's code to run under, not for your project to run under.\nRestart VS Code to apply changes.\n\n⚠️ This is NOT the .NET Runtime that your project will use to run. Extensions such as 'C#', 'C# DevKit', and more have components written in .NET. This .NET PATH is the 'dotnet.exe' that these extensions will use to run their code, not your code.\n\nUsing a path value in which .NET does not meet the requirements of a specific extension will cause that extension to fail.\n\n🚀 The version of .NET that is used for your project is determined by the .NET host, or dotnet.exe. The .NET host picks a runtime based on your project. To use a specific version of .NET for your project, install the .NET SDK using the '.NET Install Tool - Install SDK System-Wide' command, use the instructions at https://dotnet.microsoft.com/download to manually install the .NET SDK, or edit your PATH environment variable to point to a 'dotnet.exe' that has an '/sdk/' folder with only one SDK.",
"examples": [
"C:\\Program Files\\dotnet\\dotnet.exe",
"/usr/local/share/dotnet/dotnet",
Expand All @@ -99,7 +99,7 @@
"type": "string",
"description": "URL to a proxy if you use one, such as: https://proxy:port"
},
"dotnetAcquisitionExtension.allowInvalidPaths": {
"dotnetAcquisitionExtension.allowInvalidPaths": {
"type": "boolean",
"description": "If you'd like to continue using a .NET path that is not meant to be used for an extension and may cause instability (please read above about the existingDotnetPath setting) then set this to true and restart."
}
Expand Down
105 changes: 103 additions & 2 deletions vscode-dotnet-runtime-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ import {
getMajorMinor,
DotnetOfflineWarning,
IUtilityContext,
IDotnetFindPathContext,
DotnetVersionSpecRequirement,
DotnetConditionValidator,
DotnetPathFinder,
IDotnetConditionValidator,
DotnetFindPathSettingFound,
DotnetFindPathLookupSetting,
DotnetFindPathDidNotMeetCondition,
DotnetFindPathMetCondition,
DotnetFindPathCommandInvoked,
} from 'vscode-dotnet-runtime-library';
import { dotnetCoreAcquisitionExtensionId } from './DotnetCoreAcquisitionId';
import { InstallTrackerSingleton } from 'vscode-dotnet-runtime-library/dist/Acquisition/InstallTrackerSingleton';
Expand All @@ -87,6 +97,7 @@ namespace commandKeys {
export const acquireGlobalSDK = 'acquireGlobalSDK';
export const acquireStatus = 'acquireStatus';
export const uninstall = 'uninstall';
export const findPath = 'findPath';
export const uninstallPublic = 'uninstallPublic'
export const uninstallAll = 'uninstallAll';
export const listVersions = 'listVersions';
Expand Down Expand Up @@ -432,6 +443,95 @@ export function activate(vsCodeContext: vscode.ExtensionContext, extensionContex
return uninstall(commandContext);
});

/**
* @param commandContext The context of the request to find the dotnet path.
* We wrap an AcquisitionContext which must include the version, requestingExtensionId, architecture of .NET desired, and mode.
* The architecture should be of the node format ('x64', 'x86', 'arm64', etc.)
*
* @returns the path to the dotnet executable, if one can be found. This should be the true path to the executable. undefined if none can be found.
*
* @remarks Priority Order for path lookup:
* VSCode Setting -> PATH -> Realpath of PATH -> DOTNET_ROOT (Emulation DOTNET_ROOT if set first)
*
* This accounts for pmc installs, snap installs, bash configurations, and other non-standard installations such as homebrew.
*/
const dotnetFindPathRegistration = vscode.commands.registerCommand(`${commandPrefix}.${commandKeys.findPath}`, async (commandContext : IDotnetFindPathContext) =>
{
globalEventStream.post(new DotnetFindPathCommandInvoked(`The find path command was invoked.`, commandContext));

if(!commandContext.acquireContext.mode || !commandContext.acquireContext.requestingExtensionId || !commandContext.acquireContext.version || !commandContext.acquireContext.architecture)
{
throw new EventCancellationError('BadContextualFindPathError', `The find path request was missing required information: a mode, version, architecture, and requestingExtensionId.`);
}

globalEventStream.post(new DotnetFindPathLookupSetting(`Looking up vscode setting.`));
const workerContext = getAcquisitionWorkerContext(commandContext.acquireContext.mode, commandContext.acquireContext);
const existingPath = await resolveExistingPathIfExists(existingPathConfigWorker, commandContext.acquireContext, workerContext, utilContext, commandContext.versionSpecRequirement);

if(existingPath)
{
globalEventStream.post(new DotnetFindPathSettingFound(`Found vscode setting.`));
outputChannel.show(true);
return existingPath;
}

const validator = new DotnetConditionValidator(workerContext, utilContext);
const finder = new DotnetPathFinder(workerContext, utilContext);

const dotnetsOnPATH = await finder.findRawPathEnvironmentSetting();
for(const dotnetPath of dotnetsOnPATH ?? [])
{
const validatedPATH = await getPathIfValid(dotnetPath, validator, commandContext);
if(validatedPATH)
{
outputChannel.show(true);
return validatedPATH;
}
}

const dotnetsOnRealPATH = await finder.findRealPathEnvironmentSetting();
for(const dotnetPath of dotnetsOnRealPATH ?? [])
{
const validatedRealPATH = await getPathIfValid(dotnetPath, validator, commandContext);
if(validatedRealPATH)
{
outputChannel.show(true);
return validatedRealPATH;
}
}

const dotnetOnROOT = await finder.findDotnetRootPath(commandContext.acquireContext.architecture);
const validatedRoot = await getPathIfValid(dotnetOnROOT, validator, commandContext);
if(validatedRoot)
{
outputChannel.show(true);

return validatedRoot;
}

outputChannel.show(true);
return undefined;
});

async function getPathIfValid(path : string | undefined, validator : IDotnetConditionValidator, commandContext : IDotnetFindPathContext) : Promise<string | undefined>
{
if(path)
{
const validated = await validator.dotnetMeetsRequirement(path, commandContext);
if(validated)
{
globalEventStream.post(new DotnetFindPathMetCondition(`${path} met the conditions.`));
return path;
}
else
{
globalEventStream.post(new DotnetFindPathDidNotMeetCondition(`${path} did NOT satisfy the conditions.`));
}
}

return undefined;
}

async function uninstall(commandContext: IDotnetAcquireContext | undefined, force = false) : Promise<string>
{
let result = '1';
Expand Down Expand Up @@ -515,11 +615,11 @@ export function activate(vsCodeContext: vscode.ExtensionContext, extensionContex

// Helper Functions
async function resolveExistingPathIfExists(configResolver : ExtensionConfigurationWorker, commandContext : IDotnetAcquireContext,
workerContext : IAcquisitionWorkerContext, utilityContext : IUtilityContext) : Promise<IDotnetAcquireResult | null>
workerContext : IAcquisitionWorkerContext, utilityContext : IUtilityContext, requirement? : DotnetVersionSpecRequirement) : Promise<IDotnetAcquireResult | null>
{
const existingPathResolver = new ExistingPathResolver(workerContext, utilityContext);

const existingPath = await existingPathResolver.resolveExistingPath(configResolver.getAllPathConfigurationValues(), commandContext.requestingExtensionId, displayWorker);
const existingPath = await existingPathResolver.resolveExistingPath(configResolver.getAllPathConfigurationValues(), commandContext.requestingExtensionId, displayWorker, requirement);
if (existingPath) {
globalEventStream.post(new DotnetExistingPathResolutionCompleted(existingPath.dotnetPath));
return new Promise((resolve) => {
Expand Down Expand Up @@ -663,6 +763,7 @@ We will try to install .NET, but are unlikely to be able to connect to the serve
dotnetAcquireStatusRegistration,
dotnetAcquireGlobalSDKRegistration,
acquireGlobalSDKPublicRegistration,
dotnetFindPathRegistration,
dotnetListVersionsRegistration,
dotnetRecommendedVersionRegistration,
dotnetUninstallRegistration,
Expand Down
Loading
Loading